diff options
author | Keith Packard <keithp@gamba.jf.intel.com> | 2007-03-03 21:02:17 -0800 |
---|---|---|
committer | Keith Packard <keithp@gamba.jf.intel.com> | 2007-03-03 21:02:17 -0800 |
commit | 0fa3d4f51b5ee0dba3882fd74b6ac4e7da708f8f (patch) | |
tree | 7c309acf14e8fb78dc5f3337672f42cf93904ee1 /src | |
parent | 10655c4674cdac8a231c50dd9afc5d43fe43b4bd (diff) | |
parent | fd52d635603b7093c5a2b7fa9c987cf59f9be27c (diff) |
Merge branch 'modesetting' into crestline
Diffstat (limited to 'src')
55 files changed, 3537 insertions, 6488 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 7656e02e..c65c1e73 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,21 +18,49 @@ # 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. -SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 +if HAVE_PCIACCESS +REGDUMPER = reg_dumper +endif + +SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 $(REGDUMPER) # this is obnoxious: # -module lets us name the module exactly how we want # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ + +AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @XMODES_CFLAGS@ \ -DI830_XV -DI830_USE_XAA -DI830_USE_EXA -i810_drv_la_LTLIBRARIES = i810_drv.la -i810_drv_la_LDFLAGS = -module -avoid-version -i810_drv_ladir = @moduledir@/drivers +intel_drv_la_LTLIBRARIES = intel_drv.la +intel_drv_la_LDFLAGS = -module -avoid-version +intel_drv_ladir = @moduledir@/drivers -i810_drv_la_SOURCES = \ +XMODE_SRCS=\ + local_xf86Rename.h \ + parser/xf86Parser.h \ + parser/xf86Optrec.h \ + modes/xf86Modes.h \ + modes/xf86Modes.c \ + modes/xf86cvt.c \ + modes/xf86Crtc.h \ + modes/xf86Crtc.c \ + modes/xf86EdidModes.c \ + modes/xf86RandR12.c \ + modes/xf86RandR12.h \ + modes/xf86Rename.h \ + modes/xf86Rotate.c \ + modes/xf86DiDGA.c + +INTEL_DRI_SRCS = \ + i810_dri.c \ + i810_dri.h \ + i830_dri.c \ + i810_hwmc.c \ + i830_dri.h + +intel_drv_la_SOURCES = \ brw_defines.h \ brw_structs.h \ sf_prog.h \ @@ -59,12 +87,10 @@ i810_drv_la_SOURCES = \ i830_cursor.c \ i830_debug.c \ i830_debug.h \ - i830_dga.c \ i830_display.c \ i830_display.h \ i830_driver.c \ i830_dvo.c \ - i830_edid_modes.c \ i830.h \ i830_i2c.c \ i830_io.c \ @@ -74,17 +100,10 @@ i810_drv_la_SOURCES = \ i830_video.c \ i830_video.h \ i830_reg.h \ - i830_randr.c \ i830_sdvo.c \ i830_sdvo.h \ i830_sdvo_regs.h \ i830_tv.c \ - i830_xf86Modes.h \ - i830_xf86Modes.c \ - i830_xf86cvt.c \ - i830_xf86Crtc.h \ - i830_xf86Crtc.c \ - i830_xf86Rotate.c \ i915_3d.c \ i915_3d.h \ i915_reg.h \ @@ -96,30 +115,72 @@ i810_drv_la_SOURCES = \ i915_render.c \ i965_render.c +INTEL_G4A = \ + packed_yuv_sf.g4a \ + packed_yuv_wm.g4a \ + exa_sf.g4a \ + exa_sf_mask.g4a \ + exa_wm_maskca.g4a \ + exa_wm_maskca_srcalpha.g4a \ + exa_wm_masknoca.g4a \ + exa_wm_nomask.g4a + +INTEL_G4H = \ + sf_prog.h \ + wm_prog.h \ + exa_sf_mask_prog.h \ + exa_sf_prog.h \ + exa_wm_maskca_prog.h \ + exa_wm_maskca_srcalpha_prog.h \ + exa_wm_masknoca_prog.h \ + exa_wm_nomask_prog.h + +EXTRA_DIST = \ + $(XMODE_SRCS) \ + $(INTEL_G4A) \ + $(INTEL_G4H) \ + $(INTEL_DRI_SRCS) + if HAVE_GEN4ASM + sf_prog.h: packed_yuv_sf.g4a intel-gen4asm -o sf_prog.h packed_yuv_sf.g4a + wm_prog.h: packed_yuv_wm.g4a intel-gen4asm -o wm_prog.h packed_yuv_wm.g4a -exa_sf_prog.h: exa_sf.g4a - intel-gen4asm -o exa_sf_prog.h exa_sf.g4a + exa_sf_mask_prog.h: exa_sf_mask.g4a intel-gen4asm -o exa_sf_mask_prog.h exa_sf_mask.g4a -exa_wm_nomask_prog.h: exa_wm_nomask.g4a - intel-gen4asm -o exa_wm_nomask_prog.h exa_wm_nomask.g4a + +exa_sf_prog.h: exa_sf.g4a + intel-gen4asm -o exa_sf_prog.h exa_sf.g4a + +exa_wm_maskca_prog.h: exa_wm_maskca.g4a + intel-gen4asm -o exa_wm_maskca_prog.h exa_wm_maskca.g4a + +exa_wm_maskca_srcalpha_prog.h: exa_wm_maskca_srcalpha.g4a + intel-gen4asm -o exa_wm_maskca_srcalpha_prog.h exa_wm_maskca_srcalpha.g4a + exa_wm_masknoca_prog.h: exa_wm_masknoca.g4a intel-gen4asm -o exa_wm_masknoca_prog.h exa_wm_masknoca.g4a + +exa_wm_nomask_prog.h: exa_wm_nomask.g4a + intel-gen4asm -o exa_wm_nomask_prog.h exa_wm_nomask.g4a + +endif + +if XMODES +intel_drv_la_SOURCES += \ + $(XMODE_SRCS) endif if DRI -i810_drv_la_SOURCES += \ - i810_dri.c \ - i810_dri.h \ - i830_dri.c \ - i810_hwmc.c \ - i830_dri.h +intel_drv_la_SOURCES += \ + $(INTEL_DRI_SRCS) endif -EXTRA_DIST = \ - packed_yuv_sf.g4a \ - packed_yuv_wm.g4a +install-data-local: install-intel_drv_laLTLIBRARIES + (cd $(DESTDIR)$(intel_drv_ladir) && rm -f i810_drv.so && ln -s intel_drv.so i810_drv.so) + +uninstall-local: + (cd $(DESTDIR)$(intel_drv_ladir) && rm -f i810_drv.so) diff --git a/src/bios_reader/Makefile.am b/src/bios_reader/Makefile.am index f18a00c3..a5c81a6c 100644 --- a/src/bios_reader/Makefile.am +++ b/src/bios_reader/Makefile.am @@ -1,4 +1,4 @@ -AM_CFLAGS = @XORG_CFLAGS@ +AM_CFLAGS = @XORG_CFLAGS@ @XMODES_CFLAGS@ noinst_PROGRAMS = bios_reader diff --git a/src/ch7017/Makefile.am b/src/ch7017/Makefile.am index 9cf2fa49..7fbb4408 100644 --- a/src/ch7017/Makefile.am +++ b/src/ch7017/Makefile.am @@ -3,7 +3,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ +AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes ch7017_la_LTLIBRARIES = ch7017.la ch7017_la_LDFLAGS = -module -avoid-version diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c index 28bce0d2..019dcea0 100644 --- a/src/ch7017/ch7017.c +++ b/src/ch7017/ch7017.c @@ -37,7 +37,7 @@ #include "compiler.h" #include "miscstruct.h" #include "xf86i2c.h" -#include "../i830_xf86Crtc.h" +#include "xf86Crtc.h" #define DPMS_SERVER #include <X11/extensions/dpms.h> diff --git a/src/ch7xxx/Makefile.am b/src/ch7xxx/Makefile.am index 7f3b1e1e..b827bf8e 100644 --- a/src/ch7xxx/Makefile.am +++ b/src/ch7xxx/Makefile.am @@ -3,7 +3,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/../ +AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes ch7xxx_la_LTLIBRARIES = ch7xxx.la ch7xxx_la_LDFLAGS = -module -avoid-version diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index 161aebf4..9ce581fa 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -37,7 +37,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "compiler.h" #include "miscstruct.h" #include "xf86i2c.h" -#include "i830_xf86Crtc.h" +#include "xf86Crtc.h" #define DPMS_SERVER #include <X11/extensions/dpms.h> diff --git a/src/common.h b/src/common.h index cc682395..fa2a197b 100644 --- a/src/common.h +++ b/src/common.h @@ -72,6 +72,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DELAY(x) do {;} while (0) #endif +#ifndef REG_DUMPER /* I830 hooks for the I810 driver setup/probe. */ extern const OptionInfoRec *I830AvailableOptions(int chipid, int busid); extern void I830InitpScrn(ScrnInfoPtr pScrn); @@ -130,6 +131,43 @@ extern void I830DPRINTF_stub(const char *filename, int line, outring &= ringmask; \ } while (0) +static inline void memset_volatile(volatile void *b, int c, size_t len) +{ + int i; + + for (i = 0; i < len; i++) + ((volatile char *)b)[i] = c; +} + +static inline void memcpy_volatile(volatile void *dst, const void *src, + size_t len) +{ + int i; + + for (i = 0; i < len; i++) + ((volatile char *)dst)[i] = ((volatile char *)src)[i]; +} + +/** Copies a given number of bytes to the ring */ +#define OUT_RING_COPY(n, ptr) do { \ + if (I810_DEBUG & DEBUG_VERBOSE_RING) \ + ErrorF("OUT_RING_DATA %d bytes\n", n); \ + memcpy_volatile(virt + outring, ptr, n); \ + outring += n; \ + ringused += n; \ + outring &= ringmask; \ +} while (0) + +/** Pads the ring with a given number of zero bytes */ +#define OUT_RING_PAD(n) do { \ + if (I810_DEBUG & DEBUG_VERBOSE_RING) \ + ErrorF("OUT_RING_PAD %d bytes\n", n); \ + memset_volatile(virt + outring, 0, n); \ + outring += n; \ + ringused += n; \ + outring &= ringmask; \ +} while (0) + union intfloat { float f; unsigned int ui; @@ -242,6 +280,7 @@ extern int I810_DEBUG; #define DEBUG_ALWAYS_SYNC 0x80 #define DEBUG_VERBOSE_DRI 0x100 #define DEBUG_VERBOSE_BIOS 0x200 +#endif /* !REG_DUMPER */ /* Size of the mmio region. */ diff --git a/src/exa_sf_mask.g4a b/src/exa_sf_mask.g4a index ab519cee..a7e2d324 100644 --- a/src/exa_sf_mask.g4a +++ b/src/exa_sf_mask.g4a @@ -22,25 +22,25 @@ mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 }; /* Cy[0] */ mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 }; /* Cx[2] */ -mul (1) g7.16<1>F g7.16<0,1,0>F g6<0,1,0>F { align1 }; +mul (1) g7.8<1>F g7.8<0,1,0>F g6<0,1,0>F { align1 }; /* Cy[2] */ -mul (1) g7.20<1>F g7.20<0,1,0>F g6.4<0,1,0>F { align1 }; +mul (1) g7.12<1>F g7.12<0,1,0>F g6.4<0,1,0>F { align1 }; /* src Cx[0], Cx[1] */ mov (8) m1<1>F g7<0,1,0>F { align1 }; /* mask Cx[2], Cx[3] */ -mov (1) m1.8<1>F g7.16<0,1,0>F { align1 }; -mov (1) m1.12<1>F g7.16<0,1,0>F { align1 }; +mov (1) m1.8<1>F g7.8<0,1,0>F { align1 }; +mov (1) m1.12<1>F g7.8<0,1,0>F { align1 }; /* src Cy[0], Cy[1] */ mov (8) m2<1>F g7.4<0,1,0>F { align1 }; /* mask Cy[2], Cy[3] */ -mov (1) m2.8<1>F g7.20<0,1,0>F { align1 }; -mov (1) m2.12<1>F g7.20<0,1,0>F { align1 }; +mov (1) m2.8<1>F g7.12<0,1,0>F { align1 }; +mov (1) m2.12<1>F g7.12<0,1,0>F { align1 }; /* src Co[0], Co[1] */ mov (8) m3<1>F g3<8,8,1>F { align1 }; /* mask Co[2], Co[3] */ -mov (1) m3.8<1>F g3.16<0,1,0>F { align1 }; -mov (1) m3.12<1>F g3.20<0,1,0>F { align1 }; +mov (1) m3.8<1>F g3.8<0,1,0>F { align1 }; +mov (1) m3.12<1>F g3.12<0,1,0>F { align1 }; send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT }; nop; diff --git a/src/exa_sf_mask_prog.h b/src/exa_sf_mask_prog.h index cd7f460a..4e9114d6 100644 --- a/src/exa_sf_mask_prog.h +++ b/src/exa_sf_mask_prog.h @@ -3,17 +3,17 @@ { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 }, { 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 }, { 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 }, - { 0x00000041, 0x20f077bd, 0x000000f0, 0x000000c0 }, - { 0x00000041, 0x20f477bd, 0x000000f4, 0x000000c4 }, + { 0x00000041, 0x20e877bd, 0x000000e8, 0x000000c0 }, + { 0x00000041, 0x20ec77bd, 0x000000ec, 0x000000c4 }, { 0x00600001, 0x202003be, 0x000000e0, 0x00000000 }, - { 0x00000001, 0x202803be, 0x000000f0, 0x00000000 }, - { 0x00000001, 0x202c03be, 0x000000f0, 0x00000000 }, + { 0x00000001, 0x202803be, 0x000000e8, 0x00000000 }, + { 0x00000001, 0x202c03be, 0x000000e8, 0x00000000 }, { 0x00600001, 0x204003be, 0x000000e4, 0x00000000 }, - { 0x00000001, 0x204803be, 0x000000f4, 0x00000000 }, - { 0x00000001, 0x204c03be, 0x000000f4, 0x00000000 }, + { 0x00000001, 0x204803be, 0x000000ec, 0x00000000 }, + { 0x00000001, 0x204c03be, 0x000000ec, 0x00000000 }, { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 }, - { 0x00000001, 0x206803be, 0x00000070, 0x00000000 }, - { 0x00000001, 0x206c03be, 0x00000074, 0x00000000 }, + { 0x00000001, 0x206803be, 0x00000068, 0x00000000 }, + { 0x00000001, 0x206c03be, 0x0000006c, 0x00000000 }, { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, diff --git a/src/exa_wm_maskca.g4a b/src/exa_wm_maskca.g4a new file mode 100644 index 00000000..fa923f6c --- /dev/null +++ b/src/exa_wm_maskca.g4a @@ -0,0 +1,202 @@ +/* + * This's for exa composite operation in no mask picture case. + * The simplest case is just sending what src picture has to dst picture. + * XXX: This is still experimental, and should be fixed to support multiple texture + * map, and conditional mul actions. + */ + +/* I think this should be same as in g4a program for texture video, + as we also use 16-pixel dispatch. and SF scale in g3 is useful for us. */ + +/* The initial payload of the thread is always g0. + * WM_URB (incoming URB entries) is g3 + As mask texture coeffient needs extra setup urb starting from g4, we should + shift this location. + + * X0_R is g4->g6 + * X1_R is g5->g7 + * Y0_R is g6->g8 + * Y1_R is g7->g9 + + * X0: {ss0.x, ss0.x+1, ss0.x, ss0.x+1, ss1.x, ss1.x+1, ss1.x, ss1.x+y} + * Y0: {ss0.y, ss0.y, ss0.y+1, ss0.y+1, ss1.y, ss1.y, ss1.y+1, ss1.y+1} + * X1: {ss2.x, ss2.x+1, ss2.x, ss2.x+1, ss3.x, ss3.x+1, ss3.x, ss3.x+y} + * Y1: {ss2.y, ss2.y, ss2.y+1, ss2.y+1, ss3.y, ss3.y, ss3.y+1, ss3.y+1} + */ + +/* multitexture program with src and mask texture */ +/* - load src texture */ +/* - load mask texture */ +/* - mul src.X with mask's alpha */ +/* - write out src.X */ + + /* Set up ss0.x coordinates*/ +mov (1) g6<1>F g1.8<0,1,0>UW { align1 }; +add (1) g6.4<1>F g1.8<0,1,0>UW 1UB { align1 }; +mov (1) g6.8<1>F g1.8<0,1,0>UW { align1 }; +add (1) g6.12<1>F g1.8<0,1,0>UW 1UB { align1 }; + /* Set up ss0.y coordinates */ +mov (1) g8<1>F g1.10<0,1,0>UW { align1 }; +mov (1) g8.4<1>F g1.10<0,1,0>UW { align1 }; +add (1) g8.8<1>F g1.10<0,1,0>UW 1UB { align1 }; +add (1) g8.12<1>F g1.10<0,1,0>UW 1UB { align1 }; + /* set up ss1.x coordinates */ +mov (1) g6.16<1>F g1.12<0,1,0>UW { align1 }; +add (1) g6.20<1>F g1.12<0,1,0>UW 1UB { align1 }; +mov (1) g6.24<1>F g1.12<0,1,0>UW { align1 }; +add (1) g6.28<1>F g1.12<0,1,0>UW 1UB { align1 }; + /* set up ss1.y coordinates */ +mov (1) g8.16<1>F g1.14<0,1,0>UW { align1 }; +mov (1) g8.20<1>F g1.14<0,1,0>UW { align1 }; +add (1) g8.24<1>F g1.14<0,1,0>UW 1UB { align1 }; +add (1) g8.28<1>F g1.14<0,1,0>UW 1UB { align1 }; + /* Set up ss2.x coordinates */ +mov (1) g7<1>F g1.16<0,1,0>UW { align1 }; +add (1) g7.4<1>F g1.16<0,1,0>UW 1UB { align1 }; +mov (1) g7.8<1>F g1.16<0,1,0>UW { align1 }; +add (1) g7.12<1>F g1.16<0,1,0>UW 1UB { align1 }; + /* Set up ss2.y coordinates */ +mov (1) g9<1>F g1.18<0,1,0>UW { align1 }; +mov (1) g9.4<1>F g1.18<0,1,0>UW { align1 }; +add (1) g9.8<1>F g1.18<0,1,0>UW 1UB { align1 }; +add (1) g9.12<1>F g1.18<0,1,0>UW 1UB { align1 }; + /* Set up ss3.x coordinates */ +mov (1) g7.16<1>F g1.20<0,1,0>UW { align1 }; +add (1) g7.20<1>F g1.20<0,1,0>UW 1UB { align1 }; +mov (1) g7.24<1>F g1.20<0,1,0>UW { align1 }; +add (1) g7.28<1>F g1.20<0,1,0>UW 1UB { align1 }; + /* Set up ss3.y coordinates */ +mov (1) g9.16<1>F g1.22<0,1,0>UW { align1 }; +mov (1) g9.20<1>F g1.22<0,1,0>UW { align1 }; +add (1) g9.24<1>F g1.22<0,1,0>UW 1UB { align1 }; +add (1) g9.28<1>F g1.22<0,1,0>UW 1UB { align1 }; + + /* Now, map these screen space coordinates into texture coordinates. */ +/* This is for src texture */ +/* I don't want to change origin ssX coords, as it will be used later in mask */ +/* so store tex coords in g10, g11, g12, g13 */ + + /* subtract screen-space X origin of vertex 0. */ +add (8) g10<1>F g6<8,8,1>F -g1<0,1,0>F { align1 }; +add (8) g11<1>F g7<8,8,1>F -g1<0,1,0>F { align1 }; + /* scale by texture X increment */ +/* Cx[0] */ +mul (8) g10<1>F g10<8,8,1>F g3<0,1,0>F { align1 }; +mul (8) g11<1>F g11<8,8,1>F g3<0,1,0>F { align1 }; + /* add in texture X offset */ +/* Co[0] */ +add (8) g10<1>F g10<8,8,1>F g3.12<0,1,0>F { align1 }; +add (8) g11<1>F g11<8,8,1>F g3.12<0,1,0>F { align1 }; + /* subtract screen-space Y origin of vertex 0. */ +add (8) g12<1>F g8<8,8,1>F -g1.4<0,1,0>F { align1 }; +add (8) g13<1>F g9<8,8,1>F -g1.4<0,1,0>F { align1 }; + /* scale by texture Y increment */ +/* Cy[0] */ +mul (8) g12<1>F g12<8,8,1>F g3.4<0,1,0>F { align1 }; +mul (8) g13<1>F g13<8,8,1>F g3.4<0,1,0>F { align1 }; + /* add in texture Y offset */ +/* Co[1] */ +add (8) g12<1>F g12<8,8,1>F g3.28<0,1,0>F { align1 }; +add (8) g13<1>F g13<8,8,1>F g3.28<0,1,0>F { align1 }; + +/* prepare sampler read back gX register, which would be written back to output */ + +/* use simd16 sampler, param 0 is u, param 1 is v. */ +/* 'payload' loading, assuming tex coord start from g4 */ +mov (8) m1<1>F g10<8,8,1>F { align1 }; +mov (8) m2<1>F g11<8,8,1>F { align1 }; /* param 0 u in m1, m2 */ +mov (8) m3<1>F g12<8,8,1>F { align1 }; +mov (8) m4<1>F g13<8,8,1>F { align1 }; /* param 1 v in m3, m4 */ + +/* m0 will be copied with g0, as it contains send desc */ +/* emit sampler 'send' cmd */ + +/* src texture readback: g14-g21 */ +send (16) 0 /* msg reg index */ + g14<1>UW /* readback */ + g0<8,8,1>UW /* copy to msg start reg*/ + sampler (1,0,F) /* sampler message description, + (binding_table,sampler_index,datatype). + here(src->dst) we should use src_sampler and + src_surface */ + mlen 5 rlen 8 { align1 }; /* required message len 5, readback len 8 */ + +mov (8) g21<1>UD g21<8,8,1>UD { align1 }; /* wait sampler return */ + +/* sampler mask texture, use g10, g11, g12, g13 */ + /* subtract screen-space X origin of vertex 0. */ +add (8) g10<1>F g6<8,8,1>F -g1<0,1,0>F { align1 }; +add (8) g11<1>F g7<8,8,1>F -g1<0,1,0>F { align1 }; + /* scale by texture X increment */ +/* Cx[2] */ +mul (8) g10<1>F g10<8,8,1>F g4<0,1,0>F { align1 }; +mul (8) g11<1>F g11<8,8,1>F g4<0,1,0>F { align1 }; + /* add in texture X offset */ +/* Co[2] */ +add (8) g10<1>F g10<8,8,1>F g4.12<0,1,0>F { align1 }; +add (8) g11<1>F g11<8,8,1>F g4.12<0,1,0>F { align1 }; + /* subtract screen-space Y origin of vertex 0. */ +add (8) g12<1>F g8<8,8,1>F -g1.4<0,1,0>F { align1 }; +add (8) g13<1>F g9<8,8,1>F -g1.4<0,1,0>F { align1 }; + /* scale by texture Y increment */ +/* Cy[2] */ +mul (8) g12<1>F g12<8,8,1>F g4.4<0,1,0>F { align1 }; +mul (8) g13<1>F g13<8,8,1>F g4.4<0,1,0>F { align1 }; + /* add in texture Y offset */ +/* Co[3] */ +add (8) g12<1>F g12<8,8,1>F g4.28<0,1,0>F { align1 }; +add (8) g13<1>F g13<8,8,1>F g4.28<0,1,0>F { align1 }; + +mov (8) m1<1>F g10<8,8,1>F { align1 }; +mov (8) m2<1>F g11<8,8,1>F { align1 }; +mov (8) m3<1>F g12<8,8,1>F { align1 }; +mov (8) m4<1>F g13<8,8,1>F { align1 }; + +/* mask sampler g22-g29 */ +/* binding_table (2), sampler (1) */ +send (16) 0 g22<1>UW g0<8,8,1>UW sampler (2,1,F) mlen 5 rlen 8 { align1 }; +mov (8) g29<1>UD g29<8,8,1>UD { align1 }; /* wait sampler return */ + +/* mul mask's channel to src, then write out src */ +mul (8) g14<1>F g14<8,8,1>F g22<8,8,1>F { align1 }; +mul (8) g15<1>F g15<8,8,1>F g23<8,8,1>F { align1 }; +mul (8) g16<1>F g16<8,8,1>F g24<8,8,1>F { align1 }; +mul (8) g17<1>F g17<8,8,1>F g25<8,8,1>F { align1 }; +mul (8) g18<1>F g18<8,8,1>F g26<8,8,1>F { align1 }; +mul (8) g19<1>F g19<8,8,1>F g27<8,8,1>F { align1 }; +mul (8) g20<1>F g20<8,8,1>F g28<8,8,1>F { align1 }; +mul (8) g21<1>F g21<8,8,1>F g29<8,8,1>F { align1 }; + +/* prepare data in m2-m5 for subspan(1,0), m6-m9 for subspan(3,2), then it's ready to write */ +mov (8) m2<1>F g14<8,8,1>F { align1 }; +mov (8) m3<1>F g16<8,8,1>F { align1 }; +mov (8) m4<1>F g18<8,8,1>F { align1 }; +mov (8) m5<1>F g20<8,8,1>F { align1 }; +mov (8) m6<1>F g15<8,8,1>F { align1 }; +mov (8) m7<1>F g17<8,8,1>F { align1 }; +mov (8) m8<1>F g19<8,8,1>F { align1 }; +mov (8) m9<1>F g21<8,8,1>F { align1 }; + +/* m0, m1 are all direct passed by PS thread payload */ +mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable }; + +/* write */ +send (16) 0 acc0<1>UW g0<8,8,1>UW write ( + 0, /* binding_table */ + 8, /* pixel scordboard clear, msg type simd16 single source */ + 4, /* render target write */ + 0 /* no write commit message */ + ) + mlen 10 + rlen 0 + { align1 EOT }; + +nop; +nop; +nop; +nop; +nop; +nop; +nop; +nop; +nop; diff --git a/src/exa_wm_maskca_prog.h b/src/exa_wm_maskca_prog.h new file mode 100644 index 00000000..d936412c --- /dev/null +++ b/src/exa_wm_maskca_prog.h @@ -0,0 +1,95 @@ + { 0x00000001, 0x20c0013d, 0x00000028, 0x00000000 }, + { 0x00000040, 0x20c40d3d, 0x00000028, 0x00000001 }, + { 0x00000001, 0x20c8013d, 0x00000028, 0x00000000 }, + { 0x00000040, 0x20cc0d3d, 0x00000028, 0x00000001 }, + { 0x00000001, 0x2100013d, 0x0000002a, 0x00000000 }, + { 0x00000001, 0x2104013d, 0x0000002a, 0x00000000 }, + { 0x00000040, 0x21080d3d, 0x0000002a, 0x00000001 }, + { 0x00000040, 0x210c0d3d, 0x0000002a, 0x00000001 }, + { 0x00000001, 0x20d0013d, 0x0000002c, 0x00000000 }, + { 0x00000040, 0x20d40d3d, 0x0000002c, 0x00000001 }, + { 0x00000001, 0x20d8013d, 0x0000002c, 0x00000000 }, + { 0x00000040, 0x20dc0d3d, 0x0000002c, 0x00000001 }, + { 0x00000001, 0x2110013d, 0x0000002e, 0x00000000 }, + { 0x00000001, 0x2114013d, 0x0000002e, 0x00000000 }, + { 0x00000040, 0x21180d3d, 0x0000002e, 0x00000001 }, + { 0x00000040, 0x211c0d3d, 0x0000002e, 0x00000001 }, + { 0x00000001, 0x20e0013d, 0x00000030, 0x00000000 }, + { 0x00000040, 0x20e40d3d, 0x00000030, 0x00000001 }, + { 0x00000001, 0x20e8013d, 0x00000030, 0x00000000 }, + { 0x00000040, 0x20ec0d3d, 0x00000030, 0x00000001 }, + { 0x00000001, 0x2120013d, 0x00000032, 0x00000000 }, + { 0x00000001, 0x2124013d, 0x00000032, 0x00000000 }, + { 0x00000040, 0x21280d3d, 0x00000032, 0x00000001 }, + { 0x00000040, 0x212c0d3d, 0x00000032, 0x00000001 }, + { 0x00000001, 0x20f0013d, 0x00000034, 0x00000000 }, + { 0x00000040, 0x20f40d3d, 0x00000034, 0x00000001 }, + { 0x00000001, 0x20f8013d, 0x00000034, 0x00000000 }, + { 0x00000040, 0x20fc0d3d, 0x00000034, 0x00000001 }, + { 0x00000001, 0x2130013d, 0x00000036, 0x00000000 }, + { 0x00000001, 0x2134013d, 0x00000036, 0x00000000 }, + { 0x00000040, 0x21380d3d, 0x00000036, 0x00000001 }, + { 0x00000040, 0x213c0d3d, 0x00000036, 0x00000001 }, + { 0x00600040, 0x214077bd, 0x008d00c0, 0x00004020 }, + { 0x00600040, 0x216077bd, 0x008d00e0, 0x00004020 }, + { 0x00600041, 0x214077bd, 0x008d0140, 0x00000060 }, + { 0x00600041, 0x216077bd, 0x008d0160, 0x00000060 }, + { 0x00600040, 0x214077bd, 0x008d0140, 0x0000006c }, + { 0x00600040, 0x216077bd, 0x008d0160, 0x0000006c }, + { 0x00600040, 0x218077bd, 0x008d0100, 0x00004024 }, + { 0x00600040, 0x21a077bd, 0x008d0120, 0x00004024 }, + { 0x00600041, 0x218077bd, 0x008d0180, 0x00000064 }, + { 0x00600041, 0x21a077bd, 0x008d01a0, 0x00000064 }, + { 0x00600040, 0x218077bd, 0x008d0180, 0x0000007c }, + { 0x00600040, 0x21a077bd, 0x008d01a0, 0x0000007c }, + { 0x00600001, 0x202003be, 0x008d0140, 0x00000000 }, + { 0x00600001, 0x204003be, 0x008d0160, 0x00000000 }, + { 0x00600001, 0x206003be, 0x008d0180, 0x00000000 }, + { 0x00600001, 0x208003be, 0x008d01a0, 0x00000000 }, + { 0x00800031, 0x21c01d29, 0x008d0000, 0x02580001 }, + { 0x00600001, 0x22a00021, 0x008d02a0, 0x00000000 }, + { 0x00600040, 0x214077bd, 0x008d00c0, 0x00004020 }, + { 0x00600040, 0x216077bd, 0x008d00e0, 0x00004020 }, + { 0x00600041, 0x214077bd, 0x008d0140, 0x00000080 }, + { 0x00600041, 0x216077bd, 0x008d0160, 0x00000080 }, + { 0x00600040, 0x214077bd, 0x008d0140, 0x0000008c }, + { 0x00600040, 0x216077bd, 0x008d0160, 0x0000008c }, + { 0x00600040, 0x218077bd, 0x008d0100, 0x00004024 }, + { 0x00600040, 0x21a077bd, 0x008d0120, 0x00004024 }, + { 0x00600041, 0x218077bd, 0x008d0180, 0x00000084 }, + { 0x00600041, 0x21a077bd, 0x008d01a0, 0x00000084 }, + { 0x00600040, 0x218077bd, 0x008d0180, 0x0000009c }, + { 0x00600040, 0x21a077bd, 0x008d01a0, 0x0000009c }, + { 0x00600001, 0x202003be, 0x008d0140, 0x00000000 }, + { 0x00600001, 0x204003be, 0x008d0160, 0x00000000 }, + { 0x00600001, 0x206003be, 0x008d0180, 0x00000000 }, + { 0x00600001, 0x208003be, 0x008d01a0, 0x00000000 }, + { 0x00800031, 0x22c01d29, 0x008d0000, 0x02580102 }, + { 0x00600001, 0x23a00021, 0x008d03a0, 0x00000000 }, + { 0x00600041, 0x21c077bd, 0x008d01c0, 0x008d02c0 }, + { 0x00600041, 0x21e077bd, 0x008d01e0, 0x008d02e0 }, + { 0x00600041, 0x220077bd, 0x008d0200, 0x008d0300 }, + { 0x00600041, 0x222077bd, 0x008d0220, 0x008d0320 }, + { 0x00600041, 0x224077bd, 0x008d0240, 0x008d0340 }, + { 0x00600041, 0x226077bd, 0x008d0260, 0x008d0360 }, + { 0x00600041, 0x228077bd, 0x008d0280, 0x008d0380 }, + { 0x00600041, 0x22a077bd, 0x008d02a0, 0x008d03a0 }, + { 0x00600001, 0x204003be, 0x008d01c0, 0x00000000 }, + { 0x00600001, 0x206003be, 0x008d0200, 0x00000000 }, + { 0x00600001, 0x208003be, 0x008d0240, 0x00000000 }, + { 0x00600001, 0x20a003be, 0x008d0280, 0x00000000 }, + { 0x00600001, 0x20c003be, 0x008d01e0, 0x00000000 }, + { 0x00600001, 0x20e003be, 0x008d0220, 0x00000000 }, + { 0x00600001, 0x210003be, 0x008d0260, 0x00000000 }, + { 0x00600001, 0x212003be, 0x008d02a0, 0x00000000 }, + { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 }, + { 0x00800031, 0x24001d28, 0x008d0000, 0x85a04800 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, diff --git a/src/exa_wm_maskca_srcalpha.g4a b/src/exa_wm_maskca_srcalpha.g4a new file mode 100644 index 00000000..e233968c --- /dev/null +++ b/src/exa_wm_maskca_srcalpha.g4a @@ -0,0 +1,202 @@ +/* + * This's for exa composite operation in no mask picture case. + * The simplest case is just sending what src picture has to dst picture. + * XXX: This is still experimental, and should be fixed to support multiple texture + * map, and conditional mul actions. + */ + +/* I think this should be same as in g4a program for texture video, + as we also use 16-pixel dispatch. and SF scale in g3 is useful for us. */ + +/* The initial payload of the thread is always g0. + * WM_URB (incoming URB entries) is g3 + As mask texture coeffient needs extra setup urb starting from g4, we should + shift this location. + + * X0_R is g4->g6 + * X1_R is g5->g7 + * Y0_R is g6->g8 + * Y1_R is g7->g9 + + * X0: {ss0.x, ss0.x+1, ss0.x, ss0.x+1, ss1.x, ss1.x+1, ss1.x, ss1.x+y} + * Y0: {ss0.y, ss0.y, ss0.y+1, ss0.y+1, ss1.y, ss1.y, ss1.y+1, ss1.y+1} + * X1: {ss2.x, ss2.x+1, ss2.x, ss2.x+1, ss3.x, ss3.x+1, ss3.x, ss3.x+y} + * Y1: {ss2.y, ss2.y, ss2.y+1, ss2.y+1, ss3.y, ss3.y, ss3.y+1, ss3.y+1} + */ + +/* multitexture program with src and mask texture */ +/* - load src texture */ +/* - load mask texture */ +/* - mul src.X with mask's alpha */ +/* - write out src.X */ + + /* Set up ss0.x coordinates*/ +mov (1) g6<1>F g1.8<0,1,0>UW { align1 }; +add (1) g6.4<1>F g1.8<0,1,0>UW 1UB { align1 }; +mov (1) g6.8<1>F g1.8<0,1,0>UW { align1 }; +add (1) g6.12<1>F g1.8<0,1,0>UW 1UB { align1 }; + /* Set up ss0.y coordinates */ +mov (1) g8<1>F g1.10<0,1,0>UW { align1 }; +mov (1) g8.4<1>F g1.10<0,1,0>UW { align1 }; +add (1) g8.8<1>F g1.10<0,1,0>UW 1UB { align1 }; +add (1) g8.12<1>F g1.10<0,1,0>UW 1UB { align1 }; + /* set up ss1.x coordinates */ +mov (1) g6.16<1>F g1.12<0,1,0>UW { align1 }; +add (1) g6.20<1>F g1.12<0,1,0>UW 1UB { align1 }; +mov (1) g6.24<1>F g1.12<0,1,0>UW { align1 }; +add (1) g6.28<1>F g1.12<0,1,0>UW 1UB { align1 }; + /* set up ss1.y coordinates */ +mov (1) g8.16<1>F g1.14<0,1,0>UW { align1 }; +mov (1) g8.20<1>F g1.14<0,1,0>UW { align1 }; +add (1) g8.24<1>F g1.14<0,1,0>UW 1UB { align1 }; +add (1) g8.28<1>F g1.14<0,1,0>UW 1UB { align1 }; + /* Set up ss2.x coordinates */ +mov (1) g7<1>F g1.16<0,1,0>UW { align1 }; +add (1) g7.4<1>F g1.16<0,1,0>UW 1UB { align1 }; +mov (1) g7.8<1>F g1.16<0,1,0>UW { align1 }; +add (1) g7.12<1>F g1.16<0,1,0>UW 1UB { align1 }; + /* Set up ss2.y coordinates */ +mov (1) g9<1>F g1.18<0,1,0>UW { align1 }; +mov (1) g9.4<1>F g1.18<0,1,0>UW { align1 }; +add (1) g9.8<1>F g1.18<0,1,0>UW 1UB { align1 }; +add (1) g9.12<1>F g1.18<0,1,0>UW 1UB { align1 }; + /* Set up ss3.x coordinates */ +mov (1) g7.16<1>F g1.20<0,1,0>UW { align1 }; +add (1) g7.20<1>F g1.20<0,1,0>UW 1UB { align1 }; +mov (1) g7.24<1>F g1.20<0,1,0>UW { align1 }; +add (1) g7.28<1>F g1.20<0,1,0>UW 1UB { align1 }; + /* Set up ss3.y coordinates */ +mov (1) g9.16<1>F g1.22<0,1,0>UW { align1 }; +mov (1) g9.20<1>F g1.22<0,1,0>UW { align1 }; +add (1) g9.24<1>F g1.22<0,1,0>UW 1UB { align1 }; +add (1) g9.28<1>F g1.22<0,1,0>UW 1UB { align1 }; + + /* Now, map these screen space coordinates into texture coordinates. */ +/* This is for src texture */ +/* I don't want to change origin ssX coords, as it will be used later in mask */ +/* so store tex coords in g10, g11, g12, g13 */ + + /* subtract screen-space X origin of vertex 0. */ +add (8) g10<1>F g6<8,8,1>F -g1<0,1,0>F { align1 }; +add (8) g11<1>F g7<8,8,1>F -g1<0,1,0>F { align1 }; + /* scale by texture X increment */ +/* Cx[0] */ +mul (8) g10<1>F g10<8,8,1>F g3<0,1,0>F { align1 }; +mul (8) g11<1>F g11<8,8,1>F g3<0,1,0>F { align1 }; + /* add in texture X offset */ +/* Co[0] */ +add (8) g10<1>F g10<8,8,1>F g3.12<0,1,0>F { align1 }; +add (8) g11<1>F g11<8,8,1>F g3.12<0,1,0>F { align1 }; + /* subtract screen-space Y origin of vertex 0. */ +add (8) g12<1>F g8<8,8,1>F -g1.4<0,1,0>F { align1 }; +add (8) g13<1>F g9<8,8,1>F -g1.4<0,1,0>F { align1 }; + /* scale by texture Y increment */ +/* Cy[0] */ +mul (8) g12<1>F g12<8,8,1>F g3.4<0,1,0>F { align1 }; +mul (8) g13<1>F g13<8,8,1>F g3.4<0,1,0>F { align1 }; + /* add in texture Y offset */ +/* Co[1] */ +add (8) g12<1>F g12<8,8,1>F g3.28<0,1,0>F { align1 }; +add (8) g13<1>F g13<8,8,1>F g3.28<0,1,0>F { align1 }; + +/* prepare sampler read back gX register, which would be written back to output */ + +/* use simd16 sampler, param 0 is u, param 1 is v. */ +/* 'payload' loading, assuming tex coord start from g4 */ +mov (8) m1<1>F g10<8,8,1>F { align1 }; +mov (8) m2<1>F g11<8,8,1>F { align1 }; /* param 0 u in m1, m2 */ +mov (8) m3<1>F g12<8,8,1>F { align1 }; +mov (8) m4<1>F g13<8,8,1>F { align1 }; /* param 1 v in m3, m4 */ + +/* m0 will be copied with g0, as it contains send desc */ +/* emit sampler 'send' cmd */ + +/* src texture readback: g14-g21 */ +send (16) 0 /* msg reg index */ + g14<1>UW /* readback */ + g0<8,8,1>UW /* copy to msg start reg*/ + sampler (1,0,F) /* sampler message description, + (binding_table,sampler_index,datatype). + here(src->dst) we should use src_sampler and + src_surface */ + mlen 5 rlen 8 { align1 }; /* required message len 5, readback len 8 */ + +mov (8) g21<1>UD g21<8,8,1>UD { align1 }; /* wait sampler return */ + +/* sampler mask texture, use g10, g11, g12, g13 */ + /* subtract screen-space X origin of vertex 0. */ +add (8) g10<1>F g6<8,8,1>F -g1<0,1,0>F { align1 }; +add (8) g11<1>F g7<8,8,1>F -g1<0,1,0>F { align1 }; + /* scale by texture X increment */ +/* Cx[2] */ +mul (8) g10<1>F g10<8,8,1>F g4<0,1,0>F { align1 }; +mul (8) g11<1>F g11<8,8,1>F g4<0,1,0>F { align1 }; + /* add in texture X offset */ +/* Co[2] */ +add (8) g10<1>F g10<8,8,1>F g4.12<0,1,0>F { align1 }; +add (8) g11<1>F g11<8,8,1>F g4.12<0,1,0>F { align1 }; + /* subtract screen-space Y origin of vertex 0. */ +add (8) g12<1>F g8<8,8,1>F -g1.4<0,1,0>F { align1 }; +add (8) g13<1>F g9<8,8,1>F -g1.4<0,1,0>F { align1 }; + /* scale by texture Y increment */ +/* Cy[2] */ +mul (8) g12<1>F g12<8,8,1>F g4.4<0,1,0>F { align1 }; +mul (8) g13<1>F g13<8,8,1>F g4.4<0,1,0>F { align1 }; + /* add in texture Y offset */ +/* Co[3] */ +add (8) g12<1>F g12<8,8,1>F g4.28<0,1,0>F { align1 }; +add (8) g13<1>F g13<8,8,1>F g4.28<0,1,0>F { align1 }; + +mov (8) m1<1>F g10<8,8,1>F { align1 }; +mov (8) m2<1>F g11<8,8,1>F { align1 }; +mov (8) m3<1>F g12<8,8,1>F { align1 }; +mov (8) m4<1>F g13<8,8,1>F { align1 }; + +/* mask sampler g22-g29 */ +/* binding_table (2), sampler (1) */ +send (16) 0 g22<1>UW g0<8,8,1>UW sampler (2,1,F) mlen 5 rlen 8 { align1 }; +mov (8) g29<1>UD g29<8,8,1>UD { align1 }; /* wait sampler return */ + +/* src channel has no more use, src.A * mask.C */ +mul (8) g14<1>F g22<8,8,1>F g20<8,8,1>F { align1 }; +mul (8) g15<1>F g23<8,8,1>F g21<8,8,1>F { align1 }; +mul (8) g16<1>F g24<8,8,1>F g20<8,8,1>F { align1 }; +mul (8) g17<1>F g25<8,8,1>F g21<8,8,1>F { align1 }; +mul (8) g18<1>F g26<8,8,1>F g20<8,8,1>F { align1 }; +mul (8) g19<1>F g27<8,8,1>F g21<8,8,1>F { align1 }; +mul (8) g20<1>F g28<8,8,1>F g20<8,8,1>F { align1 }; +mul (8) g21<1>F g29<8,8,1>F g21<8,8,1>F { align1 }; + +/* prepare data in m2-m5 for subspan(1,0), m6-m9 for subspan(3,2), then it's ready to write */ +mov (8) m2<1>F g14<8,8,1>F { align1 }; +mov (8) m3<1>F g16<8,8,1>F { align1 }; +mov (8) m4<1>F g18<8,8,1>F { align1 }; +mov (8) m5<1>F g20<8,8,1>F { align1 }; +mov (8) m6<1>F g15<8,8,1>F { align1 }; +mov (8) m7<1>F g17<8,8,1>F { align1 }; +mov (8) m8<1>F g19<8,8,1>F { align1 }; +mov (8) m9<1>F g21<8,8,1>F { align1 }; + +/* m0, m1 are all direct passed by PS thread payload */ +mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable }; + +/* write */ +send (16) 0 acc0<1>UW g0<8,8,1>UW write ( + 0, /* binding_table */ + 8, /* pixel scordboard clear, msg type simd16 single source */ + 4, /* render target write */ + 0 /* no write commit message */ + ) + mlen 10 + rlen 0 + { align1 EOT }; + +nop; +nop; +nop; +nop; +nop; +nop; +nop; +nop; +nop; diff --git a/src/exa_wm_maskca_srcalpha_prog.h b/src/exa_wm_maskca_srcalpha_prog.h new file mode 100644 index 00000000..d83b119f --- /dev/null +++ b/src/exa_wm_maskca_srcalpha_prog.h @@ -0,0 +1,95 @@ + { 0x00000001, 0x20c0013d, 0x00000028, 0x00000000 }, + { 0x00000040, 0x20c40d3d, 0x00000028, 0x00000001 }, + { 0x00000001, 0x20c8013d, 0x00000028, 0x00000000 }, + { 0x00000040, 0x20cc0d3d, 0x00000028, 0x00000001 }, + { 0x00000001, 0x2100013d, 0x0000002a, 0x00000000 }, + { 0x00000001, 0x2104013d, 0x0000002a, 0x00000000 }, + { 0x00000040, 0x21080d3d, 0x0000002a, 0x00000001 }, + { 0x00000040, 0x210c0d3d, 0x0000002a, 0x00000001 }, + { 0x00000001, 0x20d0013d, 0x0000002c, 0x00000000 }, + { 0x00000040, 0x20d40d3d, 0x0000002c, 0x00000001 }, + { 0x00000001, 0x20d8013d, 0x0000002c, 0x00000000 }, + { 0x00000040, 0x20dc0d3d, 0x0000002c, 0x00000001 }, + { 0x00000001, 0x2110013d, 0x0000002e, 0x00000000 }, + { 0x00000001, 0x2114013d, 0x0000002e, 0x00000000 }, + { 0x00000040, 0x21180d3d, 0x0000002e, 0x00000001 }, + { 0x00000040, 0x211c0d3d, 0x0000002e, 0x00000001 }, + { 0x00000001, 0x20e0013d, 0x00000030, 0x00000000 }, + { 0x00000040, 0x20e40d3d, 0x00000030, 0x00000001 }, + { 0x00000001, 0x20e8013d, 0x00000030, 0x00000000 }, + { 0x00000040, 0x20ec0d3d, 0x00000030, 0x00000001 }, + { 0x00000001, 0x2120013d, 0x00000032, 0x00000000 }, + { 0x00000001, 0x2124013d, 0x00000032, 0x00000000 }, + { 0x00000040, 0x21280d3d, 0x00000032, 0x00000001 }, + { 0x00000040, 0x212c0d3d, 0x00000032, 0x00000001 }, + { 0x00000001, 0x20f0013d, 0x00000034, 0x00000000 }, + { 0x00000040, 0x20f40d3d, 0x00000034, 0x00000001 }, + { 0x00000001, 0x20f8013d, 0x00000034, 0x00000000 }, + { 0x00000040, 0x20fc0d3d, 0x00000034, 0x00000001 }, + { 0x00000001, 0x2130013d, 0x00000036, 0x00000000 }, + { 0x00000001, 0x2134013d, 0x00000036, 0x00000000 }, + { 0x00000040, 0x21380d3d, 0x00000036, 0x00000001 }, + { 0x00000040, 0x213c0d3d, 0x00000036, 0x00000001 }, + { 0x00600040, 0x214077bd, 0x008d00c0, 0x00004020 }, + { 0x00600040, 0x216077bd, 0x008d00e0, 0x00004020 }, + { 0x00600041, 0x214077bd, 0x008d0140, 0x00000060 }, + { 0x00600041, 0x216077bd, 0x008d0160, 0x00000060 }, + { 0x00600040, 0x214077bd, 0x008d0140, 0x0000006c }, + { 0x00600040, 0x216077bd, 0x008d0160, 0x0000006c }, + { 0x00600040, 0x218077bd, 0x008d0100, 0x00004024 }, + { 0x00600040, 0x21a077bd, 0x008d0120, 0x00004024 }, + { 0x00600041, 0x218077bd, 0x008d0180, 0x00000064 }, + { 0x00600041, 0x21a077bd, 0x008d01a0, 0x00000064 }, + { 0x00600040, 0x218077bd, 0x008d0180, 0x0000007c }, + { 0x00600040, 0x21a077bd, 0x008d01a0, 0x0000007c }, + { 0x00600001, 0x202003be, 0x008d0140, 0x00000000 }, + { 0x00600001, 0x204003be, 0x008d0160, 0x00000000 }, + { 0x00600001, 0x206003be, 0x008d0180, 0x00000000 }, + { 0x00600001, 0x208003be, 0x008d01a0, 0x00000000 }, + { 0x00800031, 0x21c01d29, 0x008d0000, 0x02580001 }, + { 0x00600001, 0x22a00021, 0x008d02a0, 0x00000000 }, + { 0x00600040, 0x214077bd, 0x008d00c0, 0x00004020 }, + { 0x00600040, 0x216077bd, 0x008d00e0, 0x00004020 }, + { 0x00600041, 0x214077bd, 0x008d0140, 0x00000080 }, + { 0x00600041, 0x216077bd, 0x008d0160, 0x00000080 }, + { 0x00600040, 0x214077bd, 0x008d0140, 0x0000008c }, + { 0x00600040, 0x216077bd, 0x008d0160, 0x0000008c }, + { 0x00600040, 0x218077bd, 0x008d0100, 0x00004024 }, + { 0x00600040, 0x21a077bd, 0x008d0120, 0x00004024 }, + { 0x00600041, 0x218077bd, 0x008d0180, 0x00000084 }, + { 0x00600041, 0x21a077bd, 0x008d01a0, 0x00000084 }, + { 0x00600040, 0x218077bd, 0x008d0180, 0x0000009c }, + { 0x00600040, 0x21a077bd, 0x008d01a0, 0x0000009c }, + { 0x00600001, 0x202003be, 0x008d0140, 0x00000000 }, + { 0x00600001, 0x204003be, 0x008d0160, 0x00000000 }, + { 0x00600001, 0x206003be, 0x008d0180, 0x00000000 }, + { 0x00600001, 0x208003be, 0x008d01a0, 0x00000000 }, + { 0x00800031, 0x22c01d29, 0x008d0000, 0x02580102 }, + { 0x00600001, 0x23a00021, 0x008d03a0, 0x00000000 }, + { 0x00600041, 0x21c077bd, 0x008d02c0, 0x008d0280 }, + { 0x00600041, 0x21e077bd, 0x008d02e0, 0x008d02a0 }, + { 0x00600041, 0x220077bd, 0x008d0300, 0x008d0280 }, + { 0x00600041, 0x222077bd, 0x008d0320, 0x008d02a0 }, + { 0x00600041, 0x224077bd, 0x008d0340, 0x008d0280 }, + { 0x00600041, 0x226077bd, 0x008d0360, 0x008d02a0 }, + { 0x00600041, 0x228077bd, 0x008d0380, 0x008d0280 }, + { 0x00600041, 0x22a077bd, 0x008d03a0, 0x008d02a0 }, + { 0x00600001, 0x204003be, 0x008d01c0, 0x00000000 }, + { 0x00600001, 0x206003be, 0x008d0200, 0x00000000 }, + { 0x00600001, 0x208003be, 0x008d0240, 0x00000000 }, + { 0x00600001, 0x20a003be, 0x008d0280, 0x00000000 }, + { 0x00600001, 0x20c003be, 0x008d01e0, 0x00000000 }, + { 0x00600001, 0x20e003be, 0x008d0220, 0x00000000 }, + { 0x00600001, 0x210003be, 0x008d0260, 0x00000000 }, + { 0x00600001, 0x212003be, 0x008d02a0, 0x00000000 }, + { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 }, + { 0x00800031, 0x24001d28, 0x008d0000, 0x85a04800 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, + { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, @@ -62,8 +62,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "common.h" #define I810_VERSION 4000 -#define I810_NAME "I810" -#define I810_DRIVER_NAME "i810" +#define I810_NAME "intel" +#define I810_DRIVER_NAME "intel" +#define I810_LEGACY_DRIVER_NAME "i810" /* HWMC Surfaces */ #define I810_MAX_SURFACES 7 diff --git a/src/i810_driver.c b/src/i810_driver.c index ab3a2008..b32e07c2 100644 --- a/src/i810_driver.c +++ b/src/i810_driver.c @@ -386,6 +386,21 @@ int I830EntityIndex = -1; static MODULESETUPPROTO(i810Setup); +static XF86ModuleVersionInfo intelVersRec = { + "intel", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +_X_EXPORT XF86ModuleData intelModuleData = { &intelVersRec, i810Setup, NULL }; + static XF86ModuleVersionInfo i810VersRec = { "i810", MODULEVENDORSTRING, @@ -523,7 +538,9 @@ I810Probe(DriverPtr drv, int flags) * driver, and return if there are none. */ if ((numDevSections = - xf86MatchDevice(I810_DRIVER_NAME, &devSections)) <= 0) { + xf86MatchDevice(I810_DRIVER_NAME, &devSections)) <= 0 && + (numDevSections = + xf86MatchDevice(I810_LEGACY_DRIVER_NAME, &devSections)) <= 0) { return FALSE; } diff --git a/src/i810_reg.h b/src/i810_reg.h index 68cce930..d63be025 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -299,6 +299,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define VCLK_DIVISOR_VGA0 0x6000 #define VCLK_DIVISOR_VGA1 0x6004 #define VCLK_POST_DIV 0x6010 +/** Selects a post divisor of 4 instead of 2. */ +# define VGA1_PD_P2_DIV_4 (1 << 15) +/** Overrides the p2 post divisor field */ +# define VGA1_PD_P1_DIV_2 (1 << 13) +# define VGA1_PD_P1_SHIFT 8 +/** P1 value is 2 greater than this field */ +# define VGA1_PD_P1_MASK (0x1f << 8) +/** Selects a post divisor of 4 instead of 2. */ +# define VGA0_PD_P2_DIV_4 (1 << 7) +/** Overrides the p2 post divisor field */ +# define VGA0_PD_P1_DIV_2 (1 << 5) +# define VGA0_PD_P1_SHIFT 0 +/** P1 value is 2 greater than this field */ +# define VGA0_PD_P1_MASK (0x1f << 0) #define POST_DIV_SELECT 0x70 #define POST_DIV_1 0x00 @@ -488,6 +502,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I915G_FENCE_SIZE_32M 0x00000500 #define I915G_FENCE_SIZE_64M 0x00000600 #define I915G_FENCE_SIZE_128M 0x00000700 +#define I965_FENCE_X_MAJOR 0x00000000 +#define I965_FENCE_Y_MAJOR 0x00000002 #define FENCE_PITCH_1 0x00000000 #define FENCE_PITCH_2 0x00000010 #define FENCE_PITCH_4 0x00000020 @@ -845,9 +861,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ # define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ # define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +/** + * The i830 generation, in DAC/serial mode, defines p1 as two plus this + * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 +/** + * The i830 generation, in LVDS mode, defines P1 as the bit number set within + * this field (only one bit may be set). + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 # define DPLL_FPA01_P1_POST_DIV_SHIFT 16 # define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */ -# define DPLL_FPA01_P1_POS_DIV_MASK_I830 0x001f0000 /* i830 */ # define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ # define PLL_REF_INPUT_DREFCLK (0 << 13) # define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ @@ -1690,6 +1715,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PIPEACONF_ENABLE (1<<31) #define PIPEACONF_DISABLE 0 #define PIPEACONF_DOUBLE_WIDE (1<<30) +#define I965_PIPECONF_ACTIVE (1<<30) #define PIPEACONF_SINGLE_WIDE 0 #define PIPEACONF_PIPE_UNLOCKED 0 #define PIPEACONF_PIPE_LOCKED (1<<25) @@ -1848,6 +1874,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I852_GME 0x2 #define I852_GM 0x5 +#define I915_GCFGC 0xf0 +#define I915_LOW_FREQUENCY_ENABLE (1 << 7) +#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) +#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) +#define I915_DISPLAY_CLOCK_MASK (7 << 4) + +#define I855_HPLLCC 0xc0 +#define I855_CLOCK_CONTROL_MASK (3 << 0) +#define I855_CLOCK_133_200 (0 << 0) +#define I855_CLOCK_100_200 (1 << 0) +#define I855_CLOCK_100_133 (2 << 0) +#define I855_CLOCK_166_250 (3 << 0) + /* BLT commands */ #define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3)) #define COLOR_BLT_WRITE_ALPHA (1<<21) @@ -1867,6 +1906,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define SRC_COPY_BLT_WRITE_RGB (1<<20) +#define XY_PAT_BLT_IMMEDIATE ((2<<29)|(0x72<<22)) + #define XY_MONO_PAT_BLT_CMD ((0x2<<29)|(0x52<<22)|0x7) #define XY_MONO_PAT_VERT_SEED ((1<<10)|(1<<9)|(1<<8)) #define XY_MONO_PAT_HORT_SEED ((1<<14)|(1<<13)|(1<<12)) @@ -58,8 +58,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86int10.h" #include "vbe.h" #include "vgaHW.h" -#include "i830_xf86Crtc.h" -#include "i830_randr.h" +#include "xf86Crtc.h" +#include "xf86RandR12.h" #ifdef XF86DRI #include "xf86drm.h" @@ -113,30 +113,52 @@ typedef CARD8(*I830ReadIndexedByteFunc)(I830Ptr pI830, IOADDRESS addr, typedef void (*I830WriteByteFunc)(I830Ptr pI830, IOADDRESS addr, CARD8 value); typedef CARD8(*I830ReadByteFunc)(I830Ptr pI830, IOADDRESS addr); -/* Linear region allocated in framebuffer. */ -typedef struct _I830MemPool *I830MemPoolPtr; -typedef struct _I830MemRange *I830MemRangePtr; -typedef struct _I830MemRange { - long Start; - long End; - long Size; - unsigned long Physical; - unsigned long Offset; /* Offset of AGP-allocated portion */ - unsigned long Alignment; - int Key; - I830MemPoolPtr Pool; -} I830MemRange; - -typedef struct _I830MemPool { - I830MemRange Total; - I830MemRange Free; - I830MemRange Fixed; - I830MemRange Allocated; -} I830MemPool; +/** Record of a linear allocation in the aperture. */ +typedef struct _i830_memory i830_memory; +struct _i830_memory { + /** Offset of the allocation in card VM */ + unsigned long offset; + /** End of the allocation in card VM */ + unsigned long end; + /** + * Requested size of the allocation: doesn't count padding. + * + * Any bound memory will cover offset to (offset + size). + */ + unsigned long size; + /** + * Physical (or more properly, bus) address of the allocation. + * Only set if requested during allocation. + */ + unsigned long bus_addr; + /** AGP memory handle */ + int key; + /** + * Whether or not the AGP memory (if any) is currently bound. + */ + Bool bound; + /** + * Offset that the AGP-allocated memory (if any) is to be bound to. + * + * This is either @offset or pI830->stolen_size + */ + unsigned long agp_offset; + + /** Description of the allocation, for logging */ + char *name; + + /** @{ + * Memory allocator linked list pointers + */ + i830_memory *next; + i830_memory *prev; + /** @} */ + +}; typedef struct { int tail_mask; - I830MemRange mem; + i830_memory *mem; unsigned char *virtual_start; int head; int tail; @@ -144,10 +166,6 @@ typedef struct { } I830RingBuffer; typedef struct { - unsigned int Fence[FENCE_NEW_NR * 2]; -} I830RegRec, *I830RegPtr; - -typedef struct { int lastInstance; int refCount; ScrnInfoPtr pScrn_1; @@ -206,8 +224,8 @@ typedef struct _I830CrtcPrivateRec { ExaOffscreenArea *rotate_mem_exa; #endif - I830MemRange cursor_mem; - I830MemRange cursor_mem_argb; + i830_memory *cursor_mem; + i830_memory *cursor_mem_argb; } I830CrtcPrivateRec, *I830CrtcPrivatePtr; #define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private) @@ -232,21 +250,6 @@ enum last_3d { LAST_3D_ROTATION }; -#if 0 -typedef struct _I830PipeRec { - Bool enabled; - int x; - int y; - Bool cursorInRange; - Bool cursorShown; - DisplayModeRec curMode; - DisplayModeRec desiredMode; -#ifdef RANDR_12_INTERFACE - RRCrtcPtr randr_crtc; -#endif -} I830PipeRec, *I830PipePtr; -#endif - typedef struct _I830Rec { unsigned char *MMIOBase; unsigned char *FbBase; @@ -264,50 +267,41 @@ typedef struct _I830Rec { /* These are set in PreInit and never changed. */ long FbMapSize; - long TotalVideoRam; - I830MemRange StolenMemory; /* pre-allocated memory */ - /* These change according to what has been allocated. */ - long FreeMemory; - I830MemRange MemoryAperture; - I830MemPool StolenPool; - long allocatedMemory; + i830_memory *memory_list; /**< Linked list of video memory allocations */ + long stolen_size; /**< bytes of pre-bound stolen memory */ + int gtt_acquired; /**< whether we currently own the AGP */ - /* Regions allocated either from the above pools, or from agpgart. */ - /* for single and dual head configurations */ - I830MemRange FrontBuffer; - I830MemRange FrontBuffer2; - I830MemRange Scratch; - I830MemRange Scratch2; + i830_memory *front_buffer; + i830_memory *front_buffer_2; + i830_memory *xaa_scratch; + i830_memory *xaa_scratch_2; #ifdef I830_USE_EXA - I830MemRange Offscreen; - I830MemRange EXAStateMem; /* specific exa state for G965 */ + i830_memory *exa_offscreen; + i830_memory *exa_965_state; #endif /* Regions allocated either from the above pools, or from agpgart. */ I830RingBuffer *LpRing; -#if REMAP_RESERVED - I830MemRange Dummy; -#endif - #ifdef I830_XV /* For Xvideo */ - I830MemRange *OverlayMem; - I830MemRange LinearMem; + i830_memory *overlay_regs; + i830_memory *xaa_linear; #endif unsigned long LinearAlloc; XF86ModReqInfo shadowReq; /* to test for later libshadow */ Rotation rotation; - int displayWidth; void (*PointerMoved)(int, int, int); CreateScreenResourcesProcPtr CreateScreenResources; int *used3D; - I830MemRange ContextMem; + i830_memory *logical_context; #ifdef XF86DRI - I830MemRange BackBuffer; - I830MemRange DepthBuffer; - I830MemRange TexMem; + i830_memory *back_buffer; + i830_memory *depth_buffer; + i830_memory *textures; /**< Compatibility texture memory */ + i830_memory *memory_manager; /**< DRI memory manager aperture */ + int TexGranularity; int drmMinor; Bool have3DWindows; @@ -345,13 +339,21 @@ typedef struct _I830Rec { unsigned int BR[20]; - int GttBound; - unsigned char **ScanlineColorExpandBuffers; int NumScanlineColorExpandBuffers; int nextColorExpandBuf; - I830RegRec ModeReg; + /** + * Values to be programmed into the fence registers. + * + * Pre-965, this is a list of FENCE_NR (8) CARD32 registers that + * contain their start, size, and pitch. On the 965, it is a list of + * FENCE_NEW_NR CARD32s for the start and pitch fields (low 32 bits) of + * the fence registers followed by FENCE_NEW_NR CARD32s for the end fields + * (high 32 bits) of the fence registers. + */ + unsigned int fence[FENCE_NEW_NR * 2]; + unsigned int next_fence; Bool useEXA; Bool noAccel; @@ -422,7 +424,6 @@ typedef struct _I830Rec { /* Broken-out options. */ OptionInfoPtr Options; - /* Stolen memory support */ Bool StolenOnly; Bool swfSaved; @@ -514,7 +515,6 @@ typedef struct _I830Rec { } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) -#define I830REGPTR(p) (&(I830PTR(p)->ModeReg)) #define I830_SELECT_FRONT 0 #define I830_SELECT_BACK 1 @@ -536,9 +536,6 @@ extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer); extern void I830RefreshRing(ScrnInfoPtr pScrn); extern void I830EmitFlush(ScrnInfoPtr pScrn); -extern Bool I830DGAReInit(ScreenPtr pScreen); -extern Bool I830DGAInit(ScreenPtr pScreen); - #ifdef I830_XV extern void I830InitVideo(ScreenPtr pScreen); extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on); @@ -546,9 +543,6 @@ extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on); #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); @@ -579,32 +573,28 @@ extern void I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, extern void I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); -extern void I830ResetAllocations(ScrnInfoPtr pScrn, const int flags); +Bool i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, + unsigned long size); +void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, + const char *prefix); +void i830_reset_allocations(ScrnInfoPtr pScrn); +void i830_free_3d_memory(ScrnInfoPtr pScrn); +void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem); extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); -extern long I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn); -extern Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags); -extern Bool I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool); -extern Bool I830FixupOffsets(ScrnInfoPtr pScrn); -extern Bool I830BindAGPMemory(ScrnInfoPtr pScrn); -extern Bool I830UnbindAGPMemory(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); +Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn); +Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn); + extern Bool I830IsPrimary(ScrnInfoPtr pScrn); -extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem); extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name); /* return a mask of output indices matching outputs against type_mask */ int i830_output_clones (ScrnInfoPtr pScrn, int type_mask); +/* i830_bios.c */ +DisplayModePtr i830_bios_get_panel_mode(ScrnInfoPtr pScrn); + /* i830_display.c */ Bool i830PipeHasType (xf86CrtcPtr crtc, int type); @@ -622,6 +612,9 @@ extern void i830MarkSync(ScrnInfoPtr pScrn); extern void i830WaitSync(ScrnInfoPtr pScrn); /* i830_memory.c */ +Bool i830_bind_all_memory(ScrnInfoPtr pScrn); +Bool i830_unbind_all_memory(ScrnInfoPtr pScrn); + Bool I830BindAGPMemory(ScrnInfoPtr pScrn); Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn); #ifdef I830_USE_XAA @@ -671,23 +664,8 @@ extern const int I830PatternROP[16]; extern const int I830CopyROP[16]; /* Flags for memory allocation function */ -#define FROM_ANYWHERE 0x00000000 -#define FROM_POOL_ONLY 0x00000001 -#define FROM_NEW_ONLY 0x00000002 -#define FROM_MASK 0x0000000f - -#define ALLOCATE_AT_TOP 0x00000010 -#define ALLOCATE_AT_BOTTOM 0x00000020 -#define FORCE_GAPS 0x00000040 - -#define NEED_PHYSICAL_ADDR 0x00000100 -#define ALIGN_BOTH_ENDS 0x00000200 -#define FORCE_LOW 0x00000400 - -#define ALLOC_NO_TILING 0x00001000 -#define ALLOC_INITIAL 0x00002000 - -#define ALLOCATE_DRY_RUN 0x80000000 +#define NEED_PHYSICAL_ADDR 0x00000001 +#define ALIGN_BOTH_ENDS 0x00000002 /* Chipset registers for VIDEO BIOS memory RW access */ #define _855_DRAM_RW_CONTROL 0x58 diff --git a/src/i830_accel.c b/src/i830_accel.c index db3168a8..49a9c134 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -117,7 +117,7 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis) ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) - ring->space += ring->mem.Size; + ring->space += ring->mem->size; iters++; now = GetTimeInMillis(); @@ -195,9 +195,9 @@ I830Sync(ScrnInfoPtr pScrn) ADVANCE_LP_RING(); } - I830WaitLpRing(pScrn, pI830->LpRing->mem.Size - 8, 0); + I830WaitLpRing(pScrn, pI830->LpRing->mem->size - 8, 0); - pI830->LpRing->space = pI830->LpRing->mem.Size - 8; + pI830->LpRing->space = pI830->LpRing->mem->size - 8; pI830->nextColorExpandBuf = 0; } @@ -226,10 +226,10 @@ I830SelectBuffer(ScrnInfoPtr pScrn, int buffer) switch (buffer) { #ifdef XF86DRI case I830_SELECT_BACK: - pI830->bufferOffset = pI830->BackBuffer.Start; + pI830->bufferOffset = pI830->back_buffer->offset; break; case I830_SELECT_DEPTH: - pI830->bufferOffset = pI830->DepthBuffer.Start; + pI830->bufferOffset = pI830->depth_buffer->offset; break; #endif default: @@ -252,7 +252,7 @@ I830RefreshRing(ScrnInfoPtr pScrn) pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); if (pI830->LpRing->space < 0) - pI830->LpRing->space += pI830->LpRing->mem.Size; + pI830->LpRing->space += pI830->LpRing->mem->size; i830MarkSync(pScrn); } diff --git a/src/i830_bios.c b/src/i830_bios.c index a9ef474d..cb886b54 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -122,8 +122,16 @@ i830GetBIOS(ScrnInfoPtr pScrn) return bios; } -Bool -i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn) +/** + * Returns the BIOS's fixed panel mode. + * + * Note that many BIOSes will have the appropriate tables for a panel even when + * a panel is not attached. Additionally, many BIOSes adjust table sizes or + * offsets, such that this parsing fails. Thus, almost any other method for + * detecting the panel mode is preferable. + */ +DisplayModePtr +i830_bios_get_panel_mode(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); struct vbt_header *vbt; @@ -131,12 +139,11 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn) int vbt_off, bdb_off, bdb_block_off, block_size; int panel_type = -1; unsigned char *bios; - Bool found_panel_info = FALSE; bios = i830GetBIOS(pScrn); if (bios == NULL) - return FALSE; + return NULL; vbt_off = INTEL_BIOS_16(0x1a); vbt = (struct vbt_header *)(bios + vbt_off); @@ -146,7 +153,7 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn) if (memcmp(bdb->signature, "BIOS_DATA_BLOCK ", 16) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad BDB signature\n"); xfree(bios); - return FALSE; + return NULL; } for (bdb_block_off = bdb->header_size; bdb_block_off < bdb->bdb_size; @@ -163,7 +170,6 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn) id = INTEL_BIOS_8(start); block_size = INTEL_BIOS_16(start + 1) + 3; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found BDB block type %d\n", id); switch (id) { case 40: lvds1 = (struct lvds_bdb_1 *)(bios + start); @@ -227,13 +233,11 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn) "Found panel mode in BIOS VBT tables:\n"); xf86PrintModeline(pScrn->scrnIndex, fixed_mode); - pI830->panel_fixed_mode = fixed_mode; - - found_panel_info = TRUE; - break; + xfree(bios); + return fixed_mode; } } xfree(bios); - return found_panel_info; + return NULL; } diff --git a/src/i830_bios.h b/src/i830_bios.h index 9bd0db8a..881d5c86 100644 --- a/src/i830_bios.h +++ b/src/i830_bios.h @@ -114,6 +114,3 @@ struct lvds_bdb_2 { CARD8 table_size; /* not sure on this one */ struct lvds_bdb_2_entry panels[16]; } __attribute__((packed)); - -Bool -i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn); diff --git a/src/i830_crt.c b/src/i830_crt.c index 573e6526..77061653 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -31,7 +31,7 @@ #include "xf86.h" #include "i830.h" -#include "i830_xf86Modes.h" +#include "xf86Modes.h" #include "i830_display.h" static void diff --git a/src/i830_cursor.c b/src/i830_cursor.c index 464eb6dd..85785112 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -88,20 +88,20 @@ I830SetPipeCursorBase (xf86CrtcPtr crtc) I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE); - I830MemRange *cursor_mem; + i830_memory *cursor_mem; if (pipe >= xf86_config->num_crtc) FatalError("Bad pipe number for cursor base setting\n"); if (pI830->CursorIsARGB) - cursor_mem = &intel_crtc->cursor_mem_argb; + cursor_mem = intel_crtc->cursor_mem_argb; else - cursor_mem = &intel_crtc->cursor_mem; + cursor_mem = intel_crtc->cursor_mem; if (pI830->CursorNeedsPhysical) { - OUTREG(cursor_base, cursor_mem->Physical); + OUTREG(cursor_base, cursor_mem->bus_addr); } else { - OUTREG(cursor_base, cursor_mem->Start); + OUTREG(cursor_base, cursor_mem->offset); } } @@ -281,7 +281,7 @@ I830CRTCLoadCursorImage(xf86CrtcPtr crtc, unsigned char *src) ScrnInfoPtr pScrn = crtc->scrn; I830Ptr pI830 = I830PTR(pScrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - CARD8 *pcurs = (CARD8 *) (pI830->FbBase + intel_crtc->cursor_mem.Start); + CARD8 *pcurs = (CARD8 *) (pI830->FbBase + intel_crtc->cursor_mem->offset); int x, y; DPRINTF(PFX, "I830LoadCursorImage\n"); @@ -372,7 +372,7 @@ static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) for (i = 0; i < xf86_config->num_crtc; i++) { I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; - if (!intel_crtc->cursor_mem_argb.Start) + if (intel_crtc->cursor_mem_argb == NULL) return FALSE; } @@ -389,7 +389,8 @@ static void I830CRTCLoadCursorARGB (xf86CrtcPtr crtc, CursorPtr pCurs) { I830Ptr pI830 = I830PTR(crtc->scrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - CARD32 *dst = (CARD32 *) (pI830->FbBase + intel_crtc->cursor_mem_argb.Start); + CARD32 *dst = (CARD32 *) (pI830->FbBase + + intel_crtc->cursor_mem_argb->offset); CARD32 *image = (CARD32 *)pCurs->bits->argb; int x, y, w, h; @@ -510,7 +511,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) hotspoty = I810_CURSOR_Y; break; case RR_Rotate_270: - thisx = mode->VDisplay - (root_y - crtc->y); + thisx = mode->HDisplay - (root_y - crtc->y); thisy = (root_x - crtc->x); hotspotx = I810_CURSOR_Y; break; diff --git a/src/i830_debug.c b/src/i830_debug.c index e0be0a4a..dccaa7ea 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -25,6 +25,11 @@ * */ +#ifdef REG_DUMPER +#include "reg_dumper/reg_dumper.h" + +#else + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -34,6 +39,10 @@ #include "i830_debug.h" #include <strings.h> +#endif + +#include "i810_reg.h" + #define DEBUGSTRING(func) static char *func(I830Ptr pI830, int reg, CARD32 val) DEBUGSTRING(i830_debug_xyminus1) @@ -69,8 +78,12 @@ DEBUGSTRING(i830_debug_dspcntr) DEBUGSTRING(i830_debug_pipeconf) { char *enabled = val & PIPEACONF_ENABLE ? "enabled" : "disabled"; - char *wide = val & PIPEACONF_DOUBLE_WIDE ? "double-wide" : "single-wide"; - return XNFprintf("%s, %s", enabled, wide); + char *bit30; + if (IS_I965G(pI830)) + bit30 = val & I965_PIPECONF_ACTIVE ? "active" : "inactive"; + else + bit30 = val & PIPEACONF_DOUBLE_WIDE ? "double-wide" : "single-wide"; + return XNFprintf("%s, %s", enabled, bit30); } DEBUGSTRING(i830_debug_hvtotal) @@ -98,6 +111,28 @@ DEBUGSTRING(i830_debug_fp) ((val & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT)); } +DEBUGSTRING(i830_debug_vga_pd) +{ + int vga0_p1, vga0_p2, vga1_p1, vga1_p2; + + /* XXX: i9xx version */ + + if (val & VGA0_PD_P1_DIV_2) + vga0_p1 = 2; + else + vga0_p1 = ((val & VGA0_PD_P1_MASK) >> VGA0_PD_P1_SHIFT) + 2; + vga0_p2 = (val & VGA0_PD_P2_DIV_4) ? 4 : 2; + + if (val & VGA1_PD_P1_DIV_2) + vga1_p1 = 2; + else + vga1_p1 = ((val & VGA1_PD_P1_MASK) >> VGA1_PD_P1_SHIFT) + 2; + vga1_p2 = (val & VGA1_PD_P2_DIV_4) ? 4 : 2; + + return XNFprintf("vga0 p1 = %d, p2 = %d, vga1 p1 = %d, p2 = %d", + vga0_p1, vga0_p2, vga1_p1, vga1_p2); +} + DEBUGSTRING(i830_debug_pp_status) { char *status = val & PP_ON ? "on" : "off"; @@ -136,18 +171,44 @@ DEBUGSTRING(i830_debug_dpll) char sdvoextra[20]; int p1, p2 = 0; - p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); - switch (val & DPLL_MODE_MASK) { - case DPLLB_MODE_DAC_SERIAL: - mode = "dac/serial"; - p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; - break; - case DPLLB_MODE_LVDS: - mode = "LVDS"; - p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; - break; + if (IS_I9XX(pI830)) { + p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + switch (val & DPLL_MODE_MASK) { + case DPLLB_MODE_DAC_SERIAL: + mode = "DAC/serial"; + p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; + break; + case DPLLB_MODE_LVDS: + mode = "LVDS"; + p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; + break; + } + } else { + Bool is_lvds = (INREG(LVDS) & LVDS_PORT_EN) && (reg == DPLL_B); + + if (val & PLL_P2_DIVIDE_BY_4) + p2 = 4; + else + p2 = 2; + + if (is_lvds) { + mode = "LVDS"; + /* Map the bit number set from (1, 6) to (-1, 4). */ + p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + } else { + mode = "DAC/serial"; + if (val & PLL_P1_DIVIDE_BY_TWO) { + p1 = 2; + } else { + /* Map the number in the field to (1, 31) */ + p1 = ((val & DPLL_FPA01_P1_POST_DIV_MASK_I830) >> + DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; + } + } } + switch (val & PLL_REF_INPUT_MASK) { case PLL_REF_INPUT_DREFCLK: clock = "default"; @@ -158,7 +219,12 @@ DEBUGSTRING(i830_debug_dpll) case PLL_REF_INPUT_TVCLKINBC: clock = "TV B/C"; break; + case PLLB_REF_INPUT_SPREADSPECTRUMIN: + if (reg == DPLL_B) + clock = "spread spectrum"; + break; } + if (IS_I945G(pI830) || IS_I945GM(pI830)) { sprintf(sdvoextra, ", SDVO mult %d", (int)((val & SDVO_MULTIPLIER_MASK) >> @@ -167,9 +233,9 @@ DEBUGSTRING(i830_debug_dpll) sdvoextra[0] = '\0'; } - return XNFprintf("%s, %s%s, %s mode, %s clock, p1 = %d, " + return XNFprintf("%s, %s%s, %s clock, %s mode, p1 = %d, " "p2 = %d%s%s", - enabled, dvomode, vgamode, mode, clock, p1, p2, + enabled, dvomode, vgamode, clock, mode, p1, p2, fpextra, sdvoextra); } @@ -229,9 +295,9 @@ static struct i830SnapshotRec { char *(*debug_output)(I830Ptr pI830, int reg, CARD32 val); CARD32 val; } i830_snapshot[] = { - DEFINEREG(VCLK_DIVISOR_VGA0), - DEFINEREG(VCLK_DIVISOR_VGA1), - DEFINEREG(VCLK_POST_DIV), + DEFINEREG2(VCLK_DIVISOR_VGA0, i830_debug_fp), + DEFINEREG2(VCLK_DIVISOR_VGA1, i830_debug_fp), + DEFINEREG2(VCLK_POST_DIV, i830_debug_vga_pd), DEFINEREG2(DPLL_TEST, i830_debug_dpll_test), DEFINEREG(D_STATE), DEFINEREG(DSPCLK_GATE_D), @@ -353,6 +419,7 @@ static struct i830SnapshotRec { #undef DEFINEREG #define NUM_I830_SNAPSHOTREGS (sizeof(i830_snapshot) / sizeof(i830_snapshot[0])) +#ifndef REG_DUMPER void i830TakeRegSnapshot(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); @@ -397,6 +464,7 @@ void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where) } } } +#endif /* !REG_DUMPER */ static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int min, int max) { @@ -530,6 +598,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn) xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsEnd\n"); } +#ifndef REG_DUMPER /* Famous last words */ void @@ -742,3 +811,4 @@ i830_check_error_state(ScrnInfoPtr pScrn) return (errors != 0); } +#endif /* !REG_DUMPER */ diff --git a/src/i830_dga.c b/src/i830_dga.c deleted file mode 100644 index 6d071ac3..00000000 --- a/src/i830_dga.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright 2000 by Alan Hourihane, Sychdyn, North Wales, UK. - * - * 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 Alan Hourihane not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Alan Hourihane makes no representations - * about the suitability of this software for any purpose. It is provided - * "as is" without express or implied warranty. - * - * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ALAN HOURIHANE 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. - * - * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> - */ -/* - * 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. - */ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c,v 1.2 2002/11/05 02:01:18 dawes Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86Pci.h" -#include "xf86PciInfo.h" -#include "xaa.h" -#include "xaalocal.h" -#include "i830.h" -#include "i810_reg.h" -#include "dgaproc.h" -#include "vgaHW.h" - -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); -static void I830_SetViewport(ScrnInfoPtr, int, int, int); -static void I830_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); -static void I830_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); - -#if 0 -static void I830_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, - unsigned long); -#endif - -static -DGAFunctionRec I830DGAFuncs = { - I830_OpenFramebuffer, - I830_CloseFramebuffer, - I830_SetMode, - I830_SetViewport, - I830_GetViewport, - I830_Sync, - I830_FillRect, - I830_BlitRect, -#if 0 - I830_BlitTransRect -#else - NULL -#endif -}; - -static DGAModePtr -I830DGAModes (ScreenPtr pScreen, int *nump) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - DGAModePtr modes = NULL, newmodes = NULL, currentMode; - DisplayModePtr pMode, firstMode; - int Bpp = pScrn->bitsPerPixel >> 3; - int num = 0; - - pMode = firstMode = pScrn->modes; - - while (pMode) { - - newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); - - if (!newmodes) { - xfree(modes); - return NULL; - } - modes = newmodes; - - currentMode = modes + num; - num++; - - currentMode->mode = pMode; - currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; - if (!pI830->noAccel) - currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; - if (pMode->Flags & V_DBLSCAN) - currentMode->flags |= DGA_DOUBLESCAN; - if (pMode->Flags & V_INTERLACE) - currentMode->flags |= DGA_INTERLACED; - currentMode->byteOrder = pScrn->imageByteOrder; - currentMode->depth = pScrn->depth; - currentMode->bitsPerPixel = pScrn->bitsPerPixel; - currentMode->red_mask = pScrn->mask.red; - currentMode->green_mask = pScrn->mask.green; - currentMode->blue_mask = pScrn->mask.blue; - currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; - currentMode->viewportWidth = pMode->HDisplay; - currentMode->viewportHeight = pMode->VDisplay; - currentMode->xViewportStep = (Bpp == 3) ? 2 : 1; - currentMode->yViewportStep = 1; - currentMode->viewportFlags = DGA_FLIP_RETRACE; - currentMode->offset = 0; - 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 = ((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 - - currentMode->viewportWidth; - /* this might need to get clamped to some maximum */ - currentMode->maxViewportY = currentMode->imageHeight - - currentMode->viewportHeight; - - pMode = pMode->next; - if (pMode == firstMode) - break; - } - *nump = num; - return modes; -} - -Bool -I830DGAReInit(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - int num; - DGAModePtr modes; - - modes = I830DGAModes (pScreen, &num); - if (!modes) - return FALSE; - - if (pI830->DGAModes) - xfree (pI830->DGAModes); - - pI830->numDGAModes = num; - pI830->DGAModes = modes; - return DGAReInitModes (pScreen, modes, num); -} - -Bool -I830DGAInit(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - int num; - DGAModePtr modes; - - modes = I830DGAModes (pScreen, &num); - if (!modes) - return FALSE; - - pI830->numDGAModes = num; - pI830->DGAModes = modes; - - return DGAInit(pScreen, &I830DGAFuncs, modes, num); -} - -static DisplayModePtr I830SavedDGAModes[MAXSCREENS]; - -static Bool -I830_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) -{ - int index = pScrn->pScreen->myNum; - I830Ptr pI830 = I830PTR(pScrn); - - MARKER(); - - 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); - pI830->DGAactive = FALSE; - } - } else { - if (!pI830->DGAactive) { - 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); - } - - return TRUE; -} - -static int -I830_GetViewport(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - MARKER(); - - return pI830->DGAViewportStatus; -} - -static void -I830_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) -{ - I830Ptr pI830 = I830PTR(pScrn); - vgaHWPtr hwp = VGAHWPTR(pScrn); - - MARKER(); - - pScrn->AdjustFrame(pScrn->pScreen->myNum, x, y, flags); - - /* wait for retrace */ - while ((hwp->readST01(hwp) & 0x08)) ; - while (!(hwp->readST01(hwp) & 0x08)) ; - - pI830->DGAViewportStatus = 0; -} - -static void -I830_FillRect(ScrnInfoPtr pScrn, - int x, int y, int w, int h, unsigned long color) -{ -#ifdef I830_USE_XAA - I830Ptr pI830 = I830PTR(pScrn); - - MARKER(); - - if (pI830->AccelInfoRec) { - (*pI830->AccelInfoRec->SetupForSolidFill) (pScrn, color, GXcopy, ~0); - (*pI830->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); - SET_SYNC_FLAG(pI830->AccelInfoRec); - } -#endif -} - -static void -I830_Sync(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE; - - MARKER(); - - if (pI830->noAccel) - return; - - if (IS_I965G(pI830)) - flags = 0; - - BEGIN_LP_RING(2); - OUT_RING(MI_FLUSH | flags); - OUT_RING(MI_NOOP); /* pad to quadword */ - ADVANCE_LP_RING(); - - I830WaitLpRing(pScrn, pI830->LpRing->mem.Size - 8, 0); - - pI830->LpRing->space = pI830->LpRing->mem.Size - 8; - pI830->nextColorExpandBuf = 0; -} - -static void -I830_BlitRect(ScrnInfoPtr pScrn, - int srcx, int srcy, int w, int h, int dstx, int dsty) -{ -#ifdef I830_USE_XAA - I830Ptr pI830 = I830PTR(pScrn); - - MARKER(); - - if (pI830->AccelInfoRec) { - int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; - int ydir = (srcy < dsty) ? -1 : 1; - - (*pI830->AccelInfoRec->SetupForScreenToScreenCopy) (pScrn, xdir, ydir, - GXcopy, ~0, -1); - (*pI830->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrn, srcx, srcy, - dstx, dsty, w, h); - SET_SYNC_FLAG(pI830->AccelInfoRec); - } -#endif -} - -#if 0 -static void -I830_BlitTransRect(ScrnInfoPtr pScrn, - int srcx, int srcy, - int w, int h, int dstx, int dsty, unsigned long color) -{ - - MARKER(); - - /* this one should be separate since the XAA function would - * prohibit usage of ~0 as the key */ -} -#endif - -static Bool -I830_OpenFramebuffer(ScrnInfoPtr pScrn, - char **name, - unsigned char **mem, int *size, int *offset, int *flags) -{ - I830Ptr pI830 = I830PTR(pScrn); - - MARKER(); - - *name = NULL; /* no special device */ - 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; - - DPRINTF(PFX, - " mem == 0x%.8x (pI830->LinearAddr)\n" - "size == %lu (pI830->FbMapSize)\n", *mem, *size); - - 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)) { - pScrn->fbOffset = pI830->FrontBuffer.Start; - } else { - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - - 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_display.c b/src/i830_display.c index 82029850..e9666de0 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -41,7 +41,7 @@ #include "i830_bios.h" #include "i830_display.h" #include "i830_debug.h" -#include "i830_xf86Modes.h" +#include "xf86Modes.h" typedef struct { /* given values */ @@ -85,10 +85,15 @@ typedef struct { #define I8XX_M2_MAX 16 #define I8XX_P_MIN 4 #define I8XX_P_MAX 128 +/* LVDS p1 value can go from 1 to 6, while DAC goes from 2 to 33. These + * values below get 2 added in the clock calculations. + */ #define I8XX_P1_MIN 0 -#define I8XX_P1_MAX 30 -#define I8XX_P2_SLOW 1 -#define I8XX_P2_FAST 0 +#define I8XX_P1_MAX 31 +#define I8XX_P1_LVDS_MIN -1 +#define I8XX_P1_LVDS_MAX 4 +#define I8XX_P2_SLOW 1 /* this is a bit shift amount */ +#define I8XX_P2_FAST 0 /* this is a bit shift amount */ #define I8XX_P2_SLOW_LIMIT 165000 #define I9XX_DOT_MIN 20000 @@ -116,12 +121,13 @@ typedef struct { #define I9XX_P2_LVDS_FAST 7 #define I9XX_P2_LVDS_SLOW_LIMIT 112000 -#define INTEL_LIMIT_I8XX 0 -#define INTEL_LIMIT_I9XX_SDVO_DAC 1 -#define INTEL_LIMIT_I9XX_LVDS 2 +#define INTEL_LIMIT_I8XX_DVO_DAC 0 +#define INTEL_LIMIT_I8XX_LVDS 1 +#define INTEL_LIMIT_I9XX_SDVO_DAC 2 +#define INTEL_LIMIT_I9XX_LVDS 3 static const intel_limit_t intel_limits[] = { - { + { /* INTEL_LIMIT_I8XX_DVO_DAC */ .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, @@ -133,7 +139,19 @@ static const intel_limit_t intel_limits[] = { .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, }, - { + { /* INTEL_LIMIT_I8XX_LVDS */ + .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, + .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, + .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, + .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX }, + .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX }, + .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX }, + .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX }, + .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX }, + .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, + .p2_slow = I8XX_P2_FAST, .p2_fast = I8XX_P2_FAST }, + }, + { /* INTEL_LIMIT_I9XX_SDVO_DAC */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, @@ -145,7 +163,7 @@ static const intel_limit_t intel_limits[] = { .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, }, - { + { /* INTEL_LIMIT_I9XX_LVDS */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, @@ -168,15 +186,18 @@ static const intel_limit_t *intel_limit (xf86CrtcPtr crtc) I830Ptr pI830 = I830PTR(pScrn); const intel_limit_t *limit; - if (IS_I9XX(pI830)) - { + if (IS_I9XX(pI830)) { if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; else limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; + } else { + if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) + limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; + else + limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC]; } - else - limit = &intel_limits[INTEL_LIMIT_I8XX]; + return limit; } @@ -342,14 +363,19 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); - if (crtc->rotatedPixmap != NULL) { - Start = (char *)crtc->rotatedPixmap->devPrivate.ptr - - (char *)pI830->FbBase; + if (pI830->front_buffer == NULL) { + /* During startup we may be called as part of monitor detection while + * there is no memory allocation done, so just supply a dummy base + * address. + */ + Start = 0; + } else if (crtc->rotatedData != NULL) { + Start = (char *)crtc->rotatedData - (char *)pI830->FbBase; } else if (I830IsPrimary(pScrn)) { - Start = pI830->FrontBuffer.Start; + Start = pI830->front_buffer->offset; } else { I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - Start = pI8301->FrontBuffer2.Start; + Start = pI8301->front_buffer_2->offset; } if (IS_I965G(pI830)) { @@ -591,6 +617,86 @@ i830_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, return TRUE; } +/** Returns the core display clock speed for i830 - i945 */ +static int +i830_get_core_clock_speed(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + /* Core clock values taken from the published datasheets. + * The 830 may go up to 166 Mhz, which we should check. + */ + if (IS_I945G(pI830)) + return 400000; + else if (IS_I915G(pI830)) + return 333000; + else if (IS_I945GM(pI830) || IS_845G(pI830)) + return 200000; + else if (IS_I915GM(pI830)) { + CARD16 gcfgc = pciReadWord(pI830->PciTag, I915_GCFGC); + + if (gcfgc & I915_LOW_FREQUENCY_ENABLE) + return 133000; + else { + switch (gcfgc & I915_DISPLAY_CLOCK_MASK) { + case I915_DISPLAY_CLOCK_333_MHZ: + return 333000; + default: + case I915_DISPLAY_CLOCK_190_200_MHZ: + return 190000; + } + } + } else if (IS_I865G(pI830)) + return 266000; + else if (IS_I855(pI830)) { + PCITAG bridge = pciTag(0, 0, 0); /* This is always the host bridge */ + CARD16 hpllcc = pciReadWord(bridge, I855_HPLLCC); + + /* Assume that the hardware is in the high speed state. This + * should be the default. + */ + switch (hpllcc & I855_CLOCK_CONTROL_MASK) { + case I855_CLOCK_133_200: + case I855_CLOCK_100_200: + return 200000; + case I855_CLOCK_166_250: + return 250000; + case I855_CLOCK_100_133: + return 133000; + } + } else /* 852, 830 */ + return 133000; + + return 0; /* Silence gcc warning */ +} + +/** + * Return the pipe currently connected to the panel fitter, + * or -1 if the panel fitter is not present or not in use + */ +static int +i830_panel_fitter_pipe (I830Ptr pI830) +{ + CARD32 pfit_control; + + /* i830 doesn't have a panel fitter */ + if (IS_I830(pI830)) + return -1; + + pfit_control = INREG(PFIT_CONTROL); + + /* See if the panel fitter is in use */ + if ((pfit_control & PFIT_ENABLE) == 0) + return -1; + + /* 965 can place panel fitter on either pipe */ + if (IS_I965G(pI830)) + return (pfit_control >> 29) & 0x3; + + /* older chips can only use pipe 1 */ + return 1; +} + /** * Sets up registers for the given mode/adjusted_mode pair. * @@ -707,7 +813,15 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, if (IS_I965G(pI830)) dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); } else { - dpll |= clock.p1 << 16; + if (is_lvds) { + /* map (-1 to 4) to ((1 << 0) to (1 << 5)). */ + dpll |= (1 << (clock.p1 + 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + } else { + if (clock.p1 == 0) + dpll |= PLL_P1_DIVIDE_BY_TWO; + else + dpll |= clock.p1 << DPLL_FPA01_P1_POST_DIV_SHIFT; + } dpll |= clock.p2 << 23; } @@ -749,23 +863,15 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, dspcntr |= DISPPLANE_SEL_PIPE_B; pipeconf = INREG(pipeconf_reg); - if (pipe == 0) + if (pipe == 0 && !IS_I965G(pI830)) { - /* - * The docs say this is needed when the dot clock is > 90% of the - * core speed. Core speeds are indicated by bits in the PCI - * config space, but that's a pain to go read, so we just guess - * based on the hardware age. AGP hardware is assumed to run - * at 133MHz while PCI-E hardware is assumed to run at 200MHz + /* Enable pixel doubling when the dot clock is > 90% of the (display) + * core speed. + * + * XXX: No double-wide on 915GM pipe B. Is that the only reason for the + * pipe == 0 check? */ - int core_clock; - - if (IS_I9XX(pI830)) - core_clock = 200000; - else - core_clock = 133000; - - if (mode->Clock > core_clock * 9 / 10) + if (mode->Clock > i830_get_core_clock_speed(pScrn) * 9 / 10) pipeconf |= PIPEACONF_DOUBLE_WIDE; else pipeconf &= ~PIPEACONF_DOUBLE_WIDE; @@ -786,7 +892,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, } /* Disable the panel fitter if it was on our pipe */ - if (!IS_I830(pI830) && ((INREG(PFIT_CONTROL) >> 29) & 0x3) == pipe) + if (i830_panel_fitter_pipe (pI830) == pipe) OUTREG(PFIT_CONTROL, 0); i830PrintPll("chosen", &clock); @@ -886,25 +992,22 @@ i830_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, } /** - * Creates a locked-in-framebuffer pixmap of the given width and height for - * this CRTC's rotated shadow framebuffer. - * - * The current implementation uses fixed buffers allocated at startup at the - * maximal size. + * Allocates memory for a locked-in-framebuffer shadow of the given + * width and height for this CRTC's rotated shadow framebuffer. */ -static PixmapPtr -i830_crtc_shadow_create(xf86CrtcPtr crtc, int width, int height) + +static void * +i830_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) { ScrnInfoPtr pScrn = crtc->scrn; ScreenPtr pScreen = pScrn->pScreen; I830Ptr pI830 = I830PTR(pScrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; unsigned long rotate_pitch; - PixmapPtr rotate_pixmap; unsigned long rotate_offset; int align = KB(4), size; - rotate_pitch = pI830->displayWidth * pI830->cpp; + rotate_pitch = pScrn->displayWidth * pI830->cpp; size = rotate_pitch * height; #ifdef I830_USE_EXA @@ -944,17 +1047,37 @@ i830_crtc_shadow_create(xf86CrtcPtr crtc, int width, int height) "Couldn't allocate shadow memory for rotated CRTC\n"); return NULL; } - rotate_offset = pI830->FrontBuffer.Start + + rotate_offset = pI830->front_buffer->offset + intel_crtc->rotate_mem_xaa->offset * pI830->cpp; } #endif /* I830_USE_XAA */ + return pI830->FbBase + rotate_offset; +} + +/** + * Creates a pixmap for this CRTC's rotated shadow framebuffer. + */ +static PixmapPtr +i830_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + I830Ptr pI830 = I830PTR(pScrn); + unsigned long rotate_pitch; + PixmapPtr rotate_pixmap; + + if (!data) + data = i830_crtc_shadow_allocate (crtc, width, height); + + rotate_pitch = pScrn->displayWidth * pI830->cpp; + rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen, width, height, pScrn->depth, pScrn->bitsPerPixel, rotate_pitch, - pI830->FbBase + rotate_offset); + data); + if (rotate_pixmap == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't allocate shadow pixmap for rotated CRTC\n"); @@ -963,25 +1086,30 @@ i830_crtc_shadow_create(xf86CrtcPtr crtc, int width, int height) } static void -i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap) +i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) { ScrnInfoPtr pScrn = crtc->scrn; I830Ptr pI830 = I830PTR(pScrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - FreeScratchPixmapHeader(rotate_pixmap); + if (rotate_pixmap) + FreeScratchPixmapHeader(rotate_pixmap); + + if (data) + { #ifdef I830_USE_EXA - if (pI830->useEXA && intel_crtc->rotate_mem_exa != NULL) { - exaOffscreenFree(pScrn->pScreen, intel_crtc->rotate_mem_exa); - intel_crtc->rotate_mem_exa = NULL; - } + if (pI830->useEXA && intel_crtc->rotate_mem_exa != NULL) { + exaOffscreenFree(pScrn->pScreen, intel_crtc->rotate_mem_exa); + intel_crtc->rotate_mem_exa = NULL; + } #endif /* I830_USE_EXA */ #ifdef I830_USE_XAA - if (!pI830->useEXA) { - xf86FreeOffscreenLinear(intel_crtc->rotate_mem_xaa); - intel_crtc->rotate_mem_xaa = NULL; - } + if (!pI830->useEXA) { + xf86FreeOffscreenLinear(intel_crtc->rotate_mem_xaa); + intel_crtc->rotate_mem_xaa = NULL; + } #endif /* I830_USE_XAA */ + } } @@ -1132,6 +1260,113 @@ i830ReleaseLoadDetectPipe(xf86OutputPtr output) } } +/* Returns the clock of the currently programmed mode of the given pipe. */ +static int +i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) +{ + I830Ptr pI830 = I830PTR(pScrn); + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + int pipe = intel_crtc->pipe; + CARD32 dpll = INREG((pipe == 0) ? DPLL_A : DPLL_B); + CARD32 fp; + intel_clock_t clock; + + if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) + fp = INREG((pipe == 0) ? FPA0 : FPB0); + else + fp = INREG((pipe == 0) ? FPA1 : FPB1); + + clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; + clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; + clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; + if (IS_I9XX(pI830)) { + clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + + switch (dpll & DPLL_MODE_MASK) { + case DPLLB_MODE_DAC_SERIAL: + clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; + break; + case DPLLB_MODE_LVDS: + clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unknown DPLL mode %08x in programmed mode\n", + (int)(dpll & DPLL_MODE_MASK)); + return 0; + } + + /* XXX: Handle the 100Mhz refclk */ + i9xx_clock(96000, &clock); + } else { + Bool is_lvds = (pipe == 1) && (INREG(LVDS) & LVDS_PORT_EN); + + if (is_lvds) { + /* Map the bit number set from (1, 6) to (-1, 4). */ + clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> + DPLL_FPA01_P1_POST_DIV_SHIFT) - 2; + clock.p2 = 0; + } else { + if (dpll & PLL_P1_DIVIDE_BY_TWO) { + clock.p1 = 0; + } else { + /* Map the number in the field to (1, 31) */ + clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + } + if (dpll & PLL_P2_DIVIDE_BY_4) + clock.p2 = 1; + else + clock.p2 = 0; + } + + /* XXX: Deal with other refclocks */ + i8xx_clock(48000, &clock); + } + + /* XXX: It would be nice to validate the clocks, but we can't reuse + * i830PllIsValid() because it relies on the xf86_config output + * configuration being accurate, which it isn't necessarily. + */ + if (0) + i830PrintPll("probed", &clock); + + return clock.dot; +} + +/** Returns the currently programmed mode of the given pipe. */ +DisplayModePtr +i830_crtc_mode_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) +{ + I830Ptr pI830 = I830PTR(pScrn); + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + int pipe = intel_crtc->pipe; + DisplayModePtr mode; + int htot = INREG((pipe == 0) ? HTOTAL_A : HTOTAL_B); + int hsync = INREG((pipe == 0) ? HSYNC_A : HSYNC_B); + int vtot = INREG((pipe == 0) ? VTOTAL_A : VTOTAL_B); + int vsync = INREG((pipe == 0) ? VSYNC_A : VSYNC_B); + + mode = xcalloc(1, sizeof(DisplayModeRec)); + if (mode == NULL) + return NULL; + + mode->Clock = i830_crtc_clock_get(pScrn, crtc); + mode->HDisplay = (htot & 0xffff) + 1; + mode->HTotal = ((htot & 0xffff0000) >> 16) + 1; + mode->HSyncStart = (hsync & 0xffff) + 1; + mode->HSyncEnd = ((hsync & 0xffff0000) >> 16) + 1; + mode->VDisplay = (vtot & 0xffff) + 1; + mode->VTotal = ((vtot & 0xffff0000) >> 16) + 1; + mode->VSyncStart = (vsync & 0xffff) + 1; + mode->VSyncEnd = ((vsync & 0xffff0000) >> 16) + 1; + xf86SetModeDefaultName(mode); + xf86SetModeCrtc(mode, 0); + + return mode; +} + static const xf86CrtcFuncsRec i830_crtc_funcs = { .dpms = i830_crtc_dpms, .save = NULL, /* XXX */ @@ -1142,6 +1377,7 @@ static const xf86CrtcFuncsRec i830_crtc_funcs = { .mode_set = i830_crtc_mode_set, .gamma_set = i830_crtc_gamma_set, .shadow_create = i830_crtc_shadow_create, + .shadow_allocate = i830_crtc_shadow_allocate, .shadow_destroy = i830_crtc_shadow_destroy, .destroy = NULL, /* XXX */ }; diff --git a/src/i830_display.h b/src/i830_display.h index dc800553..dbd1ea8e 100644 --- a/src/i830_display.h +++ b/src/i830_display.h @@ -39,3 +39,4 @@ xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output); void i830ReleaseLoadDetectPipe(xf86OutputPtr output); void i830_crtc_init(ScrnInfoPtr pScrn, int pipe); void i830_crtc_load_lut(xf86CrtcPtr crtc); +DisplayModePtr i830_crtc_mode_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc); diff --git a/src/i830_dri.c b/src/i830_dri.c index 70e7e491..f81251a5 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -145,22 +145,22 @@ I830InitDma(ScrnInfoPtr pScrn) memset(&info, 0, sizeof(drmI830Init)); info.func = I830_INIT_DMA; - info.ring_start = ring->mem.Start + pI830->LinearAddr; - info.ring_end = ring->mem.End + pI830->LinearAddr; - info.ring_size = ring->mem.Size; + info.ring_start = ring->mem->offset + pI830->LinearAddr; + info.ring_end = ring->mem->end + pI830->LinearAddr; + info.ring_size = ring->mem->size; info.mmio_offset = (unsigned int)pI830DRI->regs; info.sarea_priv_offset = sizeof(XF86DRISAREARec); - info.front_offset = pI830->FrontBuffer.Start; - info.back_offset = pI830->BackBuffer.Start; - info.depth_offset = pI830->DepthBuffer.Start; + info.front_offset = pI830->front_buffer->offset; + info.back_offset = pI830->back_buffer->offset; + info.depth_offset = pI830->depth_buffer->offset; info.w = pScrn->virtualX; info.h = pScrn->virtualY; - info.pitch = pI830->displayWidth; - info.back_pitch = pI830->displayWidth; - info.depth_pitch = pI830->displayWidth; + info.pitch = pScrn->displayWidth; + info.back_pitch = pScrn->displayWidth; + info.depth_pitch = pScrn->displayWidth; info.cpp = pI830->cpp; if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT, @@ -509,7 +509,7 @@ I830DRIScreenInit(ScreenPtr pScreen) pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL; #if 1 /* Remove this soon - see bug 5714 */ pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr + - pI830->FrontBuffer.Start; + pI830->front_buffer->offset; pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); #else @@ -654,21 +654,18 @@ I830DRIScreenInit(ScreenPtr pScreen) return FALSE; } pI830->drmMinor = version->version_minor; - if (!(pI830->mmModeFlags & I830_KERNEL_TEX)) { -#ifdef XF86DRI_MM - if ((version->version_major > 1) || - ((version->version_minor >= 7) && - (version->version_major == 1))) { - pI830->mmModeFlags |= I830_KERNEL_MM; - } else -#endif - { - pI830->mmModeFlags |= I830_KERNEL_TEX; - } - } else { - xf86DrvMsg(pScreen->myNum, X_INFO, - "Not enabling the DRM memory manager.\n"); - } + if (version->version_minor < 7) { + if (pI830->mmModeFlags & I830_KERNEL_MM) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "DRM version %d.%d older than required 1.7 for " + "DRM memory manager. Disabling.\n", + version->version_major, version->version_minor); + pI830->mmModeFlags &= ~I830_KERNEL_MM; + + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; + } + } drmFreeVersion(version); } } @@ -829,8 +826,8 @@ I830DRIDoMappings(ScreenPtr pScreen) (int)pI830DRI->regs); if (drmAddMap(pI830->drmSubFD, - (drm_handle_t)pI830->LpRing->mem.Start + pI830->LinearAddr, - pI830->LpRing->mem.Size, DRM_AGP, 0, + (drm_handle_t)pI830->LpRing->mem->offset + pI830->LinearAddr, + pI830->LpRing->mem->size, DRM_AGP, 0, (drmAddress) &pI830->ring_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); @@ -1325,10 +1322,10 @@ I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) OUT_RING(br13); OUT_RING((pbox->y1 << 16) | pbox->x1); OUT_RING((pbox->y2 << 16) | pbox->x2); - OUT_RING(pI830->BackBuffer.Start); + OUT_RING(pI830->back_buffer->offset); OUT_RING((pbox->y1 << 16) | pbox->x1); OUT_RING(br13 & 0xffff); - OUT_RING(pI830->FrontBuffer.Start); + OUT_RING(pI830->front_buffer->offset); ADVANCE_LP_RING(); } } @@ -1360,10 +1357,10 @@ I830EnablePageFlip(ScreenPtr pScreen) OUT_RING(br13); OUT_RING(0); OUT_RING((pScrn->virtualY << 16) | pScrn->virtualX); - OUT_RING(pI830->BackBuffer.Start); + OUT_RING(pI830->back_buffer->offset); OUT_RING(0); OUT_RING(br13 & 0xffff); - OUT_RING(pI830->FrontBuffer.Start); + OUT_RING(pI830->front_buffer->offset); ADVANCE_LP_RING(); pSAREAPriv->pf_active = 1; @@ -1448,11 +1445,12 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->depth_tiled = pI830->depth_tiled; sarea->rotated_tiled = FALSE; - sarea->front_offset = pI830->FrontBuffer.Start; - /* Don't use FrontBuffer.Size here as it includes the pixmap cache area + sarea->front_offset = pI830->front_buffer->offset; + /* Don't use front_buffer->size here as it includes the pixmap cache area * Instead, calculate the entire framebuffer. */ - sarea->front_size = pI830->displayWidth * pScrn->virtualY * pI830->cpp; + sarea->front_size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * + pI830->cpp); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] init sarea width,height = %d x %d (pitch %d)\n", @@ -1460,12 +1458,17 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) 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; - sarea->tex_offset = pI830->TexMem.Start; - sarea->tex_size = pI830->TexMem.Size; + sarea->back_offset = pI830->back_buffer->offset; + sarea->back_size = pI830->back_buffer->size; + sarea->depth_offset = pI830->depth_buffer->offset; + sarea->depth_size = pI830->depth_buffer->size; + if (pI830->textures != NULL) { + sarea->tex_offset = pI830->textures->offset; + sarea->tex_size = pI830->textures->size; + } else { + sarea->tex_offset = 0; + sarea->tex_size = 0; + } sarea->log_tex_granularity = pI830->TexGranularity; sarea->pitch = pScrn->displayWidth; sarea->virtualX = pScrn->virtualX; @@ -1477,7 +1480,7 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->rotation = 0; sarea->rotated_offset = -1; sarea->rotated_size = 0; - sarea->rotated_pitch = pI830->displayWidth; + sarea->rotated_pitch = pScrn->displayWidth; success = I830DRIMapScreenRegions(pScrn, sarea); diff --git a/src/i830_driver.c b/src/i830_driver.c index 701abd70..e0887260 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -536,7 +536,7 @@ I830MapMem(ScrnInfoPtr pScrn) return FALSE; if (I830IsPrimary(pScrn)) - pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem.Start; + pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem->offset; return TRUE; } @@ -754,18 +754,6 @@ PreInitCleanup(ScrnInfoPtr pScrn) if (I830IsPrimary(pScrn)) { if (pI830->entityPrivate) pI830->entityPrivate->pScrn_1 = NULL; - if (pI830->LpRing) - xfree(pI830->LpRing); - pI830->LpRing = NULL; - if (pI830->OverlayMem) - xfree(pI830->OverlayMem); - pI830->OverlayMem = NULL; - 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; @@ -817,27 +805,13 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) pI830->writeControl(pI830, GRX, 0x18, gr18); } -#ifdef XF86DRI -static void -I830ReduceMMSize(ScrnInfoPtr pScrn, unsigned long newSize, - const char *reason) -{ - I830Ptr pI830 = I830PTR(pScrn); - - newSize = ROUND_DOWN_TO(newSize, GTT_PAGE_SIZE); - if (newSize / GTT_PAGE_SIZE > I830_MM_MINPAGES) { - pI830->mmSize = newSize / 1024; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "DRM memory manager aperture size is reduced to %d kiB\n" - "\t%s\n", pI830->mmSize, reason); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "DRM memory manager will be disabled\n\t%s\n", reason); - pI830->mmSize = 0; - } -} -#endif - +/** + * This is called per zaphod head (so usually just once) to do initialization + * before the Screen is created. + * + * This code generally covers probing, module loading, option handling + * card mapping, and RandR setup. + */ static Bool I830PreInit(ScrnInfoPtr pScrn, int flags) { @@ -848,18 +822,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; I830EntPtr pI830Ent = NULL; - int mem; int flags24; int i; char *s; pointer pVBEModule = NULL; - Bool enable; const char *chipname; + Bool enable; int num_pipe; int max_width, max_height; -#ifdef XF86DRI - unsigned long savedMMSize; -#endif if (pScrn->numEntities != 1) return FALSE; @@ -898,7 +868,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->SaveGeneration = -1; pI830->pEnt = pEnt; - pI830->displayWidth = 640; /* default it */ + pScrn->displayWidth = 640; /* default it */ if (pI830->pEnt->location.type != BUS_PCI) return FALSE; @@ -1192,41 +1162,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", num_pipe, num_pipe > 1 ? "s" : ""); - /* - * Get the pre-allocated (stolen) memory size. - */ - pI830->StolenMemory.Size = I830DetectMemory(pScrn); - pI830->StolenMemory.Start = 0; - pI830->StolenMemory.End = pI830->StolenMemory.Size; - - /* Find the maximum amount of agpgart memory available. */ - if (I830IsPrimary(pScrn)) { - mem = I830CheckAvailableMemory(pScrn); - pI830->StolenOnly = FALSE; - } else { - /* videoRam isn't used on the second head, but faked */ - mem = pI830->entityPrivate->pScrn_1->videoRam; - pI830->StolenOnly = TRUE; - } - - if (mem <= 0) { - if (pI830->StolenMemory.Size <= 0) { - /* Shouldn't happen. */ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "/dev/agpgart is either not available, or no memory " - "is available\nfor allocation, " - "and no pre-allocated memory is available.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "/dev/agpgart is either not available, or no memory " - "is available\nfor allocation. " - "Using pre-allocated memory only.\n"); - mem = 0; - pI830->StolenOnly = TRUE; - } - if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { pI830->noAccel = TRUE; } @@ -1290,8 +1225,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) if (!pI830->directRenderingDisabled) { Bool tmp = FALSE; - if (IS_I965G(pI830)) - pI830->mmModeFlags |= I830_KERNEL_TEX; + pI830->mmModeFlags |= I830_KERNEL_TEX; +#ifdef XF86DRI_MM + if (!IS_I965G(pI830)) + pI830->mmModeFlags |= I830_KERNEL_MM; +#endif from = X_PROBED; if (xf86GetOptValBool(pI830->Options, @@ -1303,14 +1241,12 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->mmModeFlags &= ~I830_KERNEL_TEX; } } - if (from == X_CONFIG || - (pI830->mmModeFlags & I830_KERNEL_TEX)) { - xf86DrvMsg(pScrn->scrnIndex, from, - "Will %stry to allocate texture pool " - "for old Mesa 3D driver.\n", - (pI830->mmModeFlags & I830_KERNEL_TEX) ? - "" : "not "); - } + xf86DrvMsg(pScrn->scrnIndex, from, + "Will %stry to allocate texture pool " + "for old Mesa 3D driver.\n", + (pI830->mmModeFlags & I830_KERNEL_TEX) ? + "" : "not "); + pI830->mmSize = I830_MM_MAXSIZE; from = X_INFO; if (xf86GetOptValInteger(pI830->Options, OPTION_INTELMMSIZE, @@ -1329,18 +1265,15 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->LinearAlloc = 0; if (xf86GetOptValULong(pI830->Options, OPTION_LINEARALLOC, &(pI830->LinearAlloc))) { - if (pI830->LinearAlloc > 0) - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %luKbytes of memory\n", - pI830->LinearAlloc); - else + if (pI830->LinearAlloc < 0) pI830->LinearAlloc = 0; } I830PreInitDDC(pScrn); - I830SetupOutputs(pScrn); for (i = 0; i < num_pipe; i++) { i830_crtc_init(pScrn, i); } + I830SetupOutputs(pScrn); SaveHWState(pScrn); /* Do an initial detection of the outputs while none are configured on yet. @@ -1363,8 +1296,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } RestoreHWState(pScrn); - pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; - /* XXX This should go away, replaced by xf86Crtc.c support for it */ pI830->rotation = RR_Rotate_0; @@ -1389,77 +1320,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } else pI830->checkDevices = FALSE; - /* - * The "VideoRam" config file parameter specifies the maximum amount of - * memory that will be used/allocated. When not present, we allow the - * driver to allocate as much memory as it wishes to satisfy its - * allocations, but if agpgart support isn't available (StolenOnly == TRUE), - * it gets limited to the amount of pre-allocated ("stolen") memory. - */ - if (!pI830->pEnt->device->videoRam) { - from = X_DEFAULT; - pScrn->videoRam = pI830->FbMapSize / KB(1); - } else { - from = X_CONFIG; - pScrn->videoRam = pI830->pEnt->device->videoRam; - } - - /* Make sure it's on a page boundary */ - if (pScrn->videoRam & 3) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB " - "(page aligned - was %d KB)\n", - pScrn->videoRam & ~3, pScrn->videoRam); - pScrn->videoRam &= ~3; - } - - DPRINTF(PFX, - "Available memory: %dk\n" - "Requested memory: %dk\n", mem, pScrn->videoRam); - - - if (mem + (pI830->StolenMemory.Size / 1024) < pScrn->videoRam) { - pScrn->videoRam = mem + (pI830->StolenMemory.Size / 1024); - from = X_PROBED; - if (mem + (pI830->StolenMemory.Size / 1024) < - pI830->pEnt->device->videoRam) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRAM reduced to %d kByte " - "(limited to available sysmem)\n", pScrn->videoRam); - } - } - - if (pScrn->videoRam > pI830->FbMapSize / 1024) { - pScrn->videoRam = pI830->FbMapSize / 1024; - if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRam reduced to %d kByte (limited to aperture size)\n", - pScrn->videoRam); - } - - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Pre-allocated VideoRam: %ld kByte\n", - pI830->StolenMemory.Size / 1024); - xf86DrvMsg(pScrn->scrnIndex, from, "Potential VideoRam: %d kByte\n", - pScrn->videoRam); - - pI830->TotalVideoRam = KB(pScrn->videoRam); - - /* - * If the requested videoRam amount is less than the stolen memory size, - * reduce the stolen memory size accordingly. - */ - if (pI830->StolenMemory.Size > pI830->TotalVideoRam) { - pI830->StolenMemory.Size = pI830->TotalVideoRam; - pI830->StolenMemory.End = pI830->TotalVideoRam; - } - - if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, - &(pI830->CacheLines))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", - pI830->CacheLines); - } else { - pI830->CacheLines = -1; - } + pI830->stolen_size = I830DetectMemory(pScrn); pI830->XvDisabled = !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); @@ -1505,24 +1366,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } } - /* Alloc our pointers for the primary head */ - if (I830IsPrimary(pScrn)) { - pI830->LpRing = xalloc(sizeof(I830RingBuffer)); - pI830->OverlayMem = xalloc(sizeof(I830MemRange)); - pI830->overlayOn = xalloc(sizeof(Bool)); - pI830->used3D = xalloc(sizeof(int)); - if (!pI830->LpRing || - !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not allocate primary data structures.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - *pI830->overlayOn = FALSE; - if (pI830->entityPrivate) - pI830->entityPrivate->XvInUse = -1; - } - /* Check if the HW cursor needs physical address. */ if (IS_MOBILE(pI830) || IS_I9XX(pI830)) pI830->CursorNeedsPhysical = TRUE; @@ -1532,9 +1375,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) if (IS_I965G(pI830)) pI830->CursorNeedsPhysical = FALSE; - /* Force ring buffer to be in low memory for all chipsets */ - pI830->NeedRingBufferLow = TRUE; - /* * XXX If we knew the pre-initialised GTT format for certain, we could * probably figure out the physical address even in the StolenOnly case. @@ -1553,21 +1393,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->SWCursor = TRUE; } - /* - * Reduce the maximum videoram available for video modes by the ring buffer, - * minimum scratch space and HW cursor amounts. - */ - if (!pI830->SWCursor) { - pScrn->videoRam -= (HWCURSOR_SIZE / 1024); - pScrn->videoRam -= (HWCURSOR_SIZE_ARGB / 1024); - } - if (!pI830->XvDisabled) - pScrn->videoRam -= (OVERLAY_SIZE / 1024); - if (!pI830->noAccel) { - pScrn->videoRam -= (PRIMARY_RINGBUFFER_SIZE / 1024); - pScrn->videoRam -= (MIN_SCRATCH_BUFFER_SIZE / 1024); - } - if (!xf86RandR12PreInit (pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n"); @@ -1582,187 +1407,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } pScrn->currentMode = pScrn->modes; - pI830->disableTiling = FALSE; - - /* - * If DRI is potentially usable, check if there is enough memory available - * for it, and if there's also enough to allow tiling to be enabled. - */ - -#if defined(XF86DRI) - if (!I830CheckDRIAvailable(pScrn)) { - pI830->directRenderingDisabled = TRUE; - pI830->mmSize = 0; - } else if (pScrn->videoRam > pI830->FbMapSize / 1024 - pI830->mmSize) { - I830ReduceMMSize(pScrn, pI830->FbMapSize - KB(pScrn->videoRam), - "to make room for video memory"); - } - - if (I830IsPrimary(pScrn) && !pI830->directRenderingDisabled) { - int savedDisplayWidth = pScrn->displayWidth; - int memNeeded = 0; - Bool tiled = FALSE; - -#ifdef I830_XV - /* - * Set this so that the overlay allocation is factored in when - * appropriate. - */ - pI830->XvEnabled = !pI830->XvDisabled; -#endif - - if (IS_I965G(pI830)) { - int tile_pixels = 512 / pI830->cpp; - pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) & - ~(tile_pixels - 1); - tiled = TRUE; - } else { - /* Good pitches to allow tiling. Don't care about pitches < 1024. */ - static const int pitches[] = { - KB(1), - KB(2), - KB(4), - KB(8), - 0 - }; - - for (i = 0; pitches[i] != 0; i++) { - if (pitches[i] >= pScrn->displayWidth) { - pScrn->displayWidth = pitches[i]; - tiled = TRUE; - break; - } - } - } - - /* - * If the displayWidth is a tilable pitch, test if there's enough - * memory available to enable tiling. - */ - savedMMSize = pI830->mmSize; - if (tiled) { - retry_dryrun: - I830ResetAllocations(pScrn, 0); - if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) && - I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN)) { - memNeeded = I830GetExcessMemoryAllocations(pScrn); - if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { - if (memNeeded > 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%d kBytes additional video memory is " - "required to\n\tenable tiling mode for DRI.\n", - (memNeeded + 1023) / 1024); - } - if (pI830->MemoryAperture.Size < 0) { - if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { - I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, - "to make room in AGP aperture for tiling."); - goto retry_dryrun; - } - /* XXX */ - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Allocation with DRI tiling enabled would " - "exceed the\n" - "\tmemory aperture size (%ld kB) by %ld kB.\n" - "\tReduce VideoRam amount to avoid this!\n", - pI830->FbMapSize / 1024, - -pI830->MemoryAperture.Size / 1024); - } - pScrn->displayWidth = savedDisplayWidth; - pI830->allowPageFlip = FALSE; - } else if (pScrn->displayWidth != savedDisplayWidth) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Increasing the scanline pitch to allow tiling mode " - "(%d -> %d).\n", - savedDisplayWidth, pScrn->displayWidth); - } - } else { - memNeeded = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Unexpected dry run allocation failure (1).\n"); - } - } - if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { - /* - * Tiling can't be enabled. Check if there's enough memory for DRI - * without tiling. - */ - pI830->mmSize = savedMMSize; - pI830->disableTiling = TRUE; - retry_dryrun2: - I830ResetAllocations(pScrn, 0); - if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) && - I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_NO_TILING)) { - memNeeded = I830GetExcessMemoryAllocations(pScrn); - if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { - if (memNeeded > 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%d kBytes additional video memory is required " - "to enable DRI.\n", - (memNeeded + 1023) / 1024); - } - if (pI830->MemoryAperture.Size < 0) { - if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { - I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, - "to save AGP aperture space for video memory."); - goto retry_dryrun2; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Allocation with DRI enabled would " - "exceed the\n" - "\tmemory aperture size (%ld kB) by %ld kB.\n" - "\tReduce VideoRam amount to avoid this!\n", - pI830->FbMapSize / 1024, - -pI830->MemoryAperture.Size / 1024); - } - pI830->mmSize = 0; - pI830->directRenderingDisabled = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DRI.\n"); - } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Unexpected dry run allocation failure (2).\n"); - } - } - } else -#endif - pI830->disableTiling = TRUE; /* no DRI - so disableTiling */ - - if (pI830->pEnt->device->videoRam == 0) { - int default_videoram; - - /* Now that we've sized the allocations, reduce our default VideoRam - * allocation from the aperture size to just what we need to cover our - * allocations. Only, put in some slop for alignment and such. - */ - default_videoram = pI830->StolenPool.Total.Size + pI830->allocatedMemory; - default_videoram += KB(512); /* slop */ - /* align to 1MB increments */ - default_videoram = (default_videoram + MB(1) - 1) / MB(1) * MB(1); - - if (default_videoram < KB(pScrn->videoRam)) { - pScrn->videoRam = default_videoram / KB(1); - pI830->TotalVideoRam = KB(pScrn->videoRam); - } - } - xf86DrvMsg(pScrn->scrnIndex, - pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, - "VideoRam: %d KB\n", pScrn->videoRam); - - if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Cannot support DRI with frame buffer width > 2048.\n"); - pI830->disableTiling = TRUE; - pI830->directRenderingDisabled = TRUE; - } - if (!IS_I965G(pI830) && pScrn->virtualY > 2048) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support > 2048 vertical lines. disabling acceleration.\n"); pI830->noAccel = TRUE; } - pI830->displayWidth = pScrn->displayWidth; - /* Don't need MMIO access anymore. */ if (pI830->swfSaved) { OUTREG(SWF0, pI830->saveSWF0); @@ -1939,18 +1588,18 @@ SetFenceRegs(ScrnInfoPtr pScrn) if (IS_I965G(pI830)) { for (i = 0; i < FENCE_NEW_NR; i++) { - OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]); - OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]); + OUTREG(FENCE_NEW + i * 8, pI830->fence[i]); + OUTREG(FENCE_NEW + 4 + i * 8, pI830->fence[i+FENCE_NEW_NR]); if (I810_DEBUG & DEBUG_VERBOSE_VGA) { - ErrorF("Fence Start Register : %x\n", pI830->ModeReg.Fence[i]); - ErrorF("Fence End Register : %x\n", pI830->ModeReg.Fence[i+FENCE_NEW_NR]); + ErrorF("Fence Start Register : %x\n", pI830->fence[i]); + ErrorF("Fence End Register : %x\n", pI830->fence[i+FENCE_NEW_NR]); } } } else { for (i = 0; i < FENCE_NR; i++) { - OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]); + OUTREG(FENCE + i * 4, pI830->fence[i]); if (I810_DEBUG & DEBUG_VERBOSE_VGA) - ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]); + ErrorF("Fence Register : %x\n", pI830->fence[i]); } } } @@ -1975,25 +1624,22 @@ SetRingRegs(ScrnInfoPtr pScrn) OUTREG(LP_RING + RING_TAIL, 0); OUTREG(LP_RING + RING_HEAD, 0); - if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != - pI830->LpRing->mem.Start) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "I830SetRingRegs: Ring buffer start (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); - } + assert((pI830->LpRing->mem->offset & I830_RING_START_MASK) == + pI830->LpRing->mem->offset); + /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; + itemp = pI830->LpRing->mem->offset; OUTREG(LP_RING + RING_START, itemp); - if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != - pI830->LpRing->mem.Size - 4096) { + if (((pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES) != + pI830->LpRing->mem->size - 4096) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Size - 4096, + "mask (%x)\n", pI830->LpRing->mem->size - 4096, I830_RING_NR_PAGES); } /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; + itemp = (pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES; itemp |= (RING_NO_REPORT | RING_VALID); OUTREG(LP_RING + RING_LEN, itemp); I830RefreshRing(pScrn); @@ -2251,13 +1897,12 @@ static void InitRegisterRec(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - I830RegPtr i830Reg = &pI830->ModeReg; int i; if (!I830IsPrimary(pScrn)) return; for (i = 0; i < 8; i++) - i830Reg->Fence[i] = 0; + pI830->fence[i] = 0; } static void @@ -2366,14 +2011,12 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn) } #endif - ctx_addr = pI830->ContextMem.Start; - /* Align to a 2k boundry */ - ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048; - + ctx_addr = pI830->logical_context->offset; + assert((pI830->logical_context->offset & 2047) == 0); { BEGIN_LP_RING(2); OUT_RING(MI_SET_CONTEXT); - OUT_RING(ctx_addr | + OUT_RING(pI830->logical_context->offset | CTXT_NO_RESTORE | CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE); ADVANCE_LP_RING(); @@ -2473,15 +2116,263 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) I830Ptr pI830; VisualPtr visual; I830Ptr pI8301 = NULL; + unsigned long sys_mem; + int i; + Bool allocation_done = FALSE; + MessageType from; #ifdef XF86DRI Bool driDisabled; + unsigned long savedMMSize; #endif pScrn = xf86Screens[pScreen->myNum]; pI830 = I830PTR(pScrn); hwp = VGAHWPTR(pScrn); - pScrn->displayWidth = pI830->displayWidth; + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + /* + * The "VideoRam" config file parameter specifies the maximum amount of + * memory that will be used/allocated. When not present, we allow the + * driver to allocate as much memory as it wishes to satisfy its + * allocations, but if agpgart support isn't available, it gets limited + * to the amount of pre-allocated ("stolen") memory. + * + * Note that in using this value for allocator initialization, we're + * limiting aperture allocation to the VideoRam option, rather than limiting + * actual memory allocation, so alignment and things will cause less than + * VideoRam to be actually used. + */ + if (pI830->pEnt->device->videoRam == 0) { + from = X_DEFAULT; + pScrn->videoRam = pI830->FbMapSize / KB(1); + } else { + from = X_CONFIG; + pScrn->videoRam = pI830->pEnt->device->videoRam; + } + + /* Limit videoRam to how much we might be able to allocate from AGP */ + sys_mem = I830CheckAvailableMemory(pScrn); + if (sys_mem == -1) { + if (pScrn->videoRam > pI830->stolen_size / KB(1)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "/dev/agpgart is either not available, or no memory " + "is available\nfor allocation. " + "Using pre-allocated memory only.\n"); + pScrn->videoRam = pI830->stolen_size / KB(1); + } + pI830->StolenOnly = TRUE; + } else { + if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) { + pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024); + from = X_PROBED; + if (sys_mem + (pI830->stolen_size / 1024) < + pI830->pEnt->device->videoRam) + { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRAM reduced to %d kByte " + "(limited to available sysmem)\n", pScrn->videoRam); + } + } + } + + /* Limit video RAM to the actual aperture size */ + if (pScrn->videoRam > pI830->FbMapSize / 1024) { + pScrn->videoRam = pI830->FbMapSize / 1024; + if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRam reduced to %d kByte (limited to aperture " + "size)\n", + pScrn->videoRam); + } + } + + /* Make sure it's on a page boundary */ + if (pScrn->videoRam & 3) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB " + "(page aligned - was %d KB)\n", + pScrn->videoRam & ~3, pScrn->videoRam); + pScrn->videoRam &= ~3; + } + + /* Set up our video memory allocator for the chosen videoRam */ + if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't initialize video memory allocator\n"); + PreInitCleanup(pScrn); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, + pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, + "VideoRam: %d KB\n", pScrn->videoRam); + + if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, + &(pI830->CacheLines))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", + pI830->CacheLines); + } else { + pI830->CacheLines = -1; + } + + pI830->disableTiling = FALSE; + + if (I830IsPrimary(pScrn)) { + /* Alloc our pointers for the primary head */ + if (!pI830->LpRing) + pI830->LpRing = xcalloc(1, sizeof(I830RingBuffer)); + if (!pI830->overlayOn) + pI830->overlayOn = xalloc(sizeof(Bool)); + if (!pI830->used3D) + pI830->used3D = xalloc(sizeof(int)); + if (!pI830->LpRing || !pI830->overlayOn || !pI830->used3D) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not allocate primary data structures.\n"); + return FALSE; + } + *pI830->overlayOn = FALSE; + if (pI830->entityPrivate) + pI830->entityPrivate->XvInUse = -1; + } else { + /* Make our second head point to the first heads structures */ + pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pI830->LpRing = pI8301->LpRing; + pI830->overlay_regs = pI8301->overlay_regs; + pI830->overlayOn = pI8301->overlayOn; + pI830->used3D = pI8301->used3D; + } + +#if defined(XF86DRI) + /* + * If DRI is potentially usable, check if there is enough memory available + * for it, and if there's also enough to allow tiling to be enabled. + */ + + if (!I830CheckDRIAvailable(pScrn)) { + pI830->directRenderingDisabled = TRUE; + pI830->mmSize = 0; + } + + if (!pI830->directRenderingDisabled) { + int savedDisplayWidth = pScrn->displayWidth; + Bool tiled = FALSE; + +#ifdef I830_XV + /* + * Set this so that the overlay allocation is factored in when + * appropriate. + */ + pI830->XvEnabled = !pI830->XvDisabled; +#endif + + if (IS_I965G(pI830)) { + int tile_pixels = 512 / pI830->cpp; + pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) & + ~(tile_pixels - 1); + tiled = TRUE; + } else { + /* Good pitches to allow tiling. Don't care about pitches < 1024 + * pixels. + */ + static const int pitches[] = { + 1024, + 2048, + 4096, + 8192, + 0 + }; + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= pScrn->displayWidth) { + pScrn->displayWidth = pitches[i]; + tiled = TRUE; + break; + } + } + } + + /* Attempt several rounds of allocation to get 2d and 3d memory to fit: + * + * 0: tiled, large memory manager + * 1: tiled, small memory manager + * 2: untiled, large + * 3: untiled, small + */ + + pI830->disableTiling = FALSE; + savedMMSize = pI830->mmSize; + for (i = 0; i < 4; i++) { + if (!tiled && i < 2) + continue; + + if (i >= 2) { + /* For further allocations, disable tiling */ + pI830->disableTiling = TRUE; + pScrn->displayWidth = savedDisplayWidth; + pI830->allowPageFlip = FALSE; + } + + if (i & 1) { + /* For this allocation, switch to a smaller DRI memory manager + * size. + */ + pI830->mmSize = I830_MM_MINPAGES * GTT_PAGE_SIZE; + } else { + pI830->mmSize = savedMMSize; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Attempting memory allocation with %s buffers and \n" + "\t %s DRI memory manager reservation:\n", + (i & 2) ? "untiled" : "tiled", + (i & 1) ? "small" : "large"); + + if (i830_allocate_2d_memory(pScrn) && + i830_allocate_3d_memory(pScrn)) + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Success.\n"); + if (pScrn->displayWidth != savedDisplayWidth) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Increasing the scanline pitch to allow tiling mode " + "(%d -> %d).\n", + savedDisplayWidth, pScrn->displayWidth); + } + allocation_done = TRUE; + break; + } + + i830_reset_allocations(pScrn); + } + + if (i == 4) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Not enough video memory. Disabling DRI.\n"); + pI830->mmSize = 0; + pI830->directRenderingDisabled = TRUE; + } + } else +#endif + pI830->disableTiling = TRUE; /* no DRI - so disableTiling */ + + if (!allocation_done) { + if (!i830_allocate_2d_memory(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate video memory\n"); + return FALSE; + } + allocation_done = TRUE; + } + + i830_describe_allocations(pScrn, 1, ""); + + if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Cannot support DRI with frame buffer width > 2048.\n"); + pI830->disableTiling = TRUE; + pI830->directRenderingDisabled = TRUE; + } + + pScrn->displayWidth = pScrn->displayWidth; #ifdef HAS_MTRR_SUPPORT { @@ -2526,36 +2417,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->starting = TRUE; - /* Alloc our pointers for the primary head */ - if (I830IsPrimary(pScrn)) { - if (!pI830->LpRing) - pI830->LpRing = xalloc(sizeof(I830RingBuffer)); - if (!pI830->OverlayMem) - 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->OverlayMem || !pI830->overlayOn || !pI830->used3D) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not allocate primary data structures.\n"); - return FALSE; - } - *pI830->overlayOn = FALSE; - if (pI830->entityPrivate) - pI830->entityPrivate->XvInUse = -1; - } - - /* Make our second head point to the first heads structures */ - if (!I830IsPrimary(pScrn)) { - pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - pI830->LpRing = pI8301->LpRing; - pI830->OverlayMem = pI8301->OverlayMem; - pI830->overlayOn = pI8301->overlayOn; - pI830->used3D = pI8301->used3D; - } - miClearVisualTypes(); if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), @@ -2583,15 +2444,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = FALSE; #endif - if (I830IsPrimary(pScrn)) { - I830ResetAllocations(pScrn, 0); - - if (!I830Allocate2DMemory(pScrn, ALLOC_INITIAL)) - return FALSE; - } - if (!pI830->noAccel) { - if (pI830->LpRing->mem.Size == 0) { + if (pI830->LpRing->mem->size == 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling acceleration because the ring buffer " "allocation failed.\n"); @@ -2606,7 +2460,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) "needs 2D acceleration.\n"); pI830->XvEnabled = FALSE; } - if (pI830->OverlayMem->Physical == 0) { + if (!IS_I9XX(pI830) && pI830->overlay_regs == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling Xv because the overlay register buffer " "allocation failed.\n"); @@ -2634,6 +2488,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DRI is disabled because it " "needs HW cursor, 2D accel and AGPGART.\n"); pI830->directRenderingEnabled = FALSE; + i830_free_3d_memory(pScrn); } } @@ -2642,39 +2497,17 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (pI830->directRenderingEnabled) pI830->directRenderingEnabled = I830DRIScreenInit(pScreen); - if (pI830->directRenderingEnabled) { - pI830->directRenderingEnabled = - I830Allocate3DMemory(pScrn, - pI830->disableTiling ? ALLOC_NO_TILING : 0); - if (!pI830->directRenderingEnabled) - I830DRICloseScreen(pScreen); + if (!pI830->directRenderingEnabled) { + i830_free_3d_memory(pScrn); } #else pI830->directRenderingEnabled = FALSE; #endif - /* - * After the 3D allocations have been done, see if there's any free space - * that can be added to the framebuffer allocation. - */ - if (I830IsPrimary(pScrn)) { - I830Allocate2DMemory(pScrn, 0); - - DPRINTF(PFX, "assert(if(!I830DoPoolAllocation(pScrn, pI830->StolenPool)))\n"); - if (!I830DoPoolAllocation(pScrn, &(pI830->StolenPool))) - return FALSE; - - DPRINTF(PFX, "assert( if(!I830FixupOffsets(pScrn)) )\n"); - if (!I830FixupOffsets(pScrn)) - return FALSE; - } - #ifdef XF86DRI - if (pI830->directRenderingEnabled) { - I830SetupMemoryTiling(pScrn); + if (pI830->directRenderingEnabled) pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); - } #endif DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); @@ -2684,9 +2517,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->memPhysBase = (unsigned long)pI830->FbBase; if (I830IsPrimary(pScrn)) { - pScrn->fbOffset = pI830->FrontBuffer.Start; + pScrn->fbOffset = pI830->front_buffer->offset; } else { - pScrn->fbOffset = pI8301->FrontBuffer2.Start; + pScrn->fbOffset = pI8301->front_buffer_2->offset; } pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth; @@ -2700,8 +2533,30 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n"); - if (!I830EnterVT(scrnIndex, 0)) - return FALSE; + if (!pI830->useEXA) { + if (I830IsPrimary(pScrn)) { + if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to init memory manager\n"); + } + + if (pI830->LinearAlloc && + xf86InitFBManagerLinear(pScreen, + pI830->xaa_linear->offset / pI830->cpp, + pI830->xaa_linear->size / pI830->cpp)) + { + xf86DrvMsg(scrnIndex, X_INFO, + "Using %ld bytes of offscreen memory for linear " + "(offset=0x%lx)\n", pI830->xaa_linear->size, + pI830->xaa_linear->offset); + } + } else { + if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to init memory manager\n"); + } + } + } if (pScrn->virtualX > pScrn->displayWidth) pScrn->displayWidth = pScrn->virtualX; @@ -2732,34 +2587,10 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86SetBlackWhitePixels(pScreen); - I830DGAInit(pScreen); + xf86DiDGAInit (pScreen, pI830->LinearAddr + pScrn->fbOffset); DPRINTF(PFX, "assert( if(!I830InitFBManager(pScreen, &(pI830->FbMemBox))) )\n"); - if (!pI830->useEXA) { - if (I830IsPrimary(pScrn)) { - if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to init memory manager\n"); - } - - 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 (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to init memory manager\n"); - } - } - } if (!pI830->noAccel) { if (!I830AccelInit(pScreen)) { @@ -2768,6 +2599,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } + if (!I830EnterVT(scrnIndex, 0)) + return FALSE; + miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); @@ -2882,27 +2716,24 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->suspended = FALSE; #ifdef XF86DRI_MM - if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) { - unsigned long aperEnd = ROUND_DOWN_TO(pI830->FbMapSize, GTT_PAGE_SIZE) - / GTT_PAGE_SIZE; - unsigned long aperStart = ROUND_TO(pI830->FbMapSize - KB(pI830->mmSize), GTT_PAGE_SIZE) - / GTT_PAGE_SIZE; - - if (aperEnd < aperStart || aperEnd - aperStart < I830_MM_MINPAGES) { + if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) + { + if (pI830->memory_manager == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Too little AGP aperture space for DRM memory manager.\n" - "\tPlease increase AGP aperture size from BIOS configuration screen\n" - "\tor decrease the amount of video RAM using option \"VideoRam\".\n" + "\tPlease increase AGP aperture size from BIOS configuration screen.\n" "\tDisabling DRI.\n"); pI830->directRenderingOpen = FALSE; I830DRICloseScreen(pScreen); pI830->directRenderingEnabled = FALSE; } else { #ifndef XSERVER_LIBDRM_MM - if (I830DrmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, + if (I830DrmMMInit(pI830->drmSubFD, pI830->memory_manager->offset, + pI830->memory_manager->size, DRM_BO_MEM_TT)) { #else - if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, + if (drmMMInit(pI830->drmSubFD, pI830->memory_manager->offset, + pI830->memory_manager->size, DRM_BO_MEM_TT)) { #endif xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -2911,12 +2742,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->directRenderingOpen = FALSE; I830DRICloseScreen(pScreen); pI830->directRenderingEnabled = FALSE; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Initialized DRM memory manager, %ld AGP pages\n" - "\tat AGP offset 0x%lx\n", - aperEnd - aperStart, - aperStart); } } } @@ -2973,7 +2798,7 @@ I830LeaveVT(int scrnIndex, int flags) if (!I830IsPrimary(pScrn)) { I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - if (!pI8301->GttBound) { + if (!pI8301->gtt_acquired) { return; } } @@ -3007,7 +2832,7 @@ I830LeaveVT(int scrnIndex, int flags) i830DumpRegs (pScrn); if (I830IsPrimary(pScrn)) - I830UnbindAGPMemory(pScrn); + i830_unbind_all_memory(pScrn); if (pI830->AccelInfoRec) pI830->AccelInfoRec->NeedToSync = FALSE; } @@ -3043,7 +2868,7 @@ I830EnterVT(int scrnIndex, int flags) #endif if (I830IsPrimary(pScrn)) - if (!I830BindAGPMemory(pScrn)) + if (!i830_bind_all_memory(pScrn)) return FALSE; if (i830_check_error_state(pScrn)) { @@ -3228,8 +3053,6 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) xfree(pI830->LpRing); pI830->LpRing = NULL; - xfree(pI830->OverlayMem); - pI830->OverlayMem = NULL; xfree(pI830->overlayOn); pI830->overlayOn = NULL; xfree(pI830->used3D); @@ -3398,7 +3221,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg) xf86ProbeOutputModes (pScrn, 0, 0); xf86SetScrnInfoModes (pScrn); - I830DGAReInit (pScrn->pScreen); + xf86DiDGAReInit (pScrn->pScreen); xf86SwitchMode(pScrn->pScreen, pScrn->currentMode); /* Clear the BIOS's hotkey press flags */ diff --git a/src/i830_edid_modes.c b/src/i830_edid_modes.c deleted file mode 100644 index 1bab4cd8..00000000 --- a/src/i830_edid_modes.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright 2006 Luc Verhaegen. - * - * 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 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. - */ - -/** - * @file This is a copy of edid_modes.c from the X Server, for compatibility - * with old X Servers. - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "xf86.h" -#include "xf86DDC.h" -#include <X11/Xatom.h> -#include "property.h" -#include "propertyst.h" -#include "xf86DDC.h" -#include "i830.h" -#include "i830_display.h" -#include <string.h> -#include <math.h> - -#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) - -/* - * Quirks to work around broken EDID data from various monitors. - */ - -typedef enum { - DDC_QUIRK_NONE = 0, - /* Force detailed sync polarity to -h +v */ - DDC_QUIRK_DT_SYNC_HM_VP = 1 << 0, - /* First detailed mode is bogus, prefer largest mode at 60hz */ - DDC_QUIRK_PREFER_LARGE_60 = 1 << 1, - /* 135MHz clock is too high, drop a bit */ - DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 2 -} ddc_quirk_t; - -static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC) -{ - /* Belinea 1924S1W */ - if (memcmp (DDC->vendor.name, "MAX", 4) == 0 && - DDC->vendor.prod_id == 1932) - return TRUE; - /* Belinea 10 20 30W */ - if (memcmp (DDC->vendor.name, "MAX", 4) == 0 && - DDC->vendor.prod_id == 2007) - return TRUE; - - return FALSE; -} - -static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) -{ - /* Belinea 10 15 55 */ - if (memcmp (DDC->vendor.name, "MAX", 4) == 0 && - DDC->vendor.prod_id == 1516) - return TRUE; - - return FALSE; -} - -static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC) -{ - /* Envision Peripherals, Inc. EN-7100e. See bug #9550. */ - if (memcmp (DDC->vendor.name, "EPI", 4) == 0 && - DDC->vendor.prod_id == 59264) - return TRUE; - - return FALSE; -} - -typedef struct { - Bool (*detect) (int scrnIndex, xf86MonPtr DDC); - ddc_quirk_t quirk; - char *description; -} ddc_quirk_map_t; - -static const ddc_quirk_map_t ddc_quirks[] = { - { - quirk_dt_sync_hm_vp, DDC_QUIRK_DT_SYNC_HM_VP, - "Set detailed timing sync polarity to -h +v" - }, - { - quirk_prefer_large_60, DDC_QUIRK_PREFER_LARGE_60, - "Detailed timing is not preferred, use largest mode at 60Hz" - }, - { - quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH, - "Recommended 135MHz pixel clock is too high" - }, - { - NULL, DDC_QUIRK_NONE, - "No known quirks" - }, -}; - -/* - * TODO: - * - for those with access to the VESA DMT standard; review please. - */ -#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER -#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0 - -static DisplayModeRec DDCEstablishedModes[17] = { - { MODEPREFIX("800x600"), 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */ - { MODEPREFIX("800x600"), 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */ - { MODEPREFIX("640x480"), 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */ - { MODEPREFIX("640x480"), 31500, 640, 664, 704, 832, 0, 480, 489, 491, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */ - { MODEPREFIX("640x480"), 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@67Hz */ - { MODEPREFIX("640x480"), 25200, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */ - { MODEPREFIX("720x400"), 35500, 720, 738, 846, 900, 0, 400, 421, 423, 449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400@88Hz */ - { MODEPREFIX("720x400"), 28320, 720, 738, 846, 900, 0, 400, 412, 414, 449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */ - { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */ - { MODEPREFIX("1024x768"), 78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */ - { MODEPREFIX("1024x768"), 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */ - { MODEPREFIX("1024x768"), 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */ - { MODEPREFIX("1024x768"), 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */ - { MODEPREFIX("832x624"), 57284, 832, 864, 928, 1152, 0, 624, 625, 628, 667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624@75Hz */ - { MODEPREFIX("800x600"), 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */ - { MODEPREFIX("800x600"), 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */ - { MODEPREFIX("1152x864"), 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */ -}; - -static DisplayModePtr -DDCModesFromEstablished(int scrnIndex, struct established_timings *timing, - ddc_quirk_t quirks) -{ - DisplayModePtr Modes = NULL, Mode = NULL; - CARD32 bits = (timing->t1) | (timing->t2 << 8) | - ((timing->t_manu & 0x80) << 9); - int i; - - for (i = 0; i < 17; i++) { - if (bits & (0x01 << i)) { - Mode = xf86DuplicateMode(&DDCEstablishedModes[i]); - Modes = xf86ModesAdd(Modes, Mode); - } - } - - return Modes; -} - -/* - * - */ -static DisplayModePtr -DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing, - ddc_quirk_t quirks) -{ - DisplayModePtr Modes = NULL, Mode = NULL; - int i; - - for (i = 0; i < STD_TIMINGS; i++) { - if (timing[i].hsize && timing[i].vsize && timing[i].refresh) { - Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize, - timing[i].refresh, FALSE, FALSE); - Mode->type = M_T_DRIVER; - Modes = xf86ModesAdd(Modes, Mode); - } - } - - return Modes; -} - -/* - * - */ -static DisplayModePtr -DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, - int preferred, ddc_quirk_t quirks) -{ - DisplayModePtr Mode; - - /* We don't do stereo */ - if (timing->stereo) { - xf86DrvMsg(scrnIndex, X_INFO, - "%s: Ignoring: We don't handle stereo.\n", __func__); - return NULL; - } - - /* We only do seperate sync currently */ - if (timing->sync != 0x03) { - xf86DrvMsg(scrnIndex, X_INFO, - "%s: %dx%d Warning: We only handle seperate" - " sync.\n", __func__, timing->h_active, timing->v_active); - } - - Mode = xnfalloc(sizeof(DisplayModeRec)); - memset(Mode, 0, sizeof(DisplayModeRec)); - - Mode->type = M_T_DRIVER; - if (preferred) - Mode->type |= M_T_PREFERRED; - - if( ( quirks & DDC_QUIRK_135_CLOCK_TOO_HIGH ) && - timing->clock == 135000000 ) - Mode->Clock = 108880; - else - Mode->Clock = timing->clock / 1000.0; - - Mode->HDisplay = timing->h_active; - Mode->HSyncStart = timing->h_active + timing->h_sync_off; - Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width; - Mode->HTotal = timing->h_active + timing->h_blanking; - - Mode->VDisplay = timing->v_active; - Mode->VSyncStart = timing->v_active + timing->v_sync_off; - Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width; - Mode->VTotal = timing->v_active + timing->v_blanking; - - xf86SetModeDefaultName(Mode); - - /* We ignore h/v_size and h/v_border for now. */ - - if (timing->interlaced) - Mode->Flags |= V_INTERLACE; - - if (quirks & DDC_QUIRK_DT_SYNC_HM_VP) - Mode->Flags |= V_NHSYNC | V_PVSYNC; - else - { - if (timing->misc & 0x02) - Mode->Flags |= V_PHSYNC; - else - Mode->Flags |= V_NHSYNC; - - if (timing->misc & 0x01) - Mode->Flags |= V_PVSYNC; - else - Mode->Flags |= V_NVSYNC; - } - - return Mode; -} - -DisplayModePtr -xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) -{ - int preferred, i; - DisplayModePtr Modes = NULL, Mode; - ddc_quirk_t quirks; - - xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n", - DDC->vendor.name, DDC->vendor.prod_id); - quirks = DDC_QUIRK_NONE; - for (i = 0; ddc_quirks[i].detect; i++) - if (ddc_quirks[i].detect (scrnIndex, DDC)) - { - xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n", - ddc_quirks[i].description); - quirks |= ddc_quirks[i].quirk; - } - - preferred = PREFERRED_TIMING_MODE(DDC->features.msc); - if (quirks & DDC_QUIRK_PREFER_LARGE_60) - preferred = 0; - - for (i = 0; i < DET_TIMINGS; i++) { - struct detailed_monitor_section *det_mon = &DDC->det_mon[i]; - - switch (det_mon->type) { - case DT: - Mode = DDCModeFromDetailedTiming(scrnIndex, - &det_mon->section.d_timings, - preferred, - quirks); - preferred = 0; - Modes = xf86ModesAdd(Modes, Mode); - break; - case DS_STD_TIMINGS: - Mode = DDCModesFromStandardTiming(scrnIndex, - det_mon->section.std_t, - quirks); - Modes = xf86ModesAdd(Modes, Mode); - break; - default: - break; - } - } - - /* Add established timings */ - Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1, quirks); - Modes = xf86ModesAdd(Modes, Mode); - - /* Add standard timings */ - Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2, quirks); - Modes = xf86ModesAdd(Modes, Mode); - - if (quirks & DDC_QUIRK_PREFER_LARGE_60) - { - DisplayModePtr best = Modes; - for (Mode = Modes; Mode; Mode = Mode->next) - { - if (Mode == best) continue; - if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay) - { - best = Mode; - continue; - } - if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay) - { - double mode_refresh = xf86ModeVRefresh (Mode); - double best_refresh = xf86ModeVRefresh (best); - double mode_dist = fabs(mode_refresh - 60.0); - double best_dist = fabs(best_refresh - 60.0); - if (mode_dist < best_dist) - { - best = Mode; - continue; - } - } - } - if (best) - best->type |= M_T_PREFERRED; - } - return Modes; -} - -#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) */ diff --git a/src/i830_exa.c b/src/i830_exa.c index 97b4a98e..bef8faef 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -297,6 +297,93 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, } } +/** + * Uploads data from system memory to the framebuffer using a series of + * 8x8 pattern blits. + */ +static Bool +i830_upload_to_screen(PixmapPtr pDst, int x, int y, int w, int h, char *src, + int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + const int uts_width_max = 16, uts_height_max = 16; + int cpp = pDst->drawable.bitsPerPixel / 8; + int sub_x, sub_y; + CARD32 br13; + CARD32 offset; + + if (w > uts_width_max || h > uts_height_max) + I830FALLBACK("too large for upload to screen (%d,%d)", w, h); + + offset = exaGetPixmapOffset(pDst); + + br13 = exaGetPixmapPitch(pDst); + br13 |= ((I830PatternROP[GXcopy] & 0xff) << 16); + switch (pDst->drawable.bitsPerPixel) { + case 16: + br13 |= 1 << 24; + break; + case 32: + br13 |= 3 << 24; + break; + } + + for (sub_y = 0; sub_y < uts_height_max && sub_y < h; sub_y += 8) { + int sub_height; + + if (sub_y + 8 > h) + sub_height = h - sub_y; + else + sub_height = 8; + + for (sub_x = 0; sub_x < uts_width_max && sub_x < w; sub_x += 8) { + int sub_width, line; + char *src_line = src + sub_y * src_pitch + sub_x * cpp; + + if (sub_x + 8 > w) + sub_width = w - sub_x; + else + sub_width = 8; + + BEGIN_LP_RING(6 + (cpp * 8 * 8 / 4)); + + /* XXX We may need a pattern offset here for {x,y} % 8 != 0*/ + OUT_RING(XY_PAT_BLT_IMMEDIATE | + XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB | + (3 + cpp * 8 * 8 / 4)); + OUT_RING(br13); + OUT_RING(((y + sub_y) << 16) | (x + sub_x)); + OUT_RING(((y + sub_y + sub_height) << 16) | + (x + sub_x + sub_width)); + OUT_RING(offset); + + /* Write out the lines with valid data, followed by any needed + * padding + */ + for (line = 0; line < sub_height; line++) { + OUT_RING_COPY(sub_width * cpp, src_line); + src_line += src_pitch; + if (sub_width != 8) + OUT_RING_PAD((8 - sub_width) * cpp); + } + /* Write out any full padding lines to follow */ + if (sub_height != 8) + OUT_RING_PAD(8 * cpp * (8 - sub_height)); + + OUT_RING(MI_NOOP); + ADVANCE_LP_RING(); + } + } + + exaMarkSync(pDst->drawable.pScreen); + /* exaWaitSync(pDst->drawable.pScreen); */ + + return TRUE; +} + + /* * TODO: * - Dual head? @@ -318,8 +405,9 @@ I830EXAInit(ScreenPtr pScreen) pI830->EXADriverPtr->exa_major = 2; pI830->EXADriverPtr->exa_minor = 1; pI830->EXADriverPtr->memoryBase = pI830->FbBase; - pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start; - pI830->EXADriverPtr->memorySize = pI830->Offscreen.End; + pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset; + pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset + + pI830->exa_offscreen->size; DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n", pI830->EXADriverPtr->memoryBase, @@ -346,7 +434,8 @@ I830EXAInit(ScreenPtr pScreen) * i965 limits 3D surface to 4kB-aligned offset if tiled. * i965 limits 3D surfaces to w,h of ?,8192. * i965 limits 3D surface to pitch of 1B - 128kB. - * i965 limits 3D surface pitch alignment to 512B, only if tiled. + * i965 limits 3D surface pitch alignment to 1 or 2 times the element size. + * i965 limits 3D surface pitch alignment to 512B if tiled. * i965 limits 3D destination drawing rect to w,h of 8192,8192. * * i915 limits 3D textures to 4B-aligned offset if un-tiled. @@ -374,7 +463,7 @@ I830EXAInit(ScreenPtr pScreen) */ if (IS_I965G(pI830)) { pI830->EXADriverPtr->pixmapOffsetAlign = 4 * 2; - pI830->EXADriverPtr->pixmapPitchAlign = 1; + pI830->EXADriverPtr->pixmapPitchAlign = 16; pI830->EXADriverPtr->maxX = 8192; pI830->EXADriverPtr->maxY = 8192; } else { @@ -419,6 +508,10 @@ I830EXAInit(ScreenPtr pScreen) pI830->EXADriverPtr->DoneComposite = i830_done_composite; } + /* UploadToScreen/DownloadFromScreen */ + if (0) + pI830->EXADriverPtr->UploadToScreen = i830_upload_to_screen; + if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EXA initialization failed; trying older version\n"); diff --git a/src/i830_lvds.c b/src/i830_lvds.c index 59af13b9..642dd8a3 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -32,6 +32,7 @@ #include "xf86.h" #include "i830.h" #include "i830_bios.h" +#include "i830_display.h" #include "X11/Xatom.h" /** @@ -406,21 +407,99 @@ i830_lvds_init(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); xf86OutputPtr output; I830OutputPrivatePtr intel_output; + DisplayModePtr modes, scan, bios_mode; + output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "LVDS"); + if (!output) + return; + intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1); + if (!intel_output) + { + xf86OutputDestroy (output); + return; + } + intel_output->type = I830_OUTPUT_LVDS; + output->driver_private = intel_output; + output->subpixel_order = SubPixelHorizontalRGB; + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + + /* Set up the LVDS DDC channel. Most panels won't support it, but it can + * be useful if available. + */ + I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOC, "LVDSDDC_C"); + + /* Attempt to get the fixed panel mode from DDC. Assume that the preferred + * mode is the right one. + */ + modes = i830_ddc_get_modes(output); + for (scan = modes; scan != NULL; scan = scan->next) { + if (scan->type & M_T_PREFERRED) + break; + } + if (scan != NULL) { + /* Pull our chosen mode out and make it the fixed mode */ + if (modes == scan) + modes = modes->next; + if (scan->prev != NULL) + scan->prev = scan->next; + if (scan->next != NULL) + scan->next = scan->prev; + pI830->panel_fixed_mode = scan; + } + /* Delete the mode list */ + while (modes != NULL) + xf86DeleteMode(&modes, modes); + + /* If we didn't get EDID, try checking if the panel is already turned on. + * If so, assume that whatever is currently programmed is the correct mode. + */ + if (pI830->panel_fixed_mode == NULL) { + CARD32 lvds = INREG(LVDS); + int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcPtr crtc = xf86_config->crtc[pipe]; + + if (lvds & LVDS_PORT_EN) { + pI830->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc); + if (pI830->panel_fixed_mode != NULL) + pI830->panel_fixed_mode->type |= M_T_PREFERRED; + } + } /* Get the LVDS fixed mode out of the BIOS. We should support LVDS with * the BIOS being unavailable or broken, but lack the configuration options * for now. */ - if (!i830GetLVDSInfoFromBIOS(pScrn)) - return; + bios_mode = i830_bios_get_panel_mode(pScrn); + if (bios_mode != NULL) { + if (pI830->panel_fixed_mode != NULL) { + if (!xf86ModesEqual(pI830->panel_fixed_mode, bios_mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "BIOS panel mode data doesn't match probed data, " + "continuing with probed.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS mode:\n"); + xf86PrintModeline(pScrn->scrnIndex, bios_mode); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "probed mode:\n"); + xf86PrintModeline(pScrn->scrnIndex, pI830->panel_fixed_mode); + xfree(bios_mode->name); + xfree(bios_mode); + } + } else { + pI830->panel_fixed_mode = bios_mode; + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Couldn't detect panel mode. Disabling panel\n"); + goto disable_exit; + } /* Blacklist machines with BIOSes that list an LVDS panel without actually * having one. */ if (pI830->PciInfo->chipType == PCI_CHIP_I945_GM) { if (pI830->PciInfo->subsysVendor == 0xa0a0) /* aopen mini pc */ - return; + goto disable_exit; if ((pI830->PciInfo->subsysVendor == 0x8086) && (pI830->PciInfo->subsysCard == 0x7270)) { @@ -435,31 +514,18 @@ i830_lvds_init(ScrnInfoPtr pScrn) if (pI830->panel_fixed_mode != NULL && pI830->panel_fixed_mode->HDisplay == 800 && - pI830->panel_fixed_mode->VDisplay == 600) { + pI830->panel_fixed_mode->VDisplay == 600) + { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Suspected Mac Mini, ignoring the LVDS\n"); - return; + goto disable_exit; } } - } - - output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "LVDS"); - if (!output) - return; - intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1); - if (!intel_output) - { - xf86OutputDestroy (output); - return; } - intel_output->type = I830_OUTPUT_LVDS; - output->driver_private = intel_output; - output->subpixel_order = SubPixelHorizontalRGB; - output->interlaceAllowed = FALSE; - output->doubleScanAllowed = FALSE; - /* Set up the LVDS DDC channel. Most panels won't support it, but it can - * be useful if available. - */ - I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOC, "LVDSDDC_C"); + return; + +disable_exit: + xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); + xf86OutputDestroy(output); } diff --git a/src/i830_memory.c b/src/i830_memory.c index 6ceb05b5..5cddf173 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -50,6 +50,51 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Alan Hourihane <alanh@tungstengraphics.com> */ +/** + * @file i830_memory.c + * + * This is the video memory allocator. Our memory allocation is different from + * other graphics chips, where you have a fixed amount of graphics memory + * available that you want to put to the best use. Instead, we have almost no + * memory pre-allocated, and we have to choose an appropriate amount of sytem + * memory to use. + * + * The allocations we might do: + * + * - Ring buffer + * - HW cursor 1 + * - HW cursor 2 + * - HW ARGB cursor 1 + * - HW ARGB cursor 2 + * - Overlay registers + * - XAA linear allocator (optional) + * - EXA 965 state buffer + * - XAA scratch (screen 1) + * - XAA scratch (screen 2, only in zaphod mode) + * - Front buffer (screen 1, more is better for XAA) + * - Front buffer (screen 2, only in zaphod mode, more is better for XAA) + * - Back/depth buffer (3D only) + * - Compatibility texture pool (optional, more is always better) + * - New texture pool (optional, more is always better. aperture allocation + * only) + * - EXA offscreen pool (more is always better) + * + * We also want to be able to resize the front/back/depth buffers, and then + * resize the EXA and texture memory pools appropriately. + * + * The user may request a specific amount of memory to be used + * (pI830->pEnt->videoRam != 0), in which case allocations have to fit within + * that much aperture. If not, the individual allocations will be + * automatically sized, and will be fit within the maximum aperture size. + * Only the actual memory used (not alignment padding) will get actual AGP + * memory allocated. + * + * Given that the allocations listed are generally a page or more than a page, + * our allocator will only return page-aligned offsets, simplifying the memory + * binding process. For smaller allocations, the acceleration architecture's + * linear allocator is preferred. + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -62,429 +107,608 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i830.h" #include "i810_reg.h" -static int nextTile = 0; -static unsigned int tileGeneration = -1; +#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) +enum tile_format { + TILING_NONE, + TILING_XMAJOR, + TILING_YMAJOR +}; + +static void i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, + unsigned int pitch, unsigned int size, + enum tile_format tile_format); + +/** + * Returns the fence size for a tiled area of the given size. + */ static unsigned long -GetBestTileAlignment(unsigned long size) +i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long i; + unsigned long start; + + if (IS_I965G(pI830)) { + /* The 965 can have fences at any page boundary. */ + return ALIGN(size, GTT_PAGE_SIZE); + } else { + /* Align the size to a power of two greater than the smallest fence + * size. + */ + if (IS_I9XX(pI830)) + start = MB(1); + else + start = KB(512); + + for (i = start; i < size; i <<= 1) + ; + + return i; + } +} + +static Bool +i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { - unsigned long i; + I830Ptr pI830 = I830PTR(pScrn); - for (i = KB(512); i < size; i <<= 1) - ; + if (mem == NULL || mem->key == -1 || mem->bound || !pI830->gtt_acquired) + return TRUE; - if (i > MB(64)) - i = MB(64); + if (xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) { + mem->bound = TRUE; + return TRUE; + } else { + return FALSE; + } - return i; + return TRUE; } -/* - * Allocate memory from the given pool. Grow the pool if needed and if - * possible. - */ -static unsigned long -AllocFromPool(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) +static Bool +i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { - I830Ptr pI830 = I830PTR(pScrn); - long needed, start, end; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - - if (!result || !pool || !size) - return 0; - - /* Calculate how much space is needed. */ - if (alignment <= GTT_PAGE_SIZE) - needed = size; - else { - if (flags & ALLOCATE_AT_BOTTOM) { - start = ROUND_TO(pool->Free.Start, alignment); - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_TO(start + size, alignment); - else - end = start + size; - needed = end - pool->Free.Start; - } else { /* allocate at top */ - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_DOWN_TO(pool->Free.End, alignment); - else - end = pool->Free.End; - - start = ROUND_DOWN_TO(end - size, alignment); - needed = end - start; - } - } - if (needed > pool->Free.Size) { - long extra; - /* See if the pool can be grown. */ - if (pI830->StolenOnly && !dryrun) - return 0; - extra = needed - pool->Free.Size; - extra = ROUND_TO_PAGE(extra); - if (extra > pI830->FreeMemory) { - if (dryrun) - pI830->FreeMemory = extra; - else - return 0; - } - - if (!dryrun && ((long)extra > pI830->MemoryAperture.Size)) - return 0; - - pool->Free.Size += extra; - pool->Free.End += extra; - pool->Total.Size += extra; - pool->Total.End += extra; - pI830->FreeMemory -= extra; - pI830->MemoryAperture.Start += extra; - pI830->MemoryAperture.Size -= extra; - } - if (flags & ALLOCATE_AT_BOTTOM) { - result->Start = ROUND_TO(pool->Free.Start, alignment); - pool->Free.Start += needed; - result->End = pool->Free.Start; - } else { - result->Start = ROUND_DOWN_TO(pool->Free.End - size, alignment); - pool->Free.End -= needed; - result->End = result->Start + needed; - } - pool->Free.Size = pool->Free.End - pool->Free.Start; - result->Size = result->End - result->Start; - result->Pool = pool; - result->Alignment = alignment; - return needed; + if (mem == NULL || mem->key == -1 || !mem->bound) + return TRUE; + + if (xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) { + mem->bound = FALSE; + return TRUE; + } else { + return FALSE; + } } -static unsigned long -AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, long size, - unsigned long alignment, int flags) +void +i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) { - I830Ptr pI830 = I830PTR(pScrn); - unsigned long start, end; - unsigned long newApStart, newApEnd; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - - if (!result || !size) - return 0; - - if ((flags & ALLOCATE_AT_BOTTOM) && pI830->StolenMemory.Size != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AllocFromAGP(): can't allocate from " - "bottom when there is stolen memory\n"); - return 0; - } - - if (size > pI830->FreeMemory) { - if (dryrun) - pI830->FreeMemory = size; - else - return 0; - } - - /* Calculate offset */ - if (flags & ALLOCATE_AT_BOTTOM) { - start = ROUND_TO(pI830->MemoryAperture.Start, alignment); - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_TO(start + size, alignment); - else - end = start + size; - newApStart = end; - newApEnd = pI830->MemoryAperture.End; - } else { - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_DOWN_TO(pI830->MemoryAperture.End, alignment); - else - end = pI830->MemoryAperture.End; - start = ROUND_DOWN_TO(end - size, alignment); - newApStart = pI830->MemoryAperture.Start; - newApEnd = start; - } - - if (!dryrun) { - if (newApStart > newApEnd) - return 0; - - if (flags & NEED_PHYSICAL_ADDR) - result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, - &(result->Physical)); - else - result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); - - if (result->Key == -1) - return 0; - } - - pI830->allocatedMemory += size; - pI830->MemoryAperture.Start = newApStart; - pI830->MemoryAperture.End = newApEnd; - pI830->MemoryAperture.Size = newApEnd - newApStart; - pI830->FreeMemory -= size; - result->Start = start; - result->End = start + size; - result->Size = size; - result->Offset = start; - result->Alignment = alignment; - result->Pool = NULL; - - return size; + if (mem == NULL) + return; + + i830_unbind_memory(pScrn, mem); + + /* Disconnect from the list of allocations */ + if (mem->prev != NULL) + mem->prev->next = mem->next; + if (mem->next != NULL) + mem->next->prev = mem->prev; + + /* Free any AGP memory. */ + i830_unbind_memory(pScrn, mem); + + if (mem->key != -1) { + xf86DeallocateGARTMemory(pScrn->scrnIndex, mem->key); + mem->key = -1; + } + + xfree(mem->name); + xfree(mem); } +/* Resets the state of the aperture allocator, freeing all memory that had + * been allocated. + */ void -I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range) +i830_reset_allocations(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + /* While there is any memory between the start and end markers, free it. */ + while (pI830->memory_list->next->next != NULL) + i830_free_memory(pScrn, pI830->memory_list->next); + + /* Null out the pointers for all the allocations we just freed. This is + * kind of gross, but at least it's just one place now. + */ + for (i = 0; i < xf86_config->num_crtc; i++) { + I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + + intel_crtc->cursor_mem = NULL; + intel_crtc->cursor_mem_argb = NULL; + } + + pI830->front_buffer = NULL; + pI830->front_buffer_2 = NULL; + pI830->xaa_scratch = NULL; + pI830->xaa_scratch_2 = NULL; + pI830->exa_offscreen = NULL; + pI830->exa_965_state = NULL; + pI830->overlay_regs = NULL; + pI830->xaa_linear = NULL; + pI830->logical_context = NULL; + pI830->back_buffer = NULL; + pI830->depth_buffer = NULL; + pI830->textures = NULL; + pI830->memory_manager = NULL; + pI830->LpRing->mem = NULL; + + /* Reset the fence register allocation. */ + pI830->next_fence = 0; + memset(pI830->fence, 0, sizeof(pI830->fence)); +} + +void +i830_free_3d_memory(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + i830_free_memory(pScrn, pI830->back_buffer); + pI830->back_buffer = NULL; + i830_free_memory(pScrn, pI830->depth_buffer); + pI830->depth_buffer = NULL; + i830_free_memory(pScrn, pI830->textures); + pI830->textures = NULL; + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; +} + +/** + * Initialize's the driver's video memory allocator to allocate in the + * given range. + */ +Bool +i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, + unsigned long size) +{ + I830Ptr pI830 = I830PTR(pScrn); + i830_memory *start, *end; + + start = xcalloc(1, sizeof(*start)); + if (start == NULL) + return FALSE; + start->name = xstrdup("start marker"); + if (start->name == NULL) { + xfree(start); + return FALSE; + } + end = xcalloc(1, sizeof(*end)); + if (end == NULL) { + xfree(start->name); + xfree(start); + return FALSE; + } + end->name = xstrdup("end marker"); + if (end->name == NULL) { + xfree(start->name); + xfree(start); + xfree(end); + return FALSE; + } + + start->key = -1; + start->offset = offset; + start->end = start->offset; + start->size = 0; + start->next = end; + end->key = -1; + end->offset = offset + size; + end->end = end->offset; + end->size = 0; + end->prev = start; + + pI830->memory_list = start; + + return TRUE; +} + +/* Allocate aperture space for the given size and alignment, and returns the + * memory allocation. + * + * Allocations are a minimum of a page, and will be at least page-aligned. + */ +static i830_memory * +i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, + long size, unsigned long alignment, int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + i830_memory *mem, *scan; + + mem = xcalloc(1, sizeof(*mem)); + if (mem == NULL) + return NULL; + + /* No memory allocated to back the region */ + mem->key = -1; + + mem->name = xstrdup(name); + if (mem->name == NULL) { + xfree(mem); + return NULL; + } + /* Only allocate page-sized increments. */ + size = ALIGN(size, GTT_PAGE_SIZE); + mem->size = size; + + if (alignment < GTT_PAGE_SIZE) + alignment = GTT_PAGE_SIZE; + + for (scan = pI830->memory_list; scan->next != NULL; scan = scan->next) { + mem->offset = scan->end; + /* For allocations requiring physical addresses, we have to use AGP + * memory, so move the allocation up out of stolen memory. + */ + if ((flags & NEED_PHYSICAL_ADDR) && mem->offset < pI830->stolen_size) + mem->offset = pI830->stolen_size; + mem->offset = ROUND_TO(mem->offset, alignment); + + mem->end = mem->offset + size; + if (flags & ALIGN_BOTH_ENDS) + mem->end = ROUND_TO(mem->end, alignment); + if (mem->end <= scan->next->offset) + break; + } + if (scan->next == NULL) { + /* Reached the end of the list, and didn't find space */ + xfree(mem->name); + xfree(mem); + return NULL; + } + /* Insert new allocation into the list */ + mem->prev = scan; + mem->next = scan->next; + scan->next = mem; + mem->next->prev = scan; + + return mem; +} + +/** + * Allocates the AGP memory necessary for the part of a memory allocation not + * already covered by the stolen memory. + * + * The memory is automatically bound if we have the VT. + */ +static Bool +i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size; + + if (mem->key != -1) + return TRUE; + + if (mem->offset + mem->size <= pI830->stolen_size && + !(flags & NEED_PHYSICAL_ADDR)) + { + return TRUE; + } + + if (mem->offset < pI830->stolen_size) + mem->agp_offset = pI830->stolen_size; + else + mem->agp_offset = mem->offset; + + size = mem->size - (mem->agp_offset - mem->offset); + + if (flags & NEED_PHYSICAL_ADDR) + mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, + &mem->bus_addr); + else + mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); + if (mem->key == -1 || ((flags & NEED_PHYSICAL_ADDR) && mem->bus_addr == 0)) + { + return FALSE; + } + + if (!i830_bind_memory(pScrn, mem)) { + return FALSE; + } + + return TRUE; +} + + +/* Allocates video memory at the given size and alignment. + * + * The memory will be bound automatically when the driver is in control of the + * VT. + */ +static i830_memory * +i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, + unsigned long size, unsigned long alignment, int flags) +{ + i830_memory *mem; + + mem = i830_allocate_aperture(pScrn, name, size, alignment, flags); + if (mem == NULL) + return NULL; + + if (!i830_allocate_agp_memory(pScrn, mem, flags)) { + i830_free_memory(pScrn, mem); + return NULL; + } + + return mem; +} + +/* Allocate a tiled region with the given size and pitch. + * + * As is, we might miss out on tiling some allocations on older hardware with + * large framebuffer size and a small aperture size, where the first + * allocations use a large alignment even though we've got fences to spare, and + * the later allocations can't find enough aperture space left. We could do + * some search across all allocation options to fix this, probably, but that + * would be another rewrite. + */ +static i830_memory * +i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, + unsigned long size, unsigned long pitch, + unsigned long alignment, int flags, + enum tile_format tile_format) { - 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; - 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; + I830Ptr pI830 = I830PTR(pScrn); + unsigned long aper_size; + unsigned long aper_align; + i830_memory *mem; + int fence_divide, i; + + if (tile_format == TILING_NONE) + return i830_allocate_memory(pScrn, name, size, alignment, flags); + + /* Only allocate page-sized increments. */ + size = ALIGN(size, GTT_PAGE_SIZE); + + /* Check for maximum tiled region size */ + if (IS_I9XX(pI830)) { + if (size > MB(128)) + return NULL; + } else { + if (size > MB(64)) + return NULL; + } + + aper_size = i830_get_fence_size(pScrn, size); + if (IS_I965G(pI830)) { + aper_align = GTT_PAGE_SIZE; + } else { + /* The offset has to be aligned to at least the size of the fence + * region. + */ + aper_align = aper_size; + } + if (aper_align < alignment) + aper_align = alignment; + + fence_divide = 1; + mem = i830_allocate_aperture(pScrn, name, aper_size, aper_align, flags); + if (mem == NULL && !IS_I965G(pI830)) { + /* For the older hardware with stricter fencing limits, if we + * couldn't allocate with the large alignment, try relaxing the + * alignment requirements and using more fences to cover the area. + */ + for (fence_divide = 2; fence_divide <= 4 && mem == NULL; + fence_divide *= 2) + { + /* Check that it's not too small for fencing. */ + if (i830_get_fence_size(pScrn, aper_align / fence_divide) != + aper_align / fence_divide) + { + break; + } + + mem = i830_allocate_aperture(pScrn, name, aper_size, + aper_align / fence_divide, flags); + } + } + + if (mem == NULL) + return NULL; + + /* Make sure we've got enough free fence regs. It's pretty hard to run + * out, luckily, with 8 even on older hardware and us only tiling + * front/back/depth buffers. + */ + if (pI830->next_fence + fence_divide > + (IS_I965G(pI830) ? FENCE_NEW_NR : FENCE_NR)) + { + i830_free_memory(pScrn, mem); + return NULL; + } + + /* Allocate any necessary AGP memory to back this allocation */ + if (!i830_allocate_agp_memory(pScrn, mem, flags)) { + i830_free_memory(pScrn, mem); + return NULL; + } + + /* Set up the fence registers. */ + for (i = 0; i < fence_divide; i++) { + i830_set_fence(pScrn, pI830->next_fence++, + mem->offset + mem->size * i / fence_divide, pitch, + mem->size / fence_divide, tile_format); + } + + mem->size = size; + + return mem; } -unsigned long -I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) +static void +i830_describe_tiling(ScrnInfoPtr pScrn, int verbosity, const char *prefix, + i830_memory *mem, unsigned int tiling_mode) { - I830Ptr pI830 = I830PTR(pScrn); - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - - if (!result) - return 0; - - /* Make sure these are initialised. */ - result->Size = 0; - result->Key = -1; - - if (!size) { - return 0; - } - - switch (flags & FROM_MASK) { - case FROM_POOL_ONLY: - return AllocFromPool(pScrn, result, pool, size, alignment, flags); - case FROM_NEW_ONLY: - if (!dryrun && (pI830->StolenOnly || (pI830->FreeMemory <= 0))) - return 0; - return AllocFromAGP(pScrn, result, size, alignment, flags); - case FROM_ANYWHERE: - if ((!(flags & ALLOCATE_AT_BOTTOM) && (pI830->FreeMemory >= size)) || - (flags & NEED_PHYSICAL_ADDR)) - return AllocFromAGP(pScrn, result, size, alignment, flags); - else - return AllocFromPool(pScrn, result, pool, size, alignment, flags); - default: - /* Shouldn't happen. */ - return 0; - } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s%s is %stiled\n", prefix, mem->name, + (tiling_mode == FENCE_LINEAR) ? "not " : ""); +} + +void +i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) +{ + I830Ptr pI830 = I830PTR(pScrn); + i830_memory *mem; + + if (pI830->memory_list == NULL) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sMemory allocator not initialized\n", prefix); + return; + } + + if (pI830->memory_list->next->next == NULL) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sNo memory allocations\n", prefix); + return; + } + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sMemory allocation layout:\n", prefix); + + for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) { + + if (mem->offset >= pI830->stolen_size && + mem->prev->offset < pI830->stolen_size) + { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx: end of stolen memory\n", + prefix, pI830->stolen_size); + } + + if (mem->bus_addr == 0) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix, + mem->offset, mem->end - 1, mem->name, + mem->size / 1024); + } else { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx-0x%08lx: %s (%ld kB, 0x%08lx physical)\n", + prefix, + mem->offset, mem->end - 1, mem->name, + mem->size / 1024, mem->bus_addr); + } + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx: end of aperture\n", + prefix, pI830->FbMapSize); + + if (pI830->front_buffer != NULL) { + i830_describe_tiling(pScrn, verbosity, prefix, pI830->front_buffer, + pI830->front_tiled); + } + if (pI830->back_buffer != NULL) { + i830_describe_tiling(pScrn, verbosity, prefix, pI830->back_buffer, + pI830->back_tiled); + } + if (pI830->depth_buffer != NULL) { + i830_describe_tiling(pScrn, verbosity, prefix, pI830->depth_buffer, + pI830->depth_tiled); + } } static Bool -AllocateRingBuffer(ScrnInfoPtr pScrn, int flags) +i830_allocate_ringbuffer(ScrnInfoPtr pScrn) { - 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] " : ""; - - /* Clear ring buffer info */ - memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); - pI830->LpRing->mem.Key = -1; - - if (pI830->noAccel) - return TRUE; - - /* Ring buffer */ - size = PRIMARY_RINGBUFFER_SIZE; - if (flags & FORCE_LOW) - flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM; - else - flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP; - - alloced = I830AllocVidMem(pScrn, &(pI830->LpRing->mem), - &(pI830->StolenPool), size, - GTT_PAGE_SIZE, flags); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate Ring Buffer space\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the ring buffer at 0x%lx\n", s, - alloced / 1024, pI830->LpRing->mem.Start); - pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; - return TRUE; + I830Ptr pI830 = I830PTR(pScrn); + + if (pI830->noAccel || pI830->LpRing->mem != NULL) + return TRUE; + + pI830->LpRing->mem = i830_allocate_memory(pScrn, "ring buffer", + PRIMARY_RINGBUFFER_SIZE, + GTT_PAGE_SIZE, 0); + if (pI830->LpRing->mem == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate Ring Buffer space\n"); + return FALSE; + } + + pI830->LpRing->tail_mask = pI830->LpRing->mem->size - 1; + return TRUE; } #ifdef I830_XV -/* - * Note, the FORCE_LOW flag is currently not used or supported. +/** + * Allocate space for overlay registers and XAA linear allocator (if + * requested) */ static Bool -AllocateOverlay(ScrnInfoPtr pScrn, int flags) +i830_allocate_overlay(ScrnInfoPtr pScrn) { - 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] " : ""; - - /* Clear overlay info */ - memset(pI830->OverlayMem, 0, sizeof(I830MemRange)); - pI830->OverlayMem->Key = -1; - - if (!pI830->XvEnabled) - return TRUE; - - /* - * The overlay register space needs a physical address in - * system memory. We get this from the agpgart module using - * a special memory type. - */ - - size = OVERLAY_SIZE; - if (flags & FORCE_LOW) - flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM | NEED_PHYSICAL_ADDR; - else - flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP | NEED_PHYSICAL_ADDR; - - alloced = I830AllocVidMem(pScrn, pI830->OverlayMem, - &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags); - - /* - * XXX For testing only. Don't enable this unless you know how to set - * physBase. - */ - if (flags & FORCE_LOW) { - ErrorF("AllocateOverlay() doesn't support setting FORCE_LOW\n"); - return FALSE; - } - - if (!dryrun && (alloced < size)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate Overlay register space.\n"); - /* This failure isn't fatal. */ - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for Overlay registers at 0x%lx " - "(0x%08lx).\n", s, - alloced / 1024, pI830->OverlayMem->Start, - pI830->OverlayMem->Physical); - } - - /* Clear linearmem info */ - if (pI830->LinearAlloc) { - memset(&(pI830->LinearMem), 0, sizeof(I830MemRange)); - pI830->LinearMem.Key = -1; - - 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, + I830Ptr pI830 = I830PTR(pScrn); + + /* Only allocate if overlay is going to be enabled. */ + if (!pI830->XvEnabled || IS_I965G(pI830)) + return TRUE; + + if (!IS_I965G(pI830)) { + pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers", + OVERLAY_SIZE, GTT_PAGE_SIZE, + NEED_PHYSICAL_ADDR); + if (pI830->overlay_regs == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate Overlay register space.\n"); + /* This failure isn't fatal. */ + } + } + + if (!pI830->useEXA && pI830->LinearAlloc) { + pI830->xaa_linear = i830_allocate_memory(pScrn, "XAA linear memory", + KB(pI830->LinearAlloc), + GTT_PAGE_SIZE, 0); + if (pI830->xaa_linear == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "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 TRUE; + } + } + + return TRUE; } #endif static Bool IsTileable(ScrnInfoPtr pScrn, int pitch) { - I830Ptr pI830 = I830PTR(pScrn); - - if (IS_I965G(pI830)) { - if (pitch / 512 * 512 == pitch && pitch <= KB(128)) - return TRUE; - else - return FALSE; - } - - /* - * Allow tiling for pitches that are a power of 2 multiple of 128 bytes, - * up to 64 * 128 (= 8192) bytes. - */ - switch (pitch) { - case 128: - case 256: - if (IS_I945G(pI830) || IS_I945GM(pI830)) - return TRUE; - else - return FALSE; - case 512: - case KB(1): - case KB(2): - case KB(4): - case KB(8): - return TRUE; - default: - return FALSE; - } -} + I830Ptr pI830 = I830PTR(pScrn); -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; + if (IS_I965G(pI830)) { + if (pitch / 512 * 512 == pitch && pitch <= KB(128)) + return TRUE; + else + return FALSE; + } - return extra; + /* + * Allow tiling for pitches that are a power of 2 multiple of 128 bytes, + * up to 64 * 128 (= 8192) bytes. + */ + switch (pitch) { + case 128: + case 256: + if (IS_I945G(pI830) || IS_I945GM(pI830)) + return TRUE; + else + return FALSE; + case 512: + case KB(1): + case KB(2): + case KB(4): + case KB(8): + return TRUE; + default: + return FALSE; + } } /* This is the 2D rendering vertical coordinate limit. We can ignore @@ -504,204 +728,162 @@ GetFreeSpace(ScrnInfoPtr pScrn) * \param pI830 I830Ptr for the screen being allocated. * \param FbMemBox */ -static Bool -I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, - I830MemRange *FrontBuffer, I830MemPool *StolenPool, - Bool secondary, const int flags) +static i830_memory * +i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, + Bool secondary, int flags) { - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - unsigned long minspace, avail, lineSize; - int cacheLines, maxCacheLines; - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - Bool tileable; - int align, alignflags; - long size, alloced, fb_height; - - /* Clear everything first. */ - memset(FbMemBox, 0, sizeof(*FbMemBox)); - memset(FrontBuffer, 0, sizeof(*FrontBuffer)); - FrontBuffer->Key = -1; - - /* We'll allocate the fb such that the root window will fit regardless of - * rotation. - */ - if (pScrn->virtualX > pScrn->virtualY) - fb_height = pScrn->virtualX; - else - fb_height = pScrn->virtualY; - - FbMemBox->x1 = 0; - FbMemBox->x2 = pScrn->displayWidth; - FbMemBox->y1 = 0; - FbMemBox->y2 = fb_height; - - /* Calculate how much framebuffer memory to allocate. For the - * initial allocation, calculate a reasonable minimum. This is - * enough for the virtual screen size, plus some pixmap cache - * space if we're using XAA. - */ - - lineSize = pScrn->displayWidth * pI830->cpp; - minspace = lineSize * pScrn->virtualY; - avail = pScrn->videoRam * 1024; - - if (!pI830->useEXA) { - maxCacheLines = (avail - minspace) / lineSize; - /* This shouldn't happen. */ - if (maxCacheLines < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal Error: " - "maxCacheLines < 0 in I830Allocate2DMemory()\n"); - maxCacheLines = 0; - } - if (maxCacheLines > (MAX_2D_HEIGHT - pScrn->virtualY)) - maxCacheLines = MAX_2D_HEIGHT - pScrn->virtualY; - - if (pI830->CacheLines >= 0) { - cacheLines = pI830->CacheLines; - } else { - int size; - - size = 3 * lineSize * pScrn->virtualY; - size += 1920 * 1088 * 2 * 2; - size = ROUND_TO_PAGE(size); - - cacheLines = (size + lineSize - 1) / lineSize; - } - if (cacheLines > maxCacheLines) - cacheLines = maxCacheLines; - - FbMemBox->y2 += cacheLines; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocating at least %d scanlines for pixmap cache\n", - s, cacheLines); - } else { - /* For EXA, we have a separate allocation for the linear allocator which - * also does the pixmap cache. - */ - cacheLines = 0; - } - - tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && - IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { - if (IS_I9XX(pI830)) - align = MB(1); - else - align = KB(512); - alignflags = ALIGN_BOTH_ENDS; - } else { - align = KB(64); - alignflags = 0; - } - - size = lineSize * (fb_height + cacheLines); - size = ROUND_TO_PAGE(size); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sInitial %sframebuffer allocation size: %ld kByte\n", - s, secondary ? "secondary " : "", - size / 1024); - alloced = I830AllocVidMem(pScrn, FrontBuffer, - StolenPool, size, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " - "%sframebuffer. Is your VideoRAM set too low?\n", - secondary ? "secondary " : ""); - } - return FALSE; - } - - return TRUE; + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + unsigned long minspace, avail; + int cacheLines, maxCacheLines; + int align; + long size, fb_height; + char *name; + i830_memory *front_buffer = NULL; + + /* Clear everything first. */ + memset(FbMemBox, 0, sizeof(*FbMemBox)); + + /* We'll allocate the fb such that the root window will fit regardless of + * rotation. + */ + if (pScrn->virtualX > pScrn->virtualY) + fb_height = pScrn->virtualX; + else + fb_height = pScrn->virtualY; + + FbMemBox->x1 = 0; + FbMemBox->x2 = pScrn->displayWidth; + FbMemBox->y1 = 0; + FbMemBox->y2 = fb_height; + + /* Calculate how much framebuffer memory to allocate. For the + * initial allocation, calculate a reasonable minimum. This is + * enough for the virtual screen size, plus some pixmap cache + * space if we're using XAA. + */ + minspace = pitch * pScrn->virtualY; + avail = pScrn->videoRam * 1024; + + if (!pI830->useEXA) { + maxCacheLines = (avail - minspace) / pitch; + /* This shouldn't happen. */ + if (maxCacheLines < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal Error: " + "maxCacheLines < 0 in i830_allocate_2d_memory()\n"); + maxCacheLines = 0; + } + if (maxCacheLines > (MAX_2D_HEIGHT - pScrn->virtualY)) + maxCacheLines = MAX_2D_HEIGHT - pScrn->virtualY; + + if (pI830->CacheLines >= 0) { + cacheLines = pI830->CacheLines; + } else { + int size; + + size = 3 * pitch * pScrn->virtualY; + size += 1920 * 1088 * 2 * 2; + size = ROUND_TO_PAGE(size); + + cacheLines = (size + pitch - 1) / pitch; + } + if (cacheLines > maxCacheLines) + cacheLines = maxCacheLines; + + FbMemBox->y2 += cacheLines; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocating %d scanlines for pixmap cache\n", + cacheLines); + } else { + /* For EXA, we have a separate allocation for the linear allocator + * which also does the pixmap cache. + */ + cacheLines = 0; + } + + size = pitch * (fb_height + cacheLines); + size = ROUND_TO_PAGE(size); + + name = secondary ? "secondary front buffer" : "front buffer"; + + /* Attempt to allocate it tiled first if we have page flipping on. */ + if (!pI830->disableTiling && pI830->allowPageFlip && + IsTileable(pScrn, pitch)) + { + /* XXX: probably not the case on 965 */ + if (IS_I9XX(pI830)) + align = MB(1); + else + align = KB(512); + front_buffer = i830_allocate_memory_tiled(pScrn, name, size, + pitch, align, + 0, TILING_XMAJOR); + pI830->front_tiled = FENCE_XMAJOR; + } + + /* If not, attempt it linear */ + if (front_buffer == NULL) { + front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags); + pI830->front_tiled = FENCE_LINEAR; + } + + if (front_buffer == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " + "%sframebuffer. Is your VideoRAM set too low?\n", + secondary ? "secondary " : ""); + return NULL; + } + + return front_buffer; } static Bool -I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags) +i830_allocate_cursor_buffers(xf86CrtcPtr crtc) { - ScrnInfoPtr pScrn = crtc->scrn; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - I830Ptr pI830 = I830PTR(pScrn); - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - long size, alloced; - int cursFlags = 0; - - /* Clear cursor info */ - memset(&intel_crtc->cursor_mem, 0, sizeof(I830MemRange)); - intel_crtc->cursor_mem.Key = -1; - memset(&intel_crtc->cursor_mem_argb, 0, sizeof(I830MemRange)); - intel_crtc->cursor_mem_argb.Key = -1; - - if (pI830->SWCursor) - return FALSE; - - /* - * Mouse cursor -- The i810-i830 need a physical address in system - * memory from which to upload the cursor. We get this from - * the agpgart module using a special memory type. - */ - - size = HWCURSOR_SIZE; - cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; - if (pI830->CursorNeedsPhysical) - cursFlags |= NEED_PHYSICAL_ADDR; - - alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem, - &pI830->StolenPool, size, - GTT_PAGE_SIZE, flags | cursFlags); - if (alloced < size || - (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem.Physical)) - { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW cursor space.\n"); - return FALSE; - } - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for HW cursor at 0x%lx", s, - alloced / 1024, intel_crtc->cursor_mem.Start); - if (pI830->CursorNeedsPhysical) { - xf86ErrorFVerb(verbosity, " (0x%08lx)", - intel_crtc->cursor_mem.Physical); - } - xf86ErrorFVerb(verbosity, "\n"); - } - - /* Allocate the ARGB cursor space. Its success is optional -- we won't set - * SWCursor if it fails. - */ - size = HWCURSOR_SIZE_ARGB; - cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; - if (pI830->CursorNeedsPhysical) - cursFlags |= NEED_PHYSICAL_ADDR; - - alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem_argb, - &pI830->StolenPool, size, - GTT_PAGE_SIZE, flags | cursFlags); - if (alloced < size || - (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem_argb.Physical)) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW (ARGB) cursor space.\n"); - } - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for HW (ARGB) cursor at 0x%lx", s, - alloced / 1024, intel_crtc->cursor_mem_argb.Start); - if (pI830->CursorNeedsPhysical) { - xf86ErrorFVerb(verbosity, " (0x%08lx)", - intel_crtc->cursor_mem_argb.Physical); - } - xf86ErrorFVerb(verbosity, "\n"); - } - - return FALSE; + ScrnInfoPtr pScrn = crtc->scrn; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + I830Ptr pI830 = I830PTR(pScrn); + long size; + int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; + + if (pI830->SWCursor) + return FALSE; + + /* Mouse cursor -- The i810-i830 need a physical address in system + * memory from which to upload the cursor. We get this from + * the agpgart module using a special memory type. + */ + + size = HWCURSOR_SIZE; + + if (intel_crtc->cursor_mem == NULL) { + intel_crtc->cursor_mem = i830_allocate_memory(pScrn, "HW cursor", + size, GTT_PAGE_SIZE, + flags); + if (intel_crtc->cursor_mem == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW cursor space.\n"); + return FALSE; + } + } + + if (intel_crtc->cursor_mem_argb == NULL) { + /* Allocate the ARGB cursor space. Its success is optional -- we won't + * set SWCursor if it fails. + */ + intel_crtc->cursor_mem_argb = i830_allocate_memory(pScrn, + "HW ARGB cursor", + HWCURSOR_SIZE_ARGB, + GTT_PAGE_SIZE, + flags); + if (intel_crtc->cursor_mem_argb == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW (ARGB) cursor space.\n"); + } + } + + return TRUE; } /* @@ -709,1245 +891,600 @@ I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags) * ring buffer, scratch memory, HW cursor. */ Bool -I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) +i830_allocate_2d_memory(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - long size, alloced; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - Bool tileable; - int align, alignflags, i; - - DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n", - BOOLTOSTRING(flags & ALLOC_INITIAL)); - - if (!pI830->StolenOnly && - (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AGP GART support is either not available or cannot " - "be used.\n" - "\tMake sure your kernel has agpgart support or has the\n" - "\tagpgart module loaded.\n"); - } - return FALSE; - } - - - /* - * The I830 is slightly different from the I830/I815, it has no - * dcache and it has stolen memory by default in its gtt. All - * additional memory must go after it. - */ - - DPRINTF(PFX, - "size == %luk (%lu bytes == pScrn->videoRam)\n" - "pI830->StolenSize == %luk (%lu bytes)\n", - pScrn->videoRam, pScrn->videoRam * 1024, - pI830->StolenPool.Free.Size / 1024, - pI830->StolenPool.Free.Size); - - if (flags & ALLOC_INITIAL) { - if (pI830->NeedRingBufferLow) - AllocateRingBuffer(pScrn, flags | FORCE_LOW); - - /* Unfortunately this doesn't run on the DRY_RUN pass because our - * second head hasn't been created yet..... */ - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { - I830EntPtr pI830Ent = pI830->entityPrivate; - I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); - - if (!I830AllocateFramebuffer(pI830Ent->pScrn_2, pI8302, - &pI830->FbMemBox2, - &pI830->FrontBuffer2, &pI830->StolenPool, - TRUE, flags)) - { - return FALSE; - } - } - if (!I830AllocateFramebuffer(pScrn, pI830, &pI830->FbMemBox, - &pI830->FrontBuffer, &pI830->StolenPool, - FALSE, flags)) - { - return FALSE; - } + I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + long size; + int i; + + if (!pI830->StolenOnly && + (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "AGP GART support is either not available or cannot " + "be used.\n" + "\tMake sure your kernel has agpgart support or has\n" + "\tthe agpgart module loaded.\n"); + return FALSE; + } -#ifdef I830_USE_EXA - if (pI830->useEXA) { - /* Default EXA to having 3 screens worth of offscreen memory space - * (for pixmaps), plus a double-buffered, 1920x1088 video's worth. - */ - size = 3 * pScrn->displayWidth * pI830->cpp * pScrn->virtualY; - size += 1920 * 1088 * 2 * 2; - size = ROUND_TO_PAGE(size); - - alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen), - &(pI830->StolenPool), size, 1, - flags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " - "offscreen memory. Not enough VRAM?\n"); - } - return FALSE; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocation of " - "EXA offscreen memory at 0x%lx, size %ld KB\n", - pI830->Offscreen.Start, pI830->Offscreen.Size/1024); - } - } - if (pI830->useEXA && IS_I965G(pI830)) { - memset(&(pI830->EXAStateMem), 0, sizeof(I830MemRange)); - pI830->EXAStateMem.Key = -1; - size = ROUND_TO_PAGE(EXA_LINEAR_EXTRA); - align = GTT_PAGE_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->EXAStateMem), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "G965: Failed to allocate exa state buffer space.\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the G965 exa state buffer at 0x%lx - 0x%lx.\n", s, - alloced / 1024, pI830->EXAStateMem.Start, pI830->EXAStateMem.End); - } -#endif - } else { - long lineSize; - long extra = 0; - long maxFb = 0; - - /* - * XXX Need to "free" up any 3D allocations if the DRI ended up - * and make them available for 2D. The best way to do this would - * be position all of those regions contiguously at the end of the - * StolenPool. - */ - extra = GetFreeSpace(pScrn); - - if (extra == 0) - return TRUE; - - maxFb = pI830->FrontBuffer.Size + extra; - lineSize = pScrn->displayWidth * pI830->cpp; - maxFb = ROUND_DOWN_TO(maxFb, lineSize); - if (maxFb > lineSize * MAX_2D_HEIGHT) - maxFb = lineSize * MAX_2D_HEIGHT; - if (0/*maxFb > pI830->FrontBuffer.Size*/) { - unsigned long oldsize; - /* - * Sanity check -- the fb should be the last thing allocated at - * the bottom of the stolen pool. - */ - if (pI830->StolenPool.Free.Start != pI830->FrontBuffer.End) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal error in I830Allocate2DMemory():\n\t" - "Framebuffer isn't the last allocation at the bottom" - " of StolenPool\n\t(%lx != %lx).\n", - pI830->FrontBuffer.End, - pI830->StolenPool.Free.Start); - return FALSE; - } - /* - * XXX Maybe should have a "Free" function. This should be - * the only place where a region is resized, and we know that - * the fb is always at the bottom of the aperture/stolen pool, - * and is the only region that is allocated bottom-up. - * Allowing for more general realloction would require a smarter - * allocation system. - */ - oldsize = pI830->FrontBuffer.Size; - pI830->StolenPool.Free.Size += pI830->FrontBuffer.Size; - pI830->StolenPool.Free.Start -= pI830->FrontBuffer.Size; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sUpdated framebuffer allocation size from %ld " - "to %ld kByte\n", s, oldsize / 1024, maxFb / 1024); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sUpdated pixmap cache from %ld scanlines to %ld " - "scanlines\n", s, - oldsize / lineSize - pScrn->virtualY, - maxFb / lineSize - pScrn->virtualY); - pI830->FbMemBox.y2 = maxFb / lineSize; - tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && - IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { - if (IS_I9XX(pI830)) - align = MB(1); - else - align = KB(512); - alignflags = ALIGN_BOTH_ENDS; - } else { - align = KB(64); - alignflags = 0; - } - alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), - &(pI830->StolenPool), maxFb, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < maxFb) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to re-allocate framebuffer\n"); - } - return FALSE; - } - } - return TRUE; - } - -#if REMAP_RESERVED - /* - * Allocate a dummy page to pass when attempting to rebind the - * pre-allocated region. - */ - if (!dryrun) { - memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy)); - pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); - pI830->Dummy.Offset = 0; - } -#endif + /* Allocate the ring buffer first, so it ends up in stolen mem. */ + i830_allocate_ringbuffer(pScrn); + + /* Next, allocate other fixed-size allocations we have. */ + if (!pI830->SWCursor) { + /* Allocate cursor memory */ + for (i = 0; i < xf86_config->num_crtc; i++) { + if (!i830_allocate_cursor_buffers(xf86_config->crtc[i]) && + !pI830->SWCursor) + { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Disabling HW cursor because the cursor memory " + "allocation failed.\n"); + pI830->SWCursor = TRUE; + break; + } + } + } - if (!pI830->SWCursor && !dryrun) { - for (i = 0; i < xf86_config->num_crtc; i++) { - if (!I830AllocateCursorBuffers(xf86_config->crtc[i], flags) && - pI830->SWCursor) - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Disabling HW cursor because the cursor memory " - "allocation failed.\n"); - pI830->SWCursor = TRUE; - break; - } - } - } + /* Space for the X Server's 3D context. 32k is fine for right now. */ + pI830->logical_context = i830_allocate_memory(pScrn, "logical 3D context", + KB(32), GTT_PAGE_SIZE, 0); + if (pI830->logical_context == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate logical context space.\n"); + return FALSE; + } #ifdef I830_XV - AllocateOverlay(pScrn, flags); + /* Allocate overlay register space and optional XAA linear allocator + * space. The second head in zaphod mode will share the space. + */ + if (I830IsPrimary(pScrn)) + i830_allocate_overlay(pScrn); #endif - if (!pI830->NeedRingBufferLow) - AllocateRingBuffer(pScrn, flags); - - /* Clear scratch info */ - memset(&(pI830->Scratch), 0, sizeof(I830MemRange)); - pI830->Scratch.Key = -1; - memset(&(pI830->Scratch2), 0, sizeof(I830MemRange)); - pI830->Scratch2.Key = -1; - - if (!pI830->noAccel) { - size = MAX_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), &(pI830->StolenPool), - size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - size = MIN_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), - &(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 scratch buffer space\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the scratch buffer at 0x%lx\n", s, - alloced / 1024, pI830->Scratch.Start); - - /* Let's allocate another scratch buffer for the second head */ - /* Again, this code won't execute on the dry run pass */ - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { - size = MAX_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2), - &(pI830->StolenPool), - size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - size = MIN_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2), - &(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 second scratch buffer space\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the second scratch buffer at 0x%lx\n", s, - alloced / 1024, pI830->Scratch2.Start); - } - } - - return TRUE; -} + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { + I830EntPtr pI830Ent = pI830->entityPrivate; + I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); -void -I830ResetAllocations(ScrnInfoPtr pScrn, const int flags) -{ - I830Ptr pI830 = I830PTR(pScrn); + pI830->front_buffer_2 = + i830_allocate_framebuffer(pI830Ent->pScrn_2, pI8302, + &pI830->FbMemBox2, TRUE, 0); + if (pI830->front_buffer_2 == NULL) + return FALSE; + } + pI830->front_buffer = + i830_allocate_framebuffer(pScrn, pI830, &pI830->FbMemBox, FALSE, 0); + if (pI830->front_buffer == NULL) + return FALSE; - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = pI830->FbMapSize; - pI830->MemoryAperture.Size = pI830->FbMapSize - pI830->StolenMemory.Size; -#ifdef XF86DRI - if (!pI830->directRenderingDisabled) { - pI830->MemoryAperture.End -= KB(pI830->mmSize); - pI830->MemoryAperture.Size -= KB(pI830->mmSize); - } -#endif - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenPool.Total; - pI830->FreeMemory = pI830->TotalVideoRam - pI830->StolenPool.Total.Size; - pI830->allocatedMemory = 0; -} +#ifdef I830_USE_EXA + if (pI830->useEXA) { + if (pI830->exa_offscreen == NULL) { + /* Default EXA to having 3 screens worth of offscreen memory space + * (for pixmaps), plus a double-buffered, 1920x1088 video's worth. + * + * XXX: It would be nice to auto-size it larger if the user + * specified a larger size, or to fit along with texture and FB + * memory if a low videoRam is specified. + */ + size = 3 * pitch * pScrn->virtualY; + size += 1920 * 1088 * 2 * 2; + size = ROUND_TO_PAGE(size); + + pI830->exa_offscreen = i830_allocate_memory(pScrn, "exa offscreen", + size, 1, 0); + if (pI830->exa_offscreen == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate EXA offscreen memory."); + return FALSE; + } + } + + if (IS_I965G(pI830) && pI830->exa_965_state == NULL) { + pI830->exa_965_state = + i830_allocate_memory(pScrn, "exa G965 state buffer", + EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0); + if (pI830->exa_965_state == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate exa state buffer for 965.\n"); + return FALSE; + } + } + } +#endif /* I830_USE_EXA */ + + if (!pI830->noAccel && !pI830->useEXA) { + pI830->xaa_scratch = + i830_allocate_memory(pScrn, "xaa scratch", MAX_SCRATCH_BUFFER_SIZE, + GTT_PAGE_SIZE, 0); + if (pI830->xaa_scratch == NULL) { + pI830->xaa_scratch = + i830_allocate_memory(pScrn, "xaa scratch", + MIN_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, + 0); + if (pI830->xaa_scratch == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate scratch buffer space\n"); + return FALSE; + } + } + + /* Let's allocate another scratch buffer for the second head */ + /* Again, this code won't execute on the dry run pass */ + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) + { + pI830->xaa_scratch_2 = + i830_allocate_memory(pScrn, "xaa scratch 2", + MAX_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, + 0); + if (pI830->xaa_scratch_2 == NULL) { + pI830->xaa_scratch_2 = + i830_allocate_memory(pScrn, "xaa scratch 2", + MIN_SCRATCH_BUFFER_SIZE, + GTT_PAGE_SIZE, 0); + if (pI830->xaa_scratch_2 == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate secondary scratch " + "buffer space\n"); + return FALSE; + } + } + } + } -long -I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - long allocated; - - allocated = pI830->StolenPool.Total.Size + pI830->allocatedMemory; - if (allocated > pI830->TotalVideoRam) - return allocated - pI830->TotalVideoRam; - else - return 0; + return TRUE; } #ifdef XF86DRI static unsigned int myLog2(unsigned int n) { - unsigned int log2 = 1; + unsigned int log2 = 1; - while (n > 1) { - n >>= 1; - log2++; - } - return log2; + while (n > 1) { + n >>= 1; + log2++; + } + return log2; } -Bool -I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags) +static Bool +i830_allocate_backbuffer(ScrnInfoPtr pScrn) { - 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; - - /* Back Buffer */ - memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); - pI830->BackBuffer.Key = -1; - tileable = !(flags & ALLOC_NO_TILING) && - IsTileable(pScrn, 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 >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) { - alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), - &(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->BackBuffer), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - } - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate back buffer space.\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the back buffer at 0x%lx.\n", s, - alloced / 1024, pI830->BackBuffer.Start); - - return TRUE; -} + I830Ptr pI830 = I830PTR(pScrn); + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + unsigned long size; + int height; + + if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) + height = pScrn->virtualY; + else + height = pScrn->virtualX; + + /* Try to allocate on the best tile-friendly boundaries. */ + if (!pI830->disableTiling && IsTileable(pScrn, pitch)) + { + size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); + pI830->back_buffer = + i830_allocate_memory_tiled(pScrn, "back buffer", + size, pitch, GTT_PAGE_SIZE, + ALIGN_BOTH_ENDS, + TILING_XMAJOR); + pI830->back_tiled = FENCE_XMAJOR; + } -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, 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 >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) { - alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), - &(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->DepthBuffer), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - } - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate depth buffer space.\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the depth buffer at 0x%lx.\n", s, - alloced / 1024, pI830->DepthBuffer.Start); - - return TRUE; -} + /* Otherwise, just allocate it linear */ + if (pI830->back_buffer == NULL) { + size = ROUND_TO_PAGE(pitch * height); + pI830->back_buffer = i830_allocate_memory(pScrn, "back buffer", + size, GTT_PAGE_SIZE, + ALIGN_BOTH_ENDS); + pI830->back_tiled = FENCE_LINEAR; + } -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)); - pI830->TexMem.Key = -1; - - if (pI830->mmModeFlags & I830_KERNEL_TEX) { - - if (dryrun && pI830->pEnt->device->videoRam == 0) { - /* If we're laying out a default-sized allocation, then don't be - * too greedy and just ask for 32MB. - */ - size = MB(32); - } else { - size = GetFreeSpace(pScrn); - } - if (dryrun && (size < MB(1))) - size = MB(1); - i = myLog2(size / I830_NR_TEX_REGIONS); - if (i < I830_LOG_MIN_TEX_REGION_SIZE) - i = I830_LOG_MIN_TEX_REGION_SIZE; - pI830->TexGranularity = i; - /* Truncate size */ - size >>= i; - size <<= i; - if (size < KB(512)) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Less than 512 kBytes for texture space (real %ld kBytes).\n", - size / 1024); - } - return FALSE; - } - alloced = I830AllocVidMem(pScrn, &(pI830->TexMem), - &(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 texture space.\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for textures at 0x%lx\n", s, - alloced / 1024, pI830->TexMem.Start); - } - - return TRUE; -} + if (pI830->back_buffer == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate back buffer space.\n"); + return FALSE; + } -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; + return TRUE; } -#endif -/* Allocate pool space that isn't pre-allocated */ -Bool -I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool) +static Bool +i830_allocate_depthbuffer(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); - - DPRINTF(PFX, "I830DoPoolAllocation\n"); - - if (!pool) - return FALSE; - - /* - * Sanity check: there shouldn't be an allocation required when - * there is only stolen memory. - */ - if (pI830->StolenOnly && (pool->Total.Size > pool->Fixed.Size)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "I830DoPoolAllocation(): pool size is greater than the " - "preallocated size,\n\t" - "and there is no allocatable memory.\n"); - return FALSE; - } - - 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); - if (pool->Allocated.Key == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n"); - return FALSE; - } - pool->Allocated.Start = pool->Fixed.End; - pool->Allocated.End = pool->Total.Size; - pool->Allocated.Offset = pool->Allocated.Start; - } else - pool->Allocated.Key = -1; - return TRUE; -} + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size; + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + int height; + + /* XXX: this rotation stuff is bogus */ + if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) + height = pScrn->virtualY; + else + height = pScrn->virtualX; + + /* First try allocating it tiled */ + if (!pI830->disableTiling && IsTileable(pScrn, pitch)) + { + size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); + + pI830->depth_buffer = + i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch, + GTT_PAGE_SIZE, ALIGN_BOTH_ENDS, + TILING_YMAJOR); + pI830->depth_tiled = FENCE_YMAJOR; + } -static unsigned long topOfMem = 0; + /* Otherwise, allocate it linear. */ + if (pI830->depth_buffer == NULL) { + size = ROUND_TO_PAGE(pitch * height); + pI830->depth_buffer = + i830_allocate_memory(pScrn, "depth buffer", size, GTT_PAGE_SIZE, + 0); + pI830->depth_tiled = FENCE_LINEAR; + } -/* - * These modify the way memory is positioned within the aperture. - * - * By default, memory allocated from the bottom or specifically within - * the pool at the bottom gets allocated from the "stolen pool", which is - * actually the stolen memory plus any extra allocated to make it a larger - * contiguous region. Memory allocated from the AGP is allocated top-down - * from the end of the aperture space. Memory allocated "from top" defaults - * to AGP if there is enough "free space". The total allocation (stolen + - * extra) doesn't exceed the orignal pScrn->videoRam amount (this isn't true - * when memory allocated from AGP gets moved into the pool by one of the - * following options. - * - * XXX Write a better description. - * - */ -#define PACK_RANGES 0 -#define POOL_RANGES 0 + if (pI830->depth_buffer == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate depth buffer space.\n"); + return FALSE; + } -Bool -I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem) + return TRUE; +} + +static Bool +i830_allocate_texture_memory(ScrnInfoPtr pScrn) { -#if POOL_RANGES - I830Ptr pI830 = I830PTR(pScrn); -#endif + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size; + int i; + + if (pI830->mmModeFlags & I830_KERNEL_MM) { + pI830->memory_manager = + i830_allocate_aperture(pScrn, "DRI memory manager", + pI830->mmSize * KB(1), GTT_PAGE_SIZE, + ALIGN_BOTH_ENDS); + /* XXX: try memory manager size backoff here? */ + if (pI830->memory_manager == NULL) + return FALSE; + } - if (!mem) - return FALSE; - - if (mem->Pool && mem->Key == -1 && mem->Start < 0) { - mem->Start = mem->Pool->Total.End + mem->Start; - mem->End = mem->Start + mem->Size; - } -#if PACK_RANGES - /* - * Map AGP-allocated areas at the top of the stolen area, resulting in - * a contiguous region in the aperture. Normally most AGP-allocated areas - * will be at the top of the aperture, making alignment requirements - * easier to achieve. This optin is primarily for debugging purposes, - * and using this option can break any special alignment requirements. - */ - if (!mem->Pool && mem->Start != 0 && mem->Key != -1 && mem->Physical == 0 && - mem->Offset != 0) { - long diff; - if (mem->Offset != mem->Start) - ErrorF("mem %p, Offset != Start\n", mem); - diff = mem->Offset - topOfMem; - mem->Start -= diff; - mem->End -= diff; - mem->Offset -= diff; - topOfMem += mem->Size; - } -#elif POOL_RANGES - /* - * Move AGP-allocated regions (that don't need a physical address) into - * the pre-allocated pool when there's enough space to do so. Note: the - * AGP-allocated areas aren't freed. This option is primarily for - * debugging purposes, and using it can break any special alignment - * requirements. - */ - if (!mem->Pool && mem->Start >= pI830->StolenPool.Free.End && - mem->Key != -1 && mem->Physical == 0 && mem->Offset != 0 && - pI830->StolenPool.Free.Size >= mem->Size) { - long diff; - if (mem->Offset != mem->Start) - ErrorF("mem %p, Offset != Start\n", mem); - diff = mem->Offset - pI830->StolenPool.Free.Start; - mem->Start -= diff; - mem->End -= diff; - mem->Offset -= diff; - mem->Key = -1; - pI830->StolenPool.Free.Start += mem->Size; - pI830->StolenPool.Free.Size -= mem->Size; - } -#endif - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%p: Memory at offset 0x%08lx, size %ld kBytes\n", (void *)mem, - mem->Start, mem->Size / 1024); - return TRUE; + if (pI830->mmModeFlags & I830_KERNEL_TEX) { + /* XXX: auto-sizing */ + size = MB(32); + i = myLog2(size / I830_NR_TEX_REGIONS); + if (i < I830_LOG_MIN_TEX_REGION_SIZE) + i = I830_LOG_MIN_TEX_REGION_SIZE; + pI830->TexGranularity = i; + /* Truncate size */ + size >>= i; + size <<= i; + if (size < KB(512)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Less than 512 kBytes for texture space (real %ld" + "kBytes).\n", + size / 1024); + return FALSE; + } + pI830->textures = i830_allocate_memory(pScrn, "textures", size, + GTT_PAGE_SIZE, 0); + if (pI830->textures == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate texture space.\n"); + return FALSE; + } + } + + return TRUE; } Bool -I830FixupOffsets(ScrnInfoPtr pScrn) +i830_allocate_3d_memory(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; + DPRINTF(PFX, "i830_allocate_3d_memory\n"); - DPRINTF(PFX, "I830FixupOffsets\n"); + if (!i830_allocate_backbuffer(pScrn)) + return FALSE; - topOfMem = pI830->StolenPool.Total.End; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - I830FixOffset(pScrn, &(pI830->FrontBuffer2)); - I830FixOffset(pScrn, &(pI830->FrontBuffer)); + if (!i830_allocate_depthbuffer(pScrn)) + return FALSE; - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + if (!i830_allocate_texture_memory(pScrn)) + return FALSE; - I830FixOffset(pScrn, &intel_crtc->cursor_mem); - I830FixOffset(pScrn, &intel_crtc->cursor_mem_argb); - } - - I830FixOffset(pScrn, &(pI830->LpRing->mem)); - I830FixOffset(pScrn, &(pI830->Scratch)); - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - I830FixOffset(pScrn, &(pI830->Scratch2)); -#ifdef I830_XV - if (pI830->XvEnabled) { - I830FixOffset(pScrn, pI830->OverlayMem); - if (pI830->LinearAlloc) - I830FixOffset(pScrn, &(pI830->LinearMem)); - } -#endif -#ifdef XF86DRI - if (pI830->directRenderingEnabled) { - I830FixOffset(pScrn, &(pI830->ContextMem)); - I830FixOffset(pScrn, &(pI830->BackBuffer)); - I830FixOffset(pScrn, &(pI830->DepthBuffer)); - if (pI830->mmModeFlags & I830_KERNEL_TEX) { - I830FixOffset(pScrn, &(pI830->TexMem)); - } - } -#endif -#ifdef I830_USE_EXA - if (pI830->useEXA) { - I830FixOffset(pScrn, &(pI830->Offscreen)); - if (IS_I965G(pI830)) - I830FixOffset(pScrn, &(pI830->EXAStateMem)); - } -#endif - return TRUE; + return TRUE; } +#endif #ifdef XF86DRI -/* Tiled memory is good... really, really good... +/** + * Sets up a fence area for the hardware. * - * Need to make it less likely that we miss out on this - probably - * need to move the frontbuffer away from the 'guarenteed' alignment - * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. + * The fences control automatic tiled address swizzling for CPU access of the + * framebuffer. */ static void -SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, - unsigned int size) +i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, + unsigned int pitch, unsigned int size, + enum tile_format tile_format) { - I830Ptr pI830 = I830PTR(pScrn); - I830RegPtr i830Reg = &pI830->ModeReg; - CARD32 val; - CARD32 fence_mask = 0; - unsigned int fence_pitch; + I830Ptr pI830 = I830PTR(pScrn); + CARD32 val; + CARD32 fence_mask = 0; + unsigned int fence_pitch; + + DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n", + nr, offset, pitch, size / 1024); + + assert(tile_format != TILING_NONE); + + if (IS_I965G(pI830)) { + if (nr < 0 || nr >= FENCE_NEW_NR) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "i830_set_fence(): fence %d out of range\n",nr); + return; + } + + switch (tile_format) { + case TILING_XMAJOR: + pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1; + pI830->fence[nr] |= I965_FENCE_X_MAJOR; + break; + case TILING_YMAJOR: + /* YMajor can be 128B aligned but the current code dictates + * otherwise. This isn't a problem apart from memory waste. + * FIXME */ + pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1; + pI830->fence[nr] |= I965_FENCE_Y_MAJOR; + break; + case TILING_NONE: + break; + } - DPRINTF(PFX, "SetFence: %d, 0x%08x, %d, %d kByte\n", - nr, start, pitch, size / 1024); + /* The end marker is the address of the last page in the allocation. */ + pI830->fence[FENCE_NEW_NR + nr] = offset + size - 4096; + return; + } - if (nr < 0 || nr > 7) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: fence %d out of range\n",nr); - return; - } + if (nr < 0 || nr >= FENCE_NR) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "i830_set_fence(): fence %d out of range\n",nr); + return; + } - i830Reg->Fence[nr] = 0; + pI830->fence[nr] = 0; - if (IS_I9XX(pI830)) + if (IS_I9XX(pI830)) fence_mask = ~I915G_FENCE_START_MASK; - else + else fence_mask = ~I830_FENCE_START_MASK; - if (start & fence_mask) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); - return; - } - - if (start % size) { - 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(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", - nr, pitch); - return; - } - - val = (start | FENCE_X_MAJOR | FENCE_VALID); - - if (IS_I9XX(pI830)) { + if (offset & fence_mask) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "i830_set_fence(): %d: offset (0x%08x) is not %s aligned\n", + nr, offset, (IS_I9XX(pI830)) ? "1MB" : "512k"); + return; + } + + if (offset % size) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "i830_set_fence(): %d: offset (0x%08x) is not size (%dk) " + "aligned\n", + nr, offset, size / 1024); + return; + } + + if (pitch & 127) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "i830_set_fence(): %d: pitch (%d) not a multiple of 128 " + "bytes\n", + nr, pitch); + return; + } + + val = offset | FENCE_VALID; + + switch (tile_format) { + case TILING_XMAJOR: + val |= FENCE_X_MAJOR; + break; + case TILING_YMAJOR: + val |= FENCE_Y_MAJOR; + break; + case TILING_NONE: + break; + } + + if (IS_I9XX(pI830)) { switch (size) { - case MB(1): - val |= I915G_FENCE_SIZE_1M; - break; - case MB(2): - val |= I915G_FENCE_SIZE_2M; - break; - case MB(4): - val |= I915G_FENCE_SIZE_4M; - break; - case MB(8): - val |= I915G_FENCE_SIZE_8M; - break; - case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; - case MB(32): - val |= I915G_FENCE_SIZE_32M; - break; - case MB(64): - val |= I915G_FENCE_SIZE_64M; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; + case MB(1): + val |= I915G_FENCE_SIZE_1M; + break; + case MB(2): + val |= I915G_FENCE_SIZE_2M; + break; + case MB(4): + val |= I915G_FENCE_SIZE_4M; + break; + case MB(8): + val |= I915G_FENCE_SIZE_8M; + break; + case MB(16): + val |= I915G_FENCE_SIZE_16M; + break; + case MB(32): + val |= I915G_FENCE_SIZE_32M; + break; + case MB(64): + val |= I915G_FENCE_SIZE_64M; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "i830_set_fence(): %d: illegal size (%d kByte)\n", + nr, size / 1024); + return; } } else { switch (size) { - case KB(512): - val |= FENCE_SIZE_512K; - break; - case MB(1): - val |= FENCE_SIZE_1M; - break; - case MB(2): - val |= FENCE_SIZE_2M; - break; - case MB(4): - val |= FENCE_SIZE_4M; - break; - case MB(8): - val |= FENCE_SIZE_8M; - break; - case MB(16): - val |= FENCE_SIZE_16M; - break; - case MB(32): - val |= FENCE_SIZE_32M; - break; - case MB(64): - val |= FENCE_SIZE_64M; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; + case KB(512): + val |= FENCE_SIZE_512K; + break; + case MB(1): + val |= FENCE_SIZE_1M; + break; + case MB(2): + val |= FENCE_SIZE_2M; + break; + case MB(4): + val |= FENCE_SIZE_4M; + break; + case MB(8): + val |= FENCE_SIZE_8M; + break; + case MB(16): + val |= FENCE_SIZE_16M; + break; + case MB(32): + val |= FENCE_SIZE_32M; + break; + case MB(64): + val |= FENCE_SIZE_64M; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "i830_set_fence(): %d: illegal size (%d kByte)\n", + nr, size / 1024); + return; } - } + } - if (IS_I9XX(pI830)) + if (IS_I9XX(pI830)) fence_pitch = pitch / 512; - else + else fence_pitch = pitch / 128; - switch (fence_pitch) { - case 1: - val |= FENCE_PITCH_1; - break; - case 2: - val |= FENCE_PITCH_2; - break; - case 4: - val |= FENCE_PITCH_4; - break; - case 8: - val |= FENCE_PITCH_8; - break; - case 16: - val |= FENCE_PITCH_16; - break; - case 32: - val |= FENCE_PITCH_32; - break; - case 64: - val |= FENCE_PITCH_64; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: illegal pitch (%d)\n", nr, pitch); - return; - } - - i830Reg->Fence[nr] = val; -} - -static Bool -MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem, unsigned int fence) -{ - I830Ptr pI830 = I830PTR(pScrn); - int pitch, ntiles, i; - -#if 0 - /* Hack to "improve" the alignment of the front buffer. - */ - while (!(pMem->Start & ~pMem->Alignment) && pMem->Alignment < 0x00400000 ) - pMem->Alignment <<= 1; -#endif - - if (tileGeneration != serverGeneration) { - tileGeneration = serverGeneration; - nextTile = 0; - } - - pitch = pScrn->displayWidth * pI830->cpp; - - if (IS_I965G(pI830)) { - I830RegPtr i830Reg = &pI830->ModeReg; - - switch (fence) { - case FENCE_XMAJOR: - i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1; - break; - case FENCE_YMAJOR: - /* YMajor can be 128B aligned but the current code dictates - * otherwise. This isn't a problem apart from memory waste. - * FIXME */ - i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1; - i830Reg->Fence[nextTile] |= (1<<1); - break; - default: - case FENCE_LINEAR: - break; - } - - i830Reg->Fence[nextTile+FENCE_NEW_NR] = pMem->End; - nextTile++; - return TRUE; - } - - /* - * Simply try to break the region up into at most four pieces of size - * equal to the alignment. - */ - ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) { - return FALSE; - } - - for (i = 0; i < ntiles; i++, nextTile++) { - SetFence(pScrn, nextTile, pMem->Start + i * pMem->Alignment, - pitch, pMem->Alignment); - } - return TRUE; -} - -void -I830SetupMemoryTiling(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int i; - - /* Clear out */ - if (IS_I965G(pI830)) { - for (i = 0; i < FENCE_NEW_NR*2; i++) - pI830->ModeReg.Fence[i] = 0; - } else { - 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) - return; - - if (!IsTileable(pScrn, pScrn->displayWidth * pI830->cpp)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "I830SetupMemoryTiling: Not tileable 0x%x\n", - pScrn->displayWidth * pI830->cpp); - pI830->allowPageFlip = FALSE; - return; - } - - pI830->front_tiled = FENCE_LINEAR; - pI830->back_tiled = FENCE_LINEAR; - pI830->depth_tiled = FENCE_LINEAR; - - if (pI830->allowPageFlip) { - if (pI830->allowPageFlip && pI830->FrontBuffer.Alignment >= KB(512)) { - if (MakeTiles(pScrn, &(pI830->FrontBuffer), FENCE_XMAJOR)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Activating tiled memory for the front buffer\n"); - pI830->front_tiled = FENCE_XMAJOR; - } else { - pI830->allowPageFlip = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MakeTiles failed for the front buffer\n"); - } - } else { - pI830->allowPageFlip = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Alignment bad for the front buffer\n"); - } - } - - /* - * We tried to get the best alignment during the allocation. Check - * the alignment values to tell. If well-aligned allocations were - * successful, the address range reserved is a multiple of the align - * value. - */ - if (pI830->BackBuffer.Alignment >= KB(512)) { - if (MakeTiles(pScrn, &(pI830->BackBuffer), FENCE_XMAJOR)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Activating tiled memory for the back buffer.\n"); - pI830->back_tiled = FENCE_XMAJOR; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MakeTiles failed for the back buffer.\n"); - pI830->allowPageFlip = FALSE; - } - } - - if (pI830->DepthBuffer.Alignment >= KB(512)) { - if (MakeTiles(pScrn, &(pI830->DepthBuffer), FENCE_YMAJOR)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Activating tiled memory for the depth buffer.\n"); - pI830->depth_tiled = FENCE_YMAJOR; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MakeTiles failed for the depth buffer.\n"); - } - }} -#endif /* XF86DRI */ - -static Bool -BindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; + switch (fence_pitch) { + case 1: + val |= FENCE_PITCH_1; + break; + case 2: + val |= FENCE_PITCH_2; + break; + case 4: + val |= FENCE_PITCH_4; + break; + case 8: + val |= FENCE_PITCH_8; + break; + case 16: + val |= FENCE_PITCH_16; + break; + case 32: + val |= FENCE_PITCH_32; + break; + case 64: + val |= FENCE_PITCH_64; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "i830_set_fence(): %d: illegal pitch (%d)\n", nr, pitch); + return; + } - return xf86BindGARTMemory(pScrn->scrnIndex, mem->Key, mem->Offset); + pI830->fence[nr] = val; } +#endif +/** + * Called at EnterVT to grab the AGP GART and bind our allocations. + * + * In zaphod mode, this will walk the list trying to bind twice, since each + * pI830 points to the same allocation list, but the bind_memory will just + * no-op then. + */ Bool -I830BindAGPMemory(ScrnInfoPtr pScrn) +i830_bind_all_memory(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); - - DPRINTF(PFX, - "I830BindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n", - BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound)); + I830Ptr pI830 = I830PTR(pScrn); - if (pI830->StolenOnly == TRUE) - return TRUE; + if (pI830->StolenOnly == TRUE || pI830->memory_list == NULL) + return TRUE; - if (xf86AgpGARTSupported() && !pI830->GttBound) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; + if (xf86AgpGARTSupported() && !pI830->gtt_acquired) { + i830_memory *mem; - if (!xf86AcquireGART(pScrn->scrnIndex)) - return FALSE; - -#if REMAP_RESERVED - /* Rebind the pre-allocated region. */ - BindMemRange(pScrn, &(pI830->Dummy)); -#endif - - if (!BindMemRange(pScrn, &(pI830->StolenPool.Allocated))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!BindMemRange(pScrn, &(pI830->FrontBuffer2))) + if (!xf86AcquireGART(pScrn->scrnIndex)) return FALSE; - if (!BindMemRange(pScrn, &(pI830->FrontBuffer))) - return FALSE; - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + pI830->gtt_acquired = TRUE; - if (!BindMemRange(pScrn, &intel_crtc->cursor_mem)) - return FALSE; - if (!BindMemRange(pScrn, &intel_crtc->cursor_mem_argb)) - return FALSE; - } - if (!BindMemRange(pScrn, &(pI830->LpRing->mem))) - return FALSE; - if (!BindMemRange(pScrn, &(pI830->Scratch))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!BindMemRange(pScrn, &(pI830->Scratch2))) - return FALSE; -#ifdef I830_XV - if (pI830->XvEnabled) { - if (!BindMemRange(pScrn, pI830->OverlayMem)) - return FALSE; - if (pI830->LinearAlloc) - if (!BindMemRange(pScrn, &(pI830->LinearMem))) - return FALSE; - } -#endif -#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 ((pI830->mmModeFlags & I830_KERNEL_TEX) && - !BindMemRange(pScrn, &(pI830->TexMem))) - return FALSE; - } -#endif -#ifdef I830_USE_EXA - if (pI830->useEXA) { - if (!BindMemRange(pScrn, &(pI830->Offscreen))) - return FALSE; - if (IS_I965G(pI830) && !BindMemRange(pScrn, &(pI830->EXAStateMem))) - return FALSE; - } -#endif - pI830->GttBound = 1; - } - - return TRUE; -} - -static Bool -UnbindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; + for (mem = pI830->memory_list->next; mem->next != NULL; + mem = mem->next) + { + if (!i830_bind_memory(pScrn, mem)) { + /* This shouldn't happen */ + FatalError("Couldn't bind memory for %s\n", mem->name); + } + } + } - return xf86UnbindGARTMemory(pScrn->scrnIndex, mem->Key); + return TRUE; } - +/** Called at LeaveVT, to unbind all of our AGP allocations. */ Bool -I830UnbindAGPMemory(ScrnInfoPtr pScrn) +i830_unbind_all_memory(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); - DPRINTF(PFX, - "I830UnbindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n", - BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound)); + if (pI830->StolenOnly == TRUE) + return TRUE; - if (pI830->StolenOnly == TRUE) - return TRUE; + if (xf86AgpGARTSupported() && pI830->gtt_acquired) { + i830_memory *mem; - if (xf86AgpGARTSupported() && pI830->GttBound) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; + for (mem = pI830->memory_list->next; mem->next != NULL; + mem = mem->next) + { + i830_unbind_memory(pScrn, mem); + } -#if REMAP_RESERVED - /* "unbind" the pre-allocated region. */ - UnbindMemRange(pScrn, &(pI830->Dummy)); -#endif - - if (!UnbindMemRange(pScrn, &(pI830->StolenPool.Allocated))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer2))) - return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer))) - return FALSE; + pI830->gtt_acquired = FALSE; - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; - - if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem)) - return FALSE; - if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem_argb)) - return FALSE; - } - - if (!UnbindMemRange(pScrn, &(pI830->LpRing->mem))) - return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->Scratch))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!UnbindMemRange(pScrn, &(pI830->Scratch2))) - return FALSE; -#ifdef I830_XV - if (pI830->XvEnabled) { - if (!UnbindMemRange(pScrn, pI830->OverlayMem)) - return FALSE; - if (pI830->LinearAlloc) - if (!UnbindMemRange(pScrn, &(pI830->LinearMem))) - return FALSE; - } -#endif -#ifdef XF86DRI - if (pI830->directRenderingEnabled) { - if (!UnbindMemRange(pScrn, &(pI830->ContextMem))) - return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->BackBuffer))) + if (!xf86ReleaseGART(pScrn->scrnIndex)) return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->DepthBuffer))) - return FALSE; - if ((pI830->mmModeFlags & I830_KERNEL_TEX) && - !UnbindMemRange(pScrn, &(pI830->TexMem))) - return FALSE; - } -#endif -#ifdef I830_USE_EXA - if (pI830->useEXA) { - if (!UnbindMemRange(pScrn, &(pI830->Offscreen))) - return FALSE; - if (IS_I965G(pI830) && !UnbindMemRange(pScrn, &(pI830->EXAStateMem))) - return FALSE; - } -#endif - if (!xf86ReleaseGART(pScrn->scrnIndex)) - return FALSE; - - pI830->GttBound = 0; - } + } - return TRUE; + return TRUE; } +/** + * Returns the amount of system memory that could potentially be allocated + * from AGP, in kB. + */ long I830CheckAvailableMemory(ScrnInfoPtr pScrn) { - AgpInfoPtr agpinf; - int maxPages; + AgpInfoPtr agpinf; + int maxPages; - if (!xf86AgpGARTSupported() || - !xf86AcquireGART(pScrn->scrnIndex) || - (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL || - !xf86ReleaseGART(pScrn->scrnIndex)) - return -1; + if (!xf86AgpGARTSupported() || + !xf86AcquireGART(pScrn->scrnIndex) || + (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL || + !xf86ReleaseGART(pScrn->scrnIndex)) + return -1; - maxPages = agpinf->totalPages - agpinf->usedPages; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n", - "I830CheckAvailableMemory", maxPages * 4); + maxPages = agpinf->totalPages - agpinf->usedPages; + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n", + "I830CheckAvailableMemory", maxPages * 4); - return maxPages * 4; + return maxPages * 4; } #ifdef I830_USE_XAA @@ -1962,28 +1499,28 @@ i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length, RemoveLinearCallbackProcPtr removeCB, pointer privData) { - FBLinearPtr linear; - int max_size; + FBLinearPtr linear; + int max_size; - linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, - removeCB, privData); - if (linear != NULL) - return linear; + linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, + removeCB, privData); + if (linear != NULL) + return linear; - /* The above allocation didn't succeed, so purge unlocked stuff and try - * again. - */ - xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity, - PRIORITY_EXTREME); + /* The above allocation didn't succeed, so purge unlocked stuff and try + * again. + */ + xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity, + PRIORITY_EXTREME); - if (max_size < length) - return NULL; + if (max_size < length) + return NULL; - xf86PurgeUnlockedOffscreenAreas(pScreen); + xf86PurgeUnlockedOffscreenAreas(pScreen); - linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, - removeCB, privData); + linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, + removeCB, privData); - return linear; + return linear; } #endif diff --git a/src/i830_modes.c b/src/i830_modes.c index 405dcc61..06921a50 100644 --- a/src/i830_modes.c +++ b/src/i830_modes.c @@ -52,7 +52,7 @@ #include "X11/Xatom.h" #include "i830.h" #include "i830_display.h" -#include "i830_xf86Modes.h" +#include "xf86Modes.h" #include <randrstr.h> DisplayModePtr diff --git a/src/i830_randr.c b/src/i830_randr.c deleted file mode 100644 index 5eccf4bd..00000000 --- a/src/i830_randr.c +++ /dev/null @@ -1,950 +0,0 @@ -/* $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 the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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 <X11/extensions/render.h> - -#include "i830_xf86Crtc.h" -#include "i830_randr.h" -#include "i830_debug.h" -#include "i830_display.h" -#include "i830.h" - -typedef struct _xf86RandR12Info { - int virtualX; - int virtualY; - int mmWidth; - int mmHeight; - int maxX; - int maxY; - Rotation rotation; /* current mode */ - Rotation supported_rotations; /* driver supported */ -} XF86RandRInfoRec, *XF86RandRInfoPtr; - -#ifdef RANDR_12_INTERFACE -static Bool xf86RandR12Init12 (ScreenPtr pScreen); -static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen); -#endif - -static int xf86RandR12Index; -static int xf86RandR12Generation; - -#define XF86RANDRINFO(p) \ - ((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr) - -static int -xf86RandR12ModeRefresh (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 -xf86RandR12GetInfo (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; - } - - /* Re-probe the outputs for new monitors or modes */ - xf86ProbeOutputModes (scrp, 0, 0); - xf86SetScrnInfoModes (scrp); - I830DGAReInit (pScreen); - - for (mode = scrp->modes; ; mode = mode->next) - { - int refresh = xf86RandR12ModeRefresh (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 (xf86ModesEqual(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) - { - 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 -xf86RandR12SetMode (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 -xf86RandR12SetConfig (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 || xf86RandR12ModeRefresh (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 (!xf86RandR12SetMode (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; -} - -static Bool -xf86RandR12ScreenSetSize (ScreenPtr pScreen, - CARD16 width, - CARD16 height, - CARD32 mmWidth, - CARD32 mmHeight) -{ - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); - WindowPtr pRoot = WindowTable[pScreen->myNum]; - Bool ret = TRUE; - - if (randrp->virtualX == -1 || randrp->virtualY == -1) - { - randrp->virtualX = pScrn->virtualX; - randrp->virtualY = pScrn->virtualY; - } - if (pRoot) - (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE); - pScrn->virtualX = width; - pScrn->virtualY = height; - - pScreen->width = pScrn->virtualX; - pScreen->height = pScrn->virtualY; - pScreen->mmWidth = mmWidth; - pScreen->mmHeight = mmHeight; - - xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1); - xf86SetViewport (pScreen, 0, 0); - if (pRoot) - (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE); -#if RANDR_12_INTERFACE - if (WindowTable[pScreen->myNum]) - RRScreenSizeNotify (pScreen); -#endif - return ret; -} - -Rotation -xf86RandR12GetRotation(ScreenPtr pScreen) -{ - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - - return randrp->rotation; -} - -Bool -xf86RandR12CreateScreenResources (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - int c; - int width, height; - int mmWidth, mmHeight; -#ifdef PANORAMIX - /* XXX disable RandR when using Xinerama */ - if (!noPanoramiXExtension) - return TRUE; -#endif - - /* - * Compute size of screen - */ - width = 0; height = 0; - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - int crtc_width = crtc->x + crtc->mode.HDisplay; - int crtc_height = crtc->y + crtc->mode.VDisplay; - - if (crtc->enabled && crtc_width > width) - width = crtc_width; - if (crtc->enabled && crtc_height > height) - height = crtc_height; - } - - if (width && height) - { - /* - * Compute physical size of screen - */ - if (monitorResolution) - { - mmWidth = width * 25.4 / monitorResolution; - mmHeight = height * 25.4 / monitorResolution; - } - else - { - mmWidth = pScreen->mmWidth; - mmHeight = pScreen->mmHeight; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Setting screen physical size to %d x %d\n", - mmWidth, mmHeight); - xf86RandR12ScreenSetSize (pScreen, - width, - height, - mmWidth, - mmHeight); - } - - if (randrp->virtualX == -1 || randrp->virtualY == -1) - { - randrp->virtualX = pScrn->virtualX; - randrp->virtualY = pScrn->virtualY; - } -#if RANDR_12_INTERFACE - if (xf86RandR12CreateScreenResources12 (pScreen)) - return TRUE; -#endif - return TRUE; -} - - -Bool -xf86RandR12Init (ScreenPtr pScreen) -{ - rrScrPrivPtr rp; - XF86RandRInfoPtr randrp; - -#ifdef PANORAMIX - /* XXX disable RandR when using Xinerama */ - if (!noPanoramiXExtension) - return TRUE; -#endif - if (xf86RandR12Generation != serverGeneration) - { - xf86RandR12Index = AllocateScreenPrivateIndex(); - xf86RandR12Generation = serverGeneration; - } - - randrp = xalloc (sizeof (XF86RandRInfoRec)); - if (!randrp) - return FALSE; - - if (!RRScreenInit(pScreen)) - { - xfree (randrp); - return FALSE; - } - rp = rrGetScrPriv(pScreen); - rp->rrGetInfo = xf86RandR12GetInfo; - rp->rrSetConfig = xf86RandR12SetConfig; - - 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 = RR_Rotate_0; - - randrp->maxX = randrp->maxY = 0; - - pScreen->devPrivates[xf86RandR12Index].ptr = randrp; - -#if RANDR_12_INTERFACE - if (!xf86RandR12Init12 (pScreen)) - return FALSE; -#endif - return TRUE; -} - -void -xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations) -{ - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - int c; - - randrp->supported_rotations = rotations; - -#if RANDR_12_INTERFACE - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - - RRCrtcSetRotations (crtc->randr_crtc, rotations); - } -#endif -} - -void -xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y) -{ - ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; - - if (xf86RandR12Generation != serverGeneration || - XF86RANDRINFO(pScreen)->virtualX == -1) - { - *x = pScrn->virtualX; - *y = pScrn->virtualY; - } else { - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - - *x = randrp->virtualX; - *y = randrp->virtualY; - } -} - -#if RANDR_12_INTERFACE -static Bool -xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc) -{ - ScreenPtr pScreen = randr_crtc->pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - RRModePtr randr_mode = NULL; - int x; - int y; - Rotation rotation; - int numOutputs; - RROutputPtr *randr_outputs; - RROutputPtr randr_output; - xf86CrtcPtr crtc = randr_crtc->devPrivate; - xf86OutputPtr output; - int i, j; - DisplayModePtr mode = &crtc->mode; - Bool ret; - - randr_outputs = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr)); - if (!randr_outputs) - return FALSE; - x = crtc->x; - y = crtc->y; - rotation = crtc->rotation; - numOutputs = 0; - randr_mode = NULL; - for (i = 0; i < config->num_output; i++) - { - output = config->output[i]; - if (output->crtc == crtc) - { - randr_output = output->randr_output; - randr_outputs[numOutputs++] = randr_output; - /* - * We make copies of modes, so pointer equality - * isn't sufficient - */ - for (j = 0; j < randr_output->numModes; j++) - { - DisplayModePtr outMode = randr_output->modes[j]->devPrivate; - if (xf86ModesEqual(mode, outMode)) - { - randr_mode = randr_output->modes[j]; - break; - } - } - } - } - ret = RRCrtcNotify (randr_crtc, randr_mode, x, y, - rotation, numOutputs, randr_outputs); - DEALLOCATE_LOCAL(randr_outputs); - return ret; -} - -static Bool -xf86RandR12CrtcSet (ScreenPtr pScreen, - RRCrtcPtr randr_crtc, - RRModePtr randr_mode, - int x, - int y, - Rotation rotation, - int num_randr_outputs, - RROutputPtr *randr_outputs) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - xf86CrtcPtr crtc = randr_crtc->devPrivate; - DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL; - Bool changed = FALSE; - int o, ro; - xf86CrtcPtr *save_crtcs; - Bool save_enabled = crtc->enabled; - - save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr)); - if ((mode != NULL) != crtc->enabled) - changed = TRUE; - else if (mode && !xf86ModesEqual (&crtc->mode, mode)) - changed = TRUE; - - if (x != crtc->x || y != crtc->y) - changed = TRUE; - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - xf86CrtcPtr new_crtc; - - save_crtcs[o] = output->crtc; - - if (output->crtc == crtc) - new_crtc = NULL; - else - new_crtc = output->crtc; - for (ro = 0; ro < num_randr_outputs; ro++) - if (output->randr_output == randr_outputs[ro]) - { - new_crtc = crtc; - break; - } - if (new_crtc != output->crtc) - { - changed = TRUE; - output->crtc = new_crtc; - } - } - /* XXX need device-independent mode setting code through an API */ - if (changed) - { - crtc->enabled = mode != NULL; - - if (mode) - { - if (!xf86CrtcSetMode (crtc, mode, rotation, x, y)) - { - crtc->enabled = save_enabled; - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - output->crtc = save_crtcs[o]; - } - DEALLOCATE_LOCAL(save_crtcs); - return FALSE; - } - /* - * Save the last successful setting for EnterVT - */ - crtc->desiredMode = *mode; - crtc->desiredRotation = rotation; - crtc->desiredX = x; - crtc->desiredY = y; - } - xf86DisableUnusedFunctions (pScrn); - } - DEALLOCATE_LOCAL(save_crtcs); - return xf86RandR12CrtcNotify (randr_crtc); -} - -static Bool -xf86RandR12CrtcSetGamma (ScreenPtr pScreen, - RRCrtcPtr randr_crtc) -{ - xf86CrtcPtr crtc = randr_crtc->devPrivate; - - if (crtc->funcs->gamma_set == NULL) - return FALSE; - - crtc->funcs->gamma_set(crtc, randr_crtc->gammaRed, randr_crtc->gammaGreen, - randr_crtc->gammaBlue, randr_crtc->gammaSize); - - return TRUE; -} - -static Bool -xf86RandR12OutputSetProperty (ScreenPtr pScreen, - RROutputPtr randr_output, - Atom property, - RRPropertyValuePtr value) -{ - xf86OutputPtr output = randr_output->devPrivate; - - /* If we don't have any property handler, then we don't care what the - * user is setting properties to. - */ - if (output->funcs->set_property == NULL) - return TRUE; - - return output->funcs->set_property(output, property, value); -} - -/** - * Given a list of xf86 modes and a RandR Output object, construct - * RandR modes and assign them to the output - */ -static Bool -xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes) -{ - DisplayModePtr mode; - RRModePtr *rrmodes = NULL; - int nmode = 0; - int npreferred = 0; - Bool ret = TRUE; - int pref; - - for (mode = modes; mode; mode = mode->next) - nmode++; - - if (nmode) { - rrmodes = xalloc (nmode * sizeof (RRModePtr)); - - if (!rrmodes) - return FALSE; - nmode = 0; - - for (pref = 1; pref >= 0; pref--) { - for (mode = modes; mode; mode = mode->next) { - if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) { - xRRModeInfo modeInfo; - RRModePtr rrmode; - - modeInfo.nameLength = strlen (mode->name); - modeInfo.width = mode->HDisplay; - modeInfo.dotClock = mode->Clock * 1000; - modeInfo.hSyncStart = mode->HSyncStart; - modeInfo.hSyncEnd = mode->HSyncEnd; - modeInfo.hTotal = mode->HTotal; - modeInfo.hSkew = mode->HSkew; - - modeInfo.height = mode->VDisplay; - modeInfo.vSyncStart = mode->VSyncStart; - modeInfo.vSyncEnd = mode->VSyncEnd; - modeInfo.vTotal = mode->VTotal; - modeInfo.modeFlags = mode->Flags; - - rrmode = RRModeGet (&modeInfo, mode->name); - if (rrmode) { - rrmode->devPrivate = mode; - rrmodes[nmode++] = rrmode; - npreferred += pref; - } - } - } - } - } - - ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred); - xfree (rrmodes); - return ret; -} - -/* - * Mirror the current mode configuration to RandR - */ -static Bool -xf86RandR12SetInfo12 (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - RROutputPtr *clones; - RRCrtcPtr *crtcs; - int ncrtc; - int o, c, l; - RRCrtcPtr randr_crtc; - int nclone; - - clones = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr)); - crtcs = ALLOCATE_LOCAL (config->num_crtc * sizeof (RRCrtcPtr)); - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - ncrtc = 0; - for (c = 0; c < config->num_crtc; c++) - if (output->possible_crtcs & (1 << c)) - crtcs[ncrtc++] = config->crtc[c]->randr_crtc; - - if (output->crtc) - randr_crtc = output->crtc->randr_crtc; - else - randr_crtc = NULL; - - if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc)) - { - DEALLOCATE_LOCAL (crtcs); - DEALLOCATE_LOCAL (clones); - return FALSE; - } - - RROutputSetCrtc (output->randr_output, randr_crtc); - RROutputSetPhysicalSize(output->randr_output, - output->mm_width, - output->mm_height); - xf86RROutputSetModes (output->randr_output, output->probed_modes); - - switch (output->status) { - case XF86OutputStatusConnected: - RROutputSetConnection (output->randr_output, RR_Connected); - break; - case XF86OutputStatusDisconnected: - RROutputSetConnection (output->randr_output, RR_Disconnected); - break; - case XF86OutputStatusUnknown: - RROutputSetConnection (output->randr_output, RR_UnknownConnection); - break; - } - - RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order); - - /* - * Valid clones - */ - nclone = 0; - for (l = 0; l < config->num_output; l++) - { - xf86OutputPtr clone = config->output[l]; - - if (l != o && (output->possible_clones & (1 << l))) - clones[nclone++] = clone->randr_output; - } - if (!RROutputSetClones (output->randr_output, clones, nclone)) - { - DEALLOCATE_LOCAL (crtcs); - DEALLOCATE_LOCAL (clones); - return FALSE; - } - } - DEALLOCATE_LOCAL (crtcs); - DEALLOCATE_LOCAL (clones); - return TRUE; -} - - - -/* - * Query the hardware for the current state, then mirror - * that to RandR - */ -static Bool -xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - - xf86ProbeOutputModes (pScrn, 0, 0); - xf86SetScrnInfoModes (pScrn); - I830DGAReInit (pScreen); - return xf86RandR12SetInfo12 (pScreen); -} - -static Bool -xf86RandR12CreateObjects12 (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - int c; - int o; - - if (!RRInit ()) - return FALSE; - - /* - * Configure crtcs - */ - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - - crtc->randr_crtc = RRCrtcCreate (crtc); - RRCrtcAttachScreen (crtc->randr_crtc, pScreen); - RRCrtcGammaSetSize (crtc->randr_crtc, 256); - } - /* - * Configure outputs - */ - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - output->randr_output = RROutputCreate (output->name, - strlen (output->name), - output); - RROutputAttachScreen (output->randr_output, pScreen); - - if (output->funcs->create_resources != NULL) - output->funcs->create_resources(output); - } - return TRUE; -} - -static Bool -xf86RandR12CreateScreenResources12 (ScreenPtr pScreen) -{ - int c; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - - for (c = 0; c < config->num_crtc; c++) - xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc); - - - RRScreenSetSizeRange (pScreen, 320, 240, - randrp->virtualX, randrp->virtualY); - return TRUE; -} - -static void -xf86RandR12PointerMoved (int scrnIndex, int x, int y) -{ -} - -static Bool -xf86RandR12Init12 (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - rrScrPrivPtr rp = rrGetScrPriv(pScreen); - - rp->rrGetInfo = xf86RandR12GetInfo12; - rp->rrScreenSetSize = xf86RandR12ScreenSetSize; - rp->rrCrtcSet = xf86RandR12CrtcSet; - rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma; - rp->rrOutputSetProperty = xf86RandR12OutputSetProperty; - rp->rrSetConfig = NULL; - pScrn->PointerMoved = xf86RandR12PointerMoved; - if (!xf86RandR12CreateObjects12 (pScreen)) - return FALSE; - - /* - * Configure output modes - */ - if (!xf86RandR12SetInfo12 (pScreen)) - return FALSE; - return TRUE; -} - -#endif - -Bool -xf86RandR12PreInit (ScrnInfoPtr pScrn) -{ - return TRUE; -} diff --git a/src/i830_randr.h b/src/i830_randr.h deleted file mode 100644 index 8a4668b4..00000000 --- a/src/i830_randr.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright © 2006 Keith Packard - * - * 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 the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifndef _XF86_RANDR_H_ -#define _XF86_RANDR_H_ -#include <randrstr.h> -#include <X11/extensions/render.h> - -Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen); -Bool xf86RandR12Init(ScreenPtr pScreen); -void xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotation); -Bool xf86RandR12SetConfig(ScreenPtr pScreen, Rotation rotation, int rate, - RRScreenSizePtr pSize); -Rotation xf86RandR12GetRotation(ScreenPtr pScreen); -void xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y); -Bool xf86RandR12PreInit (ScrnInfoPtr pScrn); - -#endif /* _XF86_RANDR_H_ */ diff --git a/src/i830_render.c b/src/i830_render.c index 99338439..49d8fc11 100644 --- a/src/i830_render.c +++ b/src/i830_render.c @@ -557,17 +557,17 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, OUT_RING(PRIM3D_INLINE | PRIM3D_RECTLIST | (vertex_count-1)); - OUT_RING_F(dstX); - OUT_RING_F(dstY); - OUT_RING_F(src_x[0] / pI830->scale_units[0][0]); - OUT_RING_F(src_y[0] / pI830->scale_units[0][1]); + OUT_RING_F(-0.125 + dstX + w); + OUT_RING_F(-0.125 + dstY + h); + OUT_RING_F(src_x[2] / pI830->scale_units[0][0]); + OUT_RING_F(src_y[2] / pI830->scale_units[0][1]); if (has_mask) { - OUT_RING_F(mask_x[0] / pI830->scale_units[1][0]); - OUT_RING_F(mask_y[0] / pI830->scale_units[1][1]); + OUT_RING_F(mask_x[2] / pI830->scale_units[1][0]); + OUT_RING_F(mask_y[2] / pI830->scale_units[1][1]); } - OUT_RING_F(dstX); - OUT_RING_F(dstY + h); + OUT_RING_F(-0.125 + dstX); + OUT_RING_F(-0.125 + dstY + h); OUT_RING_F(src_x[1] / pI830->scale_units[0][0]); OUT_RING_F(src_y[1] / pI830->scale_units[0][1]); if (has_mask) { @@ -575,13 +575,13 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, OUT_RING_F(mask_y[1] / pI830->scale_units[1][1]); } - OUT_RING_F(dstX + w); - OUT_RING_F(dstY + h); - OUT_RING_F(src_x[2] / pI830->scale_units[0][0]); - OUT_RING_F(src_y[2] / pI830->scale_units[0][1]); + OUT_RING_F(-0.125 + dstX); + OUT_RING_F(-0.125 + dstY); + OUT_RING_F(src_x[0] / pI830->scale_units[0][0]); + OUT_RING_F(src_y[0] / pI830->scale_units[0][1]); if (has_mask) { - OUT_RING_F(mask_x[2] / pI830->scale_units[1][0]); - OUT_RING_F(mask_y[2] / pI830->scale_units[1][1]); + OUT_RING_F(mask_x[0] / pI830->scale_units[1][0]); + OUT_RING_F(mask_y[0] / pI830->scale_units[1][1]); } ADVANCE_LP_RING(); } diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index ea62ad96..46a35f1c 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -1079,8 +1079,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) char *name_prefix; char *name_suffix; - output = xf86OutputCreate (pScrn, &i830_sdvo_output_funcs, - "ADD2 PCIE card"); + output = xf86OutputCreate (pScrn, &i830_sdvo_output_funcs,NULL); if (!output) return; intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) + diff --git a/src/i830_video.c b/src/i830_video.c index 22f5bee4..e580dab5 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -184,9 +184,9 @@ void exaMoveInPixmap (PixmapPtr pPixmap); OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \ } \ if (IS_I965G(pI830)) \ - OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); \ + OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE); \ else \ - OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \ + OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE); \ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ OUT_RING(MI_NOOP); \ ADVANCE_LP_RING(); \ @@ -202,9 +202,9 @@ void exaMoveInPixmap (PixmapPtr pPixmap); OUT_RING(MI_NOOP); \ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF); \ if (IS_I965G(pI830)) \ - OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); \ + OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE); \ else \ - OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \ + OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE); \ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ OUT_RING(MI_NOOP); \ ADVANCE_LP_RING(); \ @@ -472,7 +472,9 @@ I830InitVideo(ScreenPtr pScreen) } /* Set up overlay video if we can do it at this depth. */ - if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8) { + if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8 && + pI830->overlay_regs != NULL) + { overlayAdaptor = I830SetupImageVideoOverlay(pScreen); if (overlayAdaptor != NULL) { adaptors[num_adaptors++] = overlayAdaptor; @@ -496,10 +498,10 @@ I830ResetVideo(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); OVERLAY_DEBUG("I830ResetVideo: base: %p, offset: 0x%lx, obase: %p\n", - pI830->FbBase, pI830->OverlayMem->Start, overlay); + pI830->FbBase, pI830->overlay_regs->offset, overlay); /* * Default to maximum image size in YV12 */ @@ -925,8 +927,7 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, { I830PortPrivPtr pPriv = (I830PortPrivPtr) data; I830Ptr pI830 = I830PTR(pScrn); - I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + I830OverlayRegPtr overlay; if (pPriv->textured) { /* XXX: Currently the brightness/saturation attributes aren't hooked up. @@ -936,6 +937,8 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, return Success; } + overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); + if (attribute == xvBrightness) { if ((value < -128) || (value > 127)) return BadValue; @@ -1553,7 +1556,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); unsigned int swidth; unsigned int mask, shift, offsety, offsetu; int tmp; @@ -2076,7 +2079,8 @@ I830AllocateMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear, int size, /* Converts an offset from XAA's linear allocator to an offset from the * start of fb. */ -#define XAA_OFFSET_TO_OFFSET(x) (pI830->FrontBuffer.Start + (x * pI830->cpp)) +#define XAA_OFFSET_TO_OFFSET(x) \ + (pI830->front_buffer->offset + (x * pI830->cpp)) /* The XFree86 linear allocator operates in units of screen pixels, * sadly. @@ -2159,8 +2163,7 @@ I830PutImage(ScrnInfoPtr pScrn, I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = (I830PortPrivPtr) data; ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; - I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + I830OverlayRegPtr overlay; PixmapPtr pPixmap; INT32 x1, x2, y1, y2; int srcPitch, srcPitch2 = 0, dstPitch, destId; @@ -2169,6 +2172,12 @@ I830PutImage(ScrnInfoPtr pScrn, int pitchAlignMask; int extraLinear; + if (pPriv->textured) + overlay = NULL; + else + overlay = (I830OverlayRegPtr) (pI830->FbBase + + pI830->overlay_regs->offset); + #if 0 ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n" "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y, @@ -2700,7 +2709,7 @@ I830DisplaySurface(XF86SurfacePtr surface, I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn); I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); INT32 x1, y1, x2, y2; INT32 loops = 0; BoxRec dstBox; diff --git a/src/i830_xaa.c b/src/i830_xaa.c index 5ef5d3c4..f0951387 100644 --- a/src/i830_xaa.c +++ b/src/i830_xaa.c @@ -162,20 +162,20 @@ I830XAAInit(ScreenPtr pScreen) /* On the primary screen */ if (pI830->init == 0) { - if (pI830->Scratch.Size != 0) { + if (pI830->xaa_scratch->size != 0) { width = ((pScrn->displayWidth + 31) & ~31) / 8; - nr_buffers = pI830->Scratch.Size / width; - ptr = pI830->FbBase + pI830->Scratch.Start; + nr_buffers = pI830->xaa_scratch->size / width; + ptr = pI830->FbBase + pI830->xaa_scratch->offset; } } else { /* On the secondary screen */ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - if (pI8301->Scratch2.Size != 0) { + if (pI8301->xaa_scratch_2->size != 0) { width = ((pScrn->displayWidth + 31) & ~31) / 8; - nr_buffers = pI8301->Scratch2.Size / width; + nr_buffers = pI8301->xaa_scratch_2->size / width; /* We have to use the primary screen's FbBase, as that's where - * we allocated Scratch2, so we get the correct pointer */ - ptr = pI8301->FbBase + pI8301->Scratch2.Start; + * we allocated xaa_scratch_2, so we get the correct pointer */ + ptr = pI8301->FbBase + pI8301->xaa_scratch_2->offset; } } @@ -279,11 +279,15 @@ CheckTiling(ScrnInfoPtr pScrn) if (IS_I965G(pI830)) { if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR) tiled = 1; - if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR) + if (pI830->bufferOffset == pI830->back_buffer->offset && + pI830->back_tiled == FENCE_XMAJOR) { tiled = 1; + } /* not really supported as it's always YMajor tiled */ - if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR) + if (pI830->bufferOffset == pI830->depth_buffer->offset && + pI830->depth_tiled == FENCE_XMAJOR) { tiled = 1; + } } return tiled; @@ -600,7 +604,7 @@ I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); /* We have to use the primary screen's FbBase, as that's where - * we allocated Scratch2, so we get the correct pointer */ + * we allocated xaa_scratch_2, so we get the correct pointer */ pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - pI8301->FbBase); } @@ -700,7 +704,7 @@ I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); /* We have to use the primary screen's FbBase, as that's where - * we allocated Scratch2, so we get the correct pointer */ + * we allocated xaa_scratch_2, so we get the correct pointer */ pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - pI8301->FbBase); } diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h deleted file mode 100644 index 6de2c923..00000000 --- a/src/i830_xf86Crtc.h +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright © 2006 Keith Packard - * - * 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 the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ -#ifndef _XF86CRTC_H_ -#define _XF86CRTC_H_ - -#include <edid.h> -#include "randrstr.h" -#include "i830_xf86Rename.h" -#include "i830_xf86Modes.h" -#include "xf86Parser.h" -#include "damage.h" - -/* Compat definitions for older X Servers. */ -#ifndef M_T_PREFERRED -#define M_T_PREFERRED 0x08 -#endif -#ifndef M_T_DRIVER -#define M_T_DRIVER 0x40 -#endif - -typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr; -typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr; - -typedef enum _xf86OutputStatus { - XF86OutputStatusConnected, - XF86OutputStatusDisconnected, - XF86OutputStatusUnknown, -} xf86OutputStatus; - -typedef struct _xf86CrtcFuncs { - /** - * Turns the crtc on/off, or sets intermediate power levels if available. - * - * Unsupported intermediate modes drop to the lower power setting. If the - * mode is DPMSModeOff, the crtc must be disabled sufficiently for it to - * be safe to call mode_set. - */ - void - (*dpms)(xf86CrtcPtr crtc, - int mode); - - /** - * Saves the crtc's state for restoration on VT switch. - */ - void - (*save)(xf86CrtcPtr crtc); - - /** - * Restore's the crtc's state at VT switch. - */ - void - (*restore)(xf86CrtcPtr crtc); - - /** - * Lock CRTC prior to mode setting, mostly for DRI. - * Returns whether unlock is needed - */ - Bool - (*lock) (xf86CrtcPtr crtc); - - /** - * Unlock CRTC after mode setting, mostly for DRI - */ - void - (*unlock) (xf86CrtcPtr crtc); - - /** - * Callback to adjust the mode to be set in the CRTC. - * - * This allows a CRTC to adjust the clock or even the entire set of - * timings, which is used for panels with fixed timings or for - * buses with clock limitations. - */ - Bool - (*mode_fixup)(xf86CrtcPtr crtc, - DisplayModePtr mode, - DisplayModePtr adjusted_mode); - - /** - * Callback for setting up a video mode after fixups have been made. - */ - void - (*mode_set)(xf86CrtcPtr crtc, - DisplayModePtr mode, - DisplayModePtr adjusted_mode, - int x, int y); - - /* Set the color ramps for the CRTC to the given values. */ - void - (*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, - int size); - - /** - * Create shadow pixmap for rotation support - */ - PixmapPtr - (*shadow_create) (xf86CrtcPtr crtc, int width, int height); - - /** - * Destroy shadow pixmap - */ - void - (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap); - - /** - * Clean up driver-specific bits of the crtc - */ - void - (*destroy) (xf86CrtcPtr crtc); -} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr; - -struct _xf86Crtc { - /** - * Associated ScrnInfo - */ - ScrnInfoPtr scrn; - - /** - * Active state of this CRTC - * - * Set when this CRTC is driving one or more outputs - */ - Bool enabled; - - /** Track whether cursor is within CRTC range */ - Bool cursorInRange; - - /** Track state of cursor associated with this CRTC */ - Bool cursorShown; - - /** - * Active mode - * - * This reflects the mode as set in the CRTC currently - * It will be cleared when the VT is not active or - * during server startup - */ - DisplayModeRec mode; - Rotation rotation; - PixmapPtr rotatedPixmap; - /** - * Position on screen - * - * Locates this CRTC within the frame buffer - */ - int x, y; - - /** - * Desired mode - * - * This is set to the requested mode, independent of - * whether the VT is active. In particular, it receives - * the startup configured mode and saves the active mode - * on VT switch. - */ - DisplayModeRec desiredMode; - Rotation desiredRotation; - int desiredX, desiredY; - - /** crtc-specific functions */ - const xf86CrtcFuncsRec *funcs; - - /** - * Driver private - * - * Holds driver-private information - */ - void *driver_private; - -#ifdef RANDR_12_INTERFACE - /** - * RandR crtc - * - * When RandR 1.2 is available, this - * points at the associated crtc object - */ - RRCrtcPtr randr_crtc; -#else - void *randr_crtc; -#endif -}; - -typedef struct _xf86OutputFuncs { - /** - * Called to allow the output a chance to create properties after the - * RandR objects have been created. - */ - void - (*create_resources)(xf86OutputPtr output); - - /** - * Turns the output on/off, or sets intermediate power levels if available. - * - * Unsupported intermediate modes drop to the lower power setting. If the - * mode is DPMSModeOff, the output must be disabled, as the DPLL may be - * disabled afterwards. - */ - void - (*dpms)(xf86OutputPtr output, - int mode); - - /** - * Saves the output's state for restoration on VT switch. - */ - void - (*save)(xf86OutputPtr output); - - /** - * Restore's the output's state at VT switch. - */ - void - (*restore)(xf86OutputPtr output); - - /** - * Callback for testing a video mode for a given output. - * - * This function should only check for cases where a mode can't be supported - * on the output specifically, and not represent generic CRTC limitations. - * - * \return MODE_OK if the mode is valid, or another MODE_* otherwise. - */ - int - (*mode_valid)(xf86OutputPtr output, - DisplayModePtr pMode); - - /** - * Callback to adjust the mode to be set in the CRTC. - * - * This allows an output to adjust the clock or even the entire set of - * timings, which is used for panels with fixed timings or for - * buses with clock limitations. - */ - Bool - (*mode_fixup)(xf86OutputPtr output, - DisplayModePtr mode, - DisplayModePtr adjusted_mode); - - /** - * Callback for setting up a video mode after fixups have been made. - * - * This is only called while the output is disabled. The dpms callback - * must be all that's necessary for the output, to turn the output on - * after this function is called. - */ - void - (*mode_set)(xf86OutputPtr output, - DisplayModePtr mode, - DisplayModePtr adjusted_mode); - - /** - * Probe for a connected output, and return detect_status. - */ - xf86OutputStatus - (*detect)(xf86OutputPtr output); - - /** - * Query the device for the modes it provides. - * - * This function may also update MonInfo, mm_width, and mm_height. - * - * \return singly-linked list of modes or NULL if no modes found. - */ - DisplayModePtr - (*get_modes)(xf86OutputPtr output); - -#ifdef RANDR_12_INTERFACE - /** - * Callback when an output's property has changed. - */ - Bool - (*set_property)(xf86OutputPtr output, - Atom property, - RRPropertyValuePtr value); -#endif - /** - * Clean up driver-specific bits of the output - */ - void - (*destroy) (xf86OutputPtr output); -} xf86OutputFuncsRec, *xf86OutputFuncsPtr; - -struct _xf86Output { - /** - * Associated ScrnInfo - */ - ScrnInfoPtr scrn; - - /** - * Currently connected crtc (if any) - * - * If this output is not in use, this field will be NULL. - */ - xf86CrtcPtr crtc; - - /** - * Possible CRTCs for this output as a mask of crtc indices - */ - CARD32 possible_crtcs; - - /** - * Possible outputs to share the same CRTC as a mask of output indices - */ - CARD32 possible_clones; - - /** - * Whether this output can support interlaced modes - */ - Bool interlaceAllowed; - - /** - * Whether this output can support double scan modes - */ - Bool doubleScanAllowed; - - /** - * List of available modes on this output. - * - * This should be the list from get_modes(), plus perhaps additional - * compatible modes added later. - */ - DisplayModePtr probed_modes; - - /** - * Options parsed from the related monitor section - */ - OptionInfoPtr options; - - /** - * Configured monitor section - */ - XF86ConfMonitorPtr conf_monitor; - - /** - * Desired initial position - */ - int initial_x, initial_y; - - /** - * Current connection status - * - * This indicates whether a monitor is known to be connected - * to this output or not, or whether there is no way to tell - */ - xf86OutputStatus status; - - /** EDID monitor information */ - xf86MonPtr MonInfo; - - /** subpixel order */ - int subpixel_order; - - /** Physical size of the currently attached output device. */ - int mm_width, mm_height; - - /** Output name */ - char *name; - - /** output-specific functions */ - const xf86OutputFuncsRec *funcs; - - /** driver private information */ - void *driver_private; - -#ifdef RANDR_12_INTERFACE - /** - * RandR 1.2 output structure. - * - * When RandR 1.2 is available, this points at the associated - * RandR output structure and is created when this output is created - */ - RROutputPtr randr_output; -#else - void *randr_output; -#endif -}; - -typedef struct _xf86CrtcConfig { - int num_output; - xf86OutputPtr *output; - /** - * compat_output is used whenever we deal - * with legacy code that only understands a single - * output. pScrn->modes will be loaded from this output, - * adjust frame will whack this output, etc. - */ - int compat_output; - - int num_crtc; - xf86CrtcPtr *crtc; - - int minWidth, minHeight; - int maxWidth, maxHeight; - - /* For crtc-based rotation */ - DamagePtr rotationDamage; - - /* DGA */ - unsigned int dga_flags; - -} xf86CrtcConfigRec, *xf86CrtcConfigPtr; - -extern int xf86CrtcConfigPrivateIndex; - -#define XF86_CRTC_CONFIG_PTR(p) ((xf86CrtcConfigPtr) ((p)->privates[xf86CrtcConfigPrivateIndex].ptr)) - -/* - * Initialize xf86CrtcConfig structure - */ - -void -xf86CrtcConfigInit (ScrnInfoPtr scrn); - -void -xf86CrtcSetSizeRange (ScrnInfoPtr scrn, - int minWidth, int minHeight, - int maxWidth, int maxHeight); - -/* - * Crtc functions - */ -xf86CrtcPtr -xf86CrtcCreate (ScrnInfoPtr scrn, - const xf86CrtcFuncsRec *funcs); - -void -xf86CrtcDestroy (xf86CrtcPtr crtc); - - -/** - * Allocate a crtc for the specified output - * - * Find a currently unused CRTC which is suitable for - * the specified output - */ - -xf86CrtcPtr -xf86AllocCrtc (xf86OutputPtr output); - -/** - * Free a crtc - * - * Mark the crtc as unused by any outputs - */ - -void -xf86FreeCrtc (xf86CrtcPtr crtc); - -/** - * Sets the given video mode on the given crtc - */ -Bool -xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, - int x, int y); - -/* - * Assign crtc rotation during mode set - */ -Bool -xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation); - -/** - * Return whether any output is assigned to the crtc - */ -Bool -xf86CrtcInUse (xf86CrtcPtr crtc); - -/* - * Output functions - */ -xf86OutputPtr -xf86OutputCreate (ScrnInfoPtr scrn, - const xf86OutputFuncsRec *funcs, - const char *name); - -Bool -xf86OutputRename (xf86OutputPtr output, const char *name); - -void -xf86OutputDestroy (xf86OutputPtr output); - -void -xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY); - -void -xf86SetScrnInfoModes (ScrnInfoPtr pScrn); - -Bool -xf86InitialConfiguration (ScrnInfoPtr pScrn); - -void -xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); - -Bool -xf86SaveScreen(ScreenPtr pScreen, int mode); - -void -xf86DisableUnusedFunctions(ScrnInfoPtr pScrn); - -/** - * Set the EDID information for the specified output - */ -void -xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon); - -/** - * Return the list of modes supported by the EDID information - * stored in 'output' - */ -DisplayModePtr -xf86OutputGetEDIDModes (xf86OutputPtr output); - -xf86MonPtr -xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus); - -#endif /* _XF86CRTC_H_ */ diff --git a/src/i830_xf86Modes.c b/src/i830_xf86Modes.c deleted file mode 100644 index f620d4d5..00000000 --- a/src/i830_xf86Modes.c +++ /dev/null @@ -1,636 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ -/* $XdotOrg: xserver/xorg/hw/xfree86/common/xf86Mode.c,v 1.10 2006/03/07 16:00:57 libv Exp $ */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Mode.c,v 1.69 2003/10/08 14:58:28 dawes Exp $ */ -/* - * Copyright (c) 1997-2003 by The XFree86 Project, Inc. - * - * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - * - * Except as contained in this notice, the name of the copyright holder(s) - * and author(s) shall not be used in advertising or otherwise to promote - * the sale, use or other dealings in this Software without prior written - * authorization from the copyright holder(s) and author(s). - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stddef.h> -#include <string.h> -#include <stdio.h> - -#include "xf86.h" -#include "i830.h" -#include "i830_xf86Modes.h" -#include "xf86Priv.h" - -extern XF86ConfigPtr xf86configptr; - -/** - * @file this file contains symbols from xf86Mode.c and friends that are static - * there but we still want to use. We need to come up with better API here. - */ - -#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) -/** - * Calculates the horizontal sync rate of a mode. - * - * Exact copy of xf86Mode.c's. - */ -double -xf86ModeHSync(DisplayModePtr mode) -{ - double hsync = 0.0; - - if (mode->HSync > 0.0) - hsync = mode->HSync; - else if (mode->HTotal > 0) - hsync = (float)mode->Clock / (float)mode->HTotal; - - return hsync; -} - -/** - * Calculates the vertical refresh rate of a mode. - * - * Exact copy of xf86Mode.c's. - */ -double -xf86ModeVRefresh(DisplayModePtr mode) -{ - double refresh = 0.0; - - if (mode->VRefresh > 0.0) - refresh = mode->VRefresh; - else if (mode->HTotal > 0 && mode->VTotal > 0) { - refresh = mode->Clock * 1000.0 / mode->HTotal / mode->VTotal; - if (mode->Flags & V_INTERLACE) - refresh *= 2.0; - if (mode->Flags & V_DBLSCAN) - refresh /= 2.0; - if (mode->VScan > 1) - refresh /= (float)(mode->VScan); - } - return refresh; -} - -/** Sets a default mode name of <width>x<height> on a mode. */ -void -xf86SetModeDefaultName(DisplayModePtr mode) -{ - if (mode->name != NULL) - xfree(mode->name); - - mode->name = XNFprintf("%dx%d", mode->HDisplay, mode->VDisplay); -} - -/* - * xf86SetModeCrtc - * - * Initialises the Crtc parameters for a mode. The initialisation includes - * adjustments for interlaced and double scan modes. - * - * Exact copy of xf86Mode.c's. - */ -void -xf86SetModeCrtc(DisplayModePtr p, int adjustFlags) -{ - if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN)) - return; - - p->CrtcHDisplay = p->HDisplay; - p->CrtcHSyncStart = p->HSyncStart; - p->CrtcHSyncEnd = p->HSyncEnd; - p->CrtcHTotal = p->HTotal; - p->CrtcHSkew = p->HSkew; - p->CrtcVDisplay = p->VDisplay; - p->CrtcVSyncStart = p->VSyncStart; - p->CrtcVSyncEnd = p->VSyncEnd; - p->CrtcVTotal = p->VTotal; - if (p->Flags & V_INTERLACE) { - if (adjustFlags & INTERLACE_HALVE_V) { - p->CrtcVDisplay /= 2; - p->CrtcVSyncStart /= 2; - p->CrtcVSyncEnd /= 2; - p->CrtcVTotal /= 2; - } - /* Force interlaced modes to have an odd VTotal */ - /* maybe we should only do this when INTERLACE_HALVE_V is set? */ - p->CrtcVTotal |= 1; - } - - if (p->Flags & V_DBLSCAN) { - p->CrtcVDisplay *= 2; - p->CrtcVSyncStart *= 2; - p->CrtcVSyncEnd *= 2; - p->CrtcVTotal *= 2; - } - if (p->VScan > 1) { - p->CrtcVDisplay *= p->VScan; - p->CrtcVSyncStart *= p->VScan; - p->CrtcVSyncEnd *= p->VScan; - p->CrtcVTotal *= p->VScan; - } - p->CrtcVBlankStart = min(p->CrtcVSyncStart, p->CrtcVDisplay); - p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal); - p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay); - p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal); - - p->CrtcHAdjusted = FALSE; - p->CrtcVAdjusted = FALSE; -} - -/** - * Allocates and returns a copy of pMode, including pointers within pMode. - */ -DisplayModePtr -xf86DuplicateMode(DisplayModePtr pMode) -{ - DisplayModePtr pNew; - - pNew = xnfalloc(sizeof(DisplayModeRec)); - *pNew = *pMode; - pNew->next = NULL; - pNew->prev = NULL; - if (pNew->name == NULL) { - xf86SetModeDefaultName(pMode); - } else { - pNew->name = xnfstrdup(pMode->name); - } - - return pNew; -} - -/** - * Duplicates every mode in the given list and returns a pointer to the first - * mode. - * - * \param modeList doubly-linked mode list - */ -DisplayModePtr -xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList) -{ - DisplayModePtr first = NULL, last = NULL; - DisplayModePtr mode; - - for (mode = modeList; mode != NULL; mode = mode->next) { - DisplayModePtr new; - - new = xf86DuplicateMode(mode); - - /* Insert pNew into modeList */ - if (last) { - last->next = new; - new->prev = last; - } else { - first = new; - new->prev = NULL; - } - new->next = NULL; - last = new; - } - - return first; -} - -/** - * Returns true if the given modes should program to the same timings. - * - * This doesn't use Crtc values, as it might be used on ModeRecs without the - * Crtc values set. So, it's assumed that the other numbers are enough. - * - * This isn't in xf86Modes.c, but it might deserve to be there. - */ -Bool -xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2) -{ - if (pMode1->Clock == pMode2->Clock && - pMode1->HDisplay == pMode2->HDisplay && - pMode1->HSyncStart == pMode2->HSyncStart && - pMode1->HSyncEnd == pMode2->HSyncEnd && - pMode1->HTotal == pMode2->HTotal && - pMode1->HSkew == pMode2->HSkew && - pMode1->VDisplay == pMode2->VDisplay && - pMode1->VSyncStart == pMode2->VSyncStart && - pMode1->VSyncEnd == pMode2->VSyncEnd && - pMode1->VTotal == pMode2->VTotal && - pMode1->VScan == pMode2->VScan && - pMode1->Flags == pMode2->Flags) - { - return TRUE; - } else { - return FALSE; - } -} - -/* exact copy of xf86Mode.c */ -static void -add(char **p, char *new) -{ - *p = xnfrealloc(*p, strlen(*p) + strlen(new) + 2); - strcat(*p, " "); - strcat(*p, new); -} - -/** - * Print out a modeline. - * - * Convenient VRefresh printing was added, though, compared to xf86Mode.c - */ -void -xf86PrintModeline(int scrnIndex,DisplayModePtr mode) -{ - char tmp[256]; - char *flags = xnfcalloc(1, 1); - - if (mode->HSkew) { - snprintf(tmp, 256, "hskew %i", mode->HSkew); - add(&flags, tmp); - } - if (mode->VScan) { - snprintf(tmp, 256, "vscan %i", mode->VScan); - add(&flags, tmp); - } - if (mode->Flags & V_INTERLACE) add(&flags, "interlace"); - if (mode->Flags & V_CSYNC) add(&flags, "composite"); - if (mode->Flags & V_DBLSCAN) add(&flags, "doublescan"); - if (mode->Flags & V_BCAST) add(&flags, "bcast"); - if (mode->Flags & V_PHSYNC) add(&flags, "+hsync"); - if (mode->Flags & V_NHSYNC) add(&flags, "-hsync"); - if (mode->Flags & V_PVSYNC) add(&flags, "+vsync"); - if (mode->Flags & V_NVSYNC) add(&flags, "-vsync"); - if (mode->Flags & V_PCSYNC) add(&flags, "+csync"); - if (mode->Flags & V_NCSYNC) add(&flags, "-csync"); -#if 0 - if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2"); -#endif - xf86DrvMsg(scrnIndex, X_INFO, - "Modeline \"%s\"x%.01f %6.2f %i %i %i %i %i %i %i %i%s " - "(%.01f kHz)\n", - mode->name, mode->VRefresh, mode->Clock/1000., mode->HDisplay, - mode->HSyncStart, mode->HSyncEnd, mode->HTotal, - mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, - mode->VTotal, flags, xf86ModeHSync(mode)); - xfree(flags); -} -#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */ - -/** - * Marks as bad any modes with unsupported flags. - * - * \param modeList doubly-linked or circular list of modes. - * \param flags flags supported by the driver. - * - * \bug only V_INTERLACE and V_DBLSCAN are supported. Is that enough? - * - * This is not in xf86Modes.c, but would be part of the proposed new API. - */ -void -xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int flags) -{ - DisplayModePtr mode; - - for (mode = modeList; mode != NULL; mode = mode->next) { - if (mode->Flags & V_INTERLACE && !(flags & V_INTERLACE)) - mode->status = MODE_NO_INTERLACE; - if (mode->Flags & V_DBLSCAN && !(flags & V_DBLSCAN)) - mode->status = MODE_NO_DBLESCAN; - } -} - -/** - * Marks as bad any modes extending beyond the given max X, Y, or pitch. - * - * \param modeList doubly-linked or circular list of modes. - * - * This is not in xf86Modes.c, but would be part of the proposed new API. - */ -void -xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int maxX, int maxY, int maxPitch) -{ - DisplayModePtr mode; - - for (mode = modeList; mode != NULL; mode = mode->next) { - if (maxPitch > 0 && mode->HDisplay > maxPitch) - mode->status = MODE_BAD_WIDTH; - - if (maxX > 0 && mode->HDisplay > maxX) - mode->status = MODE_VIRTUAL_X; - - if (maxY > 0 && mode->VDisplay > maxY) - mode->status = MODE_VIRTUAL_Y; - - if (mode->next == modeList) - break; - } -} - -/** - * Marks as bad any modes that aren't supported by the given monitor's - * hsync and vrefresh ranges. - * - * \param modeList doubly-linked or circular list of modes. - * - * This is not in xf86Modes.c, but would be part of the proposed new API. - */ -void -xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, - MonPtr mon) -{ - DisplayModePtr mode; - - for (mode = modeList; mode != NULL; mode = mode->next) { - Bool bad; - int i; - - bad = TRUE; - for (i = 0; i < mon->nHsync; i++) { - if (xf86ModeHSync(mode) >= mon->hsync[i].lo && - xf86ModeHSync(mode) <= mon->hsync[i].hi) - { - bad = FALSE; - } - } - if (bad) - mode->status = MODE_HSYNC; - - bad = TRUE; - for (i = 0; i < mon->nVrefresh; i++) { - if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo && - xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi) - { - bad = FALSE; - } - } - if (bad) - mode->status = MODE_VSYNC; - - if (mode->next == modeList) - break; - } -} - -/** - * Marks as bad any modes extending beyond outside of the given clock ranges. - * - * \param modeList doubly-linked or circular list of modes. - * \param min pointer to minimums of clock ranges - * \param max pointer to maximums of clock ranges - * \param n_ranges number of ranges. - * - * This is not in xf86Modes.c, but would be part of the proposed new API. - */ -void -xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int *min, int *max, int n_ranges) -{ - DisplayModePtr mode; - int i; - - for (mode = modeList; mode != NULL; mode = mode->next) { - Bool good = FALSE; - for (i = 0; i < n_ranges; i++) { - if (mode->Clock >= min[i] && mode->Clock <= max[i]) { - good = TRUE; - break; - } - } - if (!good) - mode->status = MODE_CLOCK_RANGE; - } -} - -/** - * If the user has specified a set of mode names to use, mark as bad any modes - * not listed. - * - * The user mode names specified are prefixes to names of modes, so "1024x768" - * will match modes named "1024x768", "1024x768x75", "1024x768-good", but - * "1024x768x75" would only match "1024x768x75" from that list. - * - * MODE_BAD is used as the rejection flag, for lack of a better flag. - * - * \param modeList doubly-linked or circular list of modes. - * - * This is not in xf86Modes.c, but would be part of the proposed new API. - */ -void -xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList) -{ - DisplayModePtr mode; - - if (pScrn->display->modes[0] == NULL) - return; - - for (mode = modeList; mode != NULL; mode = mode->next) { - int i; - Bool good = FALSE; - - for (i = 0; pScrn->display->modes[i] != NULL; i++) { - if (strncmp(pScrn->display->modes[i], mode->name, - strlen(pScrn->display->modes[i])) == 0) { - good = TRUE; - break; - } - } - if (!good) - mode->status = MODE_BAD; - } -} - - -/** - * Frees any modes from the list with a status other than MODE_OK. - * - * \param modeList pointer to a doubly-linked or circular list of modes. - * \param verbose determines whether the reason for mode invalidation is - * printed. - * - * This is not in xf86Modes.c, but would be part of the proposed new API. - */ -void -xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, - Bool verbose) -{ - DisplayModePtr mode; - - for (mode = *modeList; mode != NULL;) { - DisplayModePtr next = mode->next, first = *modeList; - - if (mode->status != MODE_OK) { - if (verbose) { - char *type = ""; - if (mode->type & M_T_BUILTIN) - type = "built-in "; - else if (mode->type & M_T_DEFAULT) - type = "default "; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Not using %smode \"%s\" (%s)\n", type, mode->name, - xf86ModeStatusToString(mode->status)); - } - xf86DeleteMode(modeList, mode); - } - - if (next == first) - break; - mode = next; - } -} - -/** - * Adds the new mode into the mode list, and returns the new list - * - * \param modes doubly-linked mode list. - */ -DisplayModePtr -xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new) -{ - if (modes == NULL) - return new; - - if (new) { - DisplayModePtr mode = modes; - - while (mode->next) - mode = mode->next; - - mode->next = new; - new->prev = mode; - } - - return modes; -} - -/** - * Build a mode list from a list of config file modes - */ -static DisplayModePtr -xf86GetConfigModes (XF86ConfModeLinePtr conf_mode) -{ - DisplayModePtr head = NULL, prev = NULL, mode; - - for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next) - { - mode = xcalloc(1, sizeof(DisplayModeRec)); - if (!mode) - continue; - mode->name = xstrdup(conf_mode->ml_identifier); - if (!mode->name) - { - xfree (mode); - continue; - } - mode->type = 0; - mode->Clock = conf_mode->ml_clock; - mode->HDisplay = conf_mode->ml_hdisplay; - mode->HSyncStart = conf_mode->ml_hsyncstart; - mode->HSyncEnd = conf_mode->ml_hsyncend; - mode->HTotal = conf_mode->ml_htotal; - mode->VDisplay = conf_mode->ml_vdisplay; - mode->VSyncStart = conf_mode->ml_vsyncstart; - mode->VSyncEnd = conf_mode->ml_vsyncend; - mode->VTotal = conf_mode->ml_vtotal; - mode->Flags = conf_mode->ml_flags; - mode->HSkew = conf_mode->ml_hskew; - mode->VScan = conf_mode->ml_vscan; - - mode->prev = prev; - mode->next = NULL; - if (prev) - prev->next = mode; - else - head = mode; - prev = mode; - } - return head; -} - -/** - * Build a mode list from a monitor configuration - */ -DisplayModePtr -xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor) -{ - DisplayModePtr modes = NULL; - XF86ConfModesLinkPtr modes_link; - - if (!conf_monitor) - return NULL; - - /* - * first we collect the mode lines from the UseModes directive - */ - for (modes_link = conf_monitor->mon_modes_sect_lst; - modes_link; - modes_link = modes_link->list.next) - { - /* If this modes link hasn't been resolved, go look it up now */ - if (!modes_link->ml_modes) - modes_link->ml_modes = xf86findModes (modes_link->ml_modes_str, - xf86configptr->conf_modes_lst); - if (modes_link->ml_modes) - modes = xf86ModesAdd (modes, - xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst)); - } - - return xf86ModesAdd (modes, - xf86GetConfigModes (conf_monitor->mon_modeline_lst)); -} - -/** - * Build a mode list containing all of the default modes - */ -DisplayModePtr -xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed) -{ - DisplayModePtr head = NULL, prev = NULL, mode; - int i; - - for (i = 0; xf86DefaultModes[i].name != NULL; i++) - { - DisplayModePtr defMode = &xf86DefaultModes[i]; - - if (!interlaceAllowed && (defMode->Flags & V_INTERLACE)) - continue; - if (!doubleScanAllowed && (defMode->Flags & V_DBLSCAN)) - continue; - - mode = xalloc(sizeof(DisplayModeRec)); - if (!mode) - continue; - memcpy(mode,&xf86DefaultModes[i],sizeof(DisplayModeRec)); - mode->name = xstrdup(xf86DefaultModes[i].name); - if (!mode->name) - { - xfree (mode); - continue; - } - mode->prev = prev; - mode->next = NULL; - if (prev) - prev->next = mode; - else - head = mode; - prev = mode; - } - return head; -} diff --git a/src/i830_xf86Modes.h b/src/i830_xf86Modes.h deleted file mode 100644 index d032199d..00000000 --- a/src/i830_xf86Modes.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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> - * - */ - -#ifndef _I830_XF86MODES_H_ -#define _I830_XF86MODES_H_ -#include "xorgVersion.h" -#include "xf86Parser.h" -#include "i830_xf86Rename.h" - -double xf86ModeHSync(DisplayModePtr mode); -double xf86ModeVRefresh(DisplayModePtr mode); -DisplayModePtr xf86DuplicateMode(DisplayModePtr pMode); -DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn, - DisplayModePtr modeList); -void xf86SetModeDefaultName(DisplayModePtr mode); -void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags); -Bool xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2); -void xf86PrintModeline(int scrnIndex,DisplayModePtr mode); -DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new); - -DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); -DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, - Bool Reduced, Bool Interlaced); - -void -xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int flags); - -void -xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int *min, int *max, int n_ranges); - -void -xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int maxX, int maxY, int maxPitch); - -void -xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, - MonPtr mon); - -void -xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, - Bool verbose); - -void -xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int flags); - -void -xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList); - -DisplayModePtr -xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor); - -DisplayModePtr -xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed); - -#endif /* _I830_XF86MODES_H_ */ diff --git a/src/i830_xf86Rename.h b/src/i830_xf86Rename.h deleted file mode 100644 index cf8de622..00000000 --- a/src/i830_xf86Rename.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright © 2006 Keith Packard - * - * 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 the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifndef _XF86RENAME_H_ -#define _XF86RENAME_H_ - -#include "local_xf86Rename.h" - -#define xf86CrtcConfigInit XF86NAME(xf86CrtcConfigInit) -#define xf86CrtcConfigPrivateIndex XF86NAME(xf86CrtcConfigPrivateIndex) -#define xf86CrtcCreate XF86NAME(xf86CrtcCreate) -#define xf86CrtcDestroy XF86NAME(xf86CrtcDestroy) -#define xf86CrtcInUse XF86NAME(xf86CrtcInUse) -#define xf86CrtcRotate XF86NAME(xf86CrtcRotate) -#define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode) -#define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange) -#define xf86CVTMode XF86NAME(xf86CVTMode) -#define xf86DisableUnusedFunctions XF86NAME(xf86DisableUnusedFunctions) -#define xf86DPMSSet XF86NAME(xf86DPMSSet) -#define xf86DuplicateMode XF86NAME(xf86DuplicateMode) -#define xf86DuplicateModes XF86NAME(xf86DuplicateModes) -#define xf86GetDefaultModes XF86NAME(xf86GetDefaultModes) -#define xf86GetMonitorModes XF86NAME(xf86GetMonitorModes) -#define xf86InitialConfiguration XF86NAME(xf86InitialConfiguration) -#define xf86ModeHSync XF86NAME(xf86ModeHSync) -#define xf86ModesAdd XF86NAME(xf86ModesAdd) -#define xf86ModesEqual XF86NAME(xf86ModesEqual) -#define xf86ModeVRefresh XF86NAME(xf86ModeVRefresh) -#define xf86OutputCreate XF86NAME(xf86OutputCreate) -#define xf86OutputDestroy XF86NAME(xf86OutputDestroy) -#define xf86OutputGetEDID XF86NAME(xf86OutputGetEDID) -#define xf86OutputGetEDIDModes XF86NAME(xf86OutputGetEDIDModes) -#define xf86OutputRename XF86NAME(xf86OutputRename) -#define xf86OutputSetEDID XF86NAME(xf86OutputSetEDID) -#define xf86PrintModeline XF86NAME(xf86PrintModeline) -#define xf86ProbeOutputModes XF86NAME(xf86ProbeOutputModes) -#define xf86PruneInvalidModes XF86NAME(xf86PruneInvalidModes) -#define xf86SetModeCrtc XF86NAME(xf86SetModeCrtc) -#define xf86SetModeDefaultName XF86NAME(xf86SetModeDefaultName) -#define xf86SetScrnInfoModes XF86NAME(xf86SetScrnInfoModes) -#define xf86ValidateModesClocks XF86NAME(xf86ValidateModesClocks) -#define xf86ValidateModesFlags XF86NAME(xf86ValidateModesFlags) -#define xf86ValidateModesSize XF86NAME(xf86ValidateModesSize) -#define xf86ValidateModesSync XF86NAME(xf86ValidateModesSync) -#define xf86ValidateModesUserConfig XF86NAME(xf86ValidateModesUserConfig) - -#endif /* _XF86RENAME_H_ */ diff --git a/src/i830_xf86Rotate.c b/src/i830_xf86Rotate.c deleted file mode 100644 index bd4d5a60..00000000 --- a/src/i830_xf86Rotate.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright © 2006 Keith Packard - * - * 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 the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stddef.h> -#include <string.h> -#include <stdio.h> - -#include "xf86.h" -#include "xf86DDC.h" -#include "fb.h" -#include "windowstr.h" -#include "i830_xf86Crtc.h" -#include "i830_xf86Modes.h" -#include "i830_randr.h" -#include "X11/extensions/render.h" -#define DPMS_SERVER -#include "X11/extensions/dpms.h" -#include "X11/Xatom.h" - -static int -mode_height (DisplayModePtr mode, Rotation rotation) -{ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_180: - return mode->VDisplay; - case RR_Rotate_90: - case RR_Rotate_270: - return mode->HDisplay; - default: - return 0; - } -} - -static int -mode_width (DisplayModePtr mode, Rotation rotation) -{ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_180: - return mode->HDisplay; - case RR_Rotate_90: - case RR_Rotate_270: - return mode->VDisplay; - default: - return 0; - } -} - -/* borrowed from composite extension, move to Render and publish? */ - -static VisualPtr -compGetWindowVisual (WindowPtr pWin) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - VisualID vid = wVisual (pWin); - int i; - - for (i = 0; i < pScreen->numVisuals; i++) - if (pScreen->visuals[i].vid == vid) - return &pScreen->visuals[i]; - return 0; -} - -static PictFormatPtr -compWindowFormat (WindowPtr pWin) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - - return PictureMatchVisual (pScreen, pWin->drawable.depth, - compGetWindowVisual (pWin)); -} - -static void -xf86RotateBox (BoxPtr dst, BoxPtr src, Rotation rotation, - int dest_width, int dest_height) -{ - switch (rotation & 0xf) { - default: - case RR_Rotate_0: - *dst = *src; - break; - case RR_Rotate_90: - dst->x1 = src->y1; - dst->y1 = dest_height - src->x2; - dst->x2 = src->y2; - dst->y2 = dest_height - src->x1; - break; - case RR_Rotate_180: - dst->x1 = dest_width - src->x2; - dst->y1 = dest_height - src->y2; - dst->x2 = dest_width - src->x1; - dst->y2 = dest_height - src->y1; - break; - case RR_Rotate_270: - dst->x1 = dest_width - src->y2; - dst->y1 = src->x1; - dst->y2 = src->x2; - dst->x2 = dest_width - src->y1; - break; - } - if (rotation & RR_Reflect_X) { - int x1 = dst->x1; - dst->x1 = dest_width - dst->x2; - dst->x2 = dest_width - x1; - } - if (rotation & RR_Reflect_Y) { - int y1 = dst->y1; - dst->y1 = dest_height - dst->y2; - dst->y2 = dest_height - y1; - } -} - -static void -xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region) -{ - ScrnInfoPtr scrn = crtc->scrn; - ScreenPtr screen = scrn->pScreen; - WindowPtr root = WindowTable[screen->myNum]; - PixmapPtr dst_pixmap = crtc->rotatedPixmap; - PictFormatPtr format = compWindowFormat (WindowTable[screen->myNum]); - int error; - PicturePtr src, dst; - PictTransform transform; - int n = REGION_NUM_RECTS(region); - BoxPtr b = REGION_RECTS(region); - XID include_inferiors = IncludeInferiors; - - src = CreatePicture (None, - &root->drawable, - format, - CPSubwindowMode, - &include_inferiors, - serverClient, - &error); - if (!src) { - ErrorF("couldn't create src pict\n"); - return; - } - dst = CreatePicture (None, - &dst_pixmap->drawable, - format, - 0L, - NULL, - serverClient, - &error); - if (!dst) { - ErrorF("couldn't create src pict\n"); - return; - } - - memset (&transform, '\0', sizeof (transform)); - transform.matrix[2][2] = IntToxFixed(1); - transform.matrix[0][2] = IntToxFixed(crtc->x); - transform.matrix[1][2] = IntToxFixed(crtc->y); - switch (crtc->rotation & 0xf) { - default: - case RR_Rotate_0: - transform.matrix[0][0] = IntToxFixed(1); - transform.matrix[1][1] = IntToxFixed(1); - break; - case RR_Rotate_90: - transform.matrix[0][1] = IntToxFixed(-1); - transform.matrix[1][0] = IntToxFixed(1); - transform.matrix[0][2] += IntToxFixed(crtc->mode.VDisplay); - break; - case RR_Rotate_180: - transform.matrix[0][0] = IntToxFixed(-1); - transform.matrix[1][1] = IntToxFixed(-1); - transform.matrix[0][2] += IntToxFixed(crtc->mode.HDisplay); - transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay); - break; - case RR_Rotate_270: - transform.matrix[0][1] = IntToxFixed(1); - transform.matrix[1][0] = IntToxFixed(-1); - transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay); - break; - } - - /* handle reflection */ - if (crtc->rotation & RR_Reflect_X) - { - /* XXX figure this out */ - } - if (crtc->rotation & RR_Reflect_Y) - { - /* XXX figure this out too */ - } - - error = SetPictureTransform (src, &transform); - if (error) { - ErrorF("Couldn't set transform\n"); - return; - } - - while (n--) - { - BoxRec dst_box; - - xf86RotateBox (&dst_box, b, crtc->rotation, - crtc->mode.HDisplay, crtc->mode.VDisplay); - CompositePicture (PictOpSrc, - src, NULL, dst, - dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1, - dst_box.x2 - dst_box.x1, - dst_box.y2 - dst_box.y1); - b++; - } - FreePicture (src, None); - FreePicture (dst, None); -} - -static void -xf86RotateRedisplay(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - DamagePtr damage = xf86_config->rotationDamage; - RegionPtr region; - - if (!damage) - return; - region = DamageRegion(damage); - if (REGION_NOTEMPTY(pScreen, region)) - { - int c; - - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (crtc->rotation != RR_Rotate_0) - { - BoxRec box; - RegionRec crtc_damage; - - /* compute portion of damage that overlaps crtc */ - box.x1 = crtc->x; - box.x2 = crtc->x + mode_width (&crtc->mode, crtc->rotation); - box.y1 = crtc->y; - box.y2 = crtc->y + mode_height (&crtc->mode, crtc->rotation); - REGION_INIT(pScreen, &crtc_damage, &box, 1); - REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region); - - /* update damaged region */ - if (REGION_NOTEMPTY(pScreen, &crtc_damage)) - xf86RotateCrtcRedisplay (crtc, &crtc_damage); - - REGION_UNINIT (pScreen, &crtc_damage); - } - } - DamageEmpty(damage); - } -} - -static void -xf86RotateBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead) -{ - ScreenPtr pScreen = (ScreenPtr) data; - - xf86RotateRedisplay(pScreen); -} - -static void -xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask) -{ -} - -Bool -xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) -{ - ScrnInfoPtr pScrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - ScreenPtr pScreen = pScrn->pScreen; - - if (rotation == RR_Rotate_0) - { - /* Free memory from rotation */ - if (crtc->rotatedPixmap) - { - crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap); - crtc->rotatedPixmap = NULL; - } - - if (xf86_config->rotationDamage) - { - /* Free damage structure */ - DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, - xf86_config->rotationDamage); - DamageDestroy (xf86_config->rotationDamage); - xf86_config->rotationDamage = NULL; - /* Free block/wakeup handler */ - RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler, - xf86RotateWakeupHandler, - (pointer) pScreen); - } - } - else - { - /* - * these are the size of the shadow pixmap, which - * matches the mode, not the pre-rotated copy in the - * frame buffer - */ - int width = mode->HDisplay; - int height = mode->VDisplay; - PixmapPtr shadow = crtc->rotatedPixmap; - int old_width = shadow ? shadow->drawable.width : 0; - int old_height = shadow ? shadow->drawable.height : 0; - BoxRec damage_box; - RegionRec damage_region; - - /* Allocate memory for rotation */ - if (old_width != width || old_height != height) - { - if (shadow) - { - crtc->funcs->shadow_destroy (crtc, shadow); - crtc->rotatedPixmap = NULL; - } - shadow = crtc->funcs->shadow_create (crtc, width, height); - if (!shadow) - goto bail1; - crtc->rotatedPixmap = shadow; - } - - if (!xf86_config->rotationDamage) - { - /* Create damage structure */ - xf86_config->rotationDamage = DamageCreate (NULL, NULL, - DamageReportNone, - TRUE, pScreen, pScreen); - if (!xf86_config->rotationDamage) - goto bail2; - - /* Hook damage to screen pixmap */ - DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, - xf86_config->rotationDamage); - - /* Assign block/wakeup handler */ - if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler, - xf86RotateWakeupHandler, - (pointer) pScreen)) - { - goto bail3; - } - damage_box.x1 = 0; - damage_box.y1 = 0; - damage_box.x2 = mode_width (mode, rotation); - damage_box.y2 = mode_height (mode, rotation); - REGION_INIT (pScreen, &damage_region, &damage_box, 1); - DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, - &damage_region); - REGION_UNINIT (pScreen, &damage_region); - } - if (0) - { -bail3: - DamageDestroy (xf86_config->rotationDamage); - xf86_config->rotationDamage = NULL; - -bail2: - if (shadow) - { - crtc->funcs->shadow_destroy (crtc, shadow); - crtc->rotatedPixmap = NULL; - } -bail1: - if (old_width && old_height) - crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc, - old_width, - old_height); - return FALSE; - } - } - - /* All done */ - return TRUE; -} diff --git a/src/i830_xf86cvt.c b/src/i830_xf86cvt.c deleted file mode 100644 index 1a2b7869..00000000 --- a/src/i830_xf86cvt.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright 2005-2006 Luc Verhaegen. - * - * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. - */ - -/** - * @file This is a copy of xf86cvt.c from the X Server, for compatibility with - * old servers (pre-1.2). - */ - -/* - * The reason for having this function in a file of its own is - * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode - * code is shared directly. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" - -#include "i830.h" -#include "i830_display.h" -#include <string.h> - -#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) -/* - * Generate a CVT standard mode from HDisplay, VDisplay and VRefresh. - * - * These calculations are stolen from the CVT calculation spreadsheet written - * by Graham Loveridge. He seems to be claiming no copyright and there seems to - * be no license attached to this. He apparently just wants to see his name - * mentioned. - * - * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls - * - * Comments and structure corresponds to the comments and structure of the xls. - * This should ease importing of future changes to the standard (not very - * likely though). - * - * About margins; i'm sure that they are to be the bit between HDisplay and - * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and - * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking - * outside sync "margin" for some reason. Since we prefer seeing proper - * blanking instead of the overscan colour, and since the Crtc* values will - * probably get altered after us, we will disable margins altogether. With - * these calculations, Margins will plainly expand H/VDisplay, and we don't - * want that. -- libv - * - */ -_X_EXPORT DisplayModePtr -xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, - Bool Interlaced) -{ - DisplayModeRec *Mode = xnfalloc(sizeof(DisplayModeRec)); - - /* 1) top/bottom margin size (% of height) - default: 1.8 */ -#define CVT_MARGIN_PERCENTAGE 1.8 - - /* 2) character cell horizontal granularity (pixels) - default 8 */ -#define CVT_H_GRANULARITY 8 - - /* 4) Minimum vertical porch (lines) - default 3 */ -#define CVT_MIN_V_PORCH 3 - - /* 4) Minimum number of vertical back porch lines - default 6 */ -#define CVT_MIN_V_BPORCH 6 - - /* Pixel Clock step (kHz) */ -#define CVT_CLOCK_STEP 250 - - Bool Margins = FALSE; - float VFieldRate, HPeriod; - int HDisplayRnd, HMargin; - int VDisplayRnd, VMargin, VSync; - float Interlace; /* Please rename this */ - - memset(Mode, 0, sizeof(DisplayModeRec)); - - /* CVT default is 60.0Hz */ - if (!VRefresh) - VRefresh = 60.0; - - /* 1. Required field rate */ - if (Interlaced) - VFieldRate = VRefresh * 2; - else - VFieldRate = VRefresh; - - /* 2. Horizontal pixels */ - HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY); - - /* 3. Determine left and right borders */ - if (Margins) { - /* right margin is actually exactly the same as left */ - HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); - HMargin -= HMargin % CVT_H_GRANULARITY; - } else - HMargin = 0; - - /* 4. Find total active pixels */ - Mode->HDisplay = HDisplayRnd + 2*HMargin; - - /* 5. Find number of lines per field */ - if (Interlaced) - VDisplayRnd = VDisplay / 2; - else - VDisplayRnd = VDisplay; - - /* 6. Find top and bottom margins */ - /* nope. */ - if (Margins) - /* top and bottom margins are equal again. */ - VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); - else - VMargin = 0; - - Mode->VDisplay = VDisplay + 2*VMargin; - - /* 7. Interlace */ - if (Interlaced) - Interlace = 0.5; - else - Interlace = 0.0; - - /* Determine VSync Width from aspect ratio */ - if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay)) - VSync = 4; - else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay)) - VSync = 5; - else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay)) - VSync = 6; - else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay)) - VSync = 7; - else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay)) - VSync = 7; - else /* Custom */ - VSync = 10; - - if (!Reduced) { /* simplified GTF calculation */ - - /* 4) Minimum time of vertical sync + back porch interval (µs) - * default 550.0 */ -#define CVT_MIN_VSYNC_BP 550.0 - - /* 3) Nominal HSync width (% of line period) - default 8 */ -#define CVT_HSYNC_PERCENTAGE 8 - - float HBlankPercentage; - int VSyncAndBackPorch, VBackPorch; - int HBlank; - - /* 8. Estimated Horizontal period */ - HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) / - (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace); - - /* 9. Find number of lines in sync + backporch */ - if (((int)(CVT_MIN_VSYNC_BP / HPeriod) + 1) < (VSync + CVT_MIN_V_PORCH)) - VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH; - else - VSyncAndBackPorch = (int)(CVT_MIN_VSYNC_BP / HPeriod) + 1; - - /* 10. Find number of lines in back porch */ - VBackPorch = VSyncAndBackPorch - VSync; - - /* 11. Find total number of lines in vertical field */ - Mode->VTotal = VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace - + CVT_MIN_V_PORCH; - - /* 5) Definition of Horizontal blanking time limitation */ - /* Gradient (%/kHz) - default 600 */ -#define CVT_M_FACTOR 600 - - /* Offset (%) - default 40 */ -#define CVT_C_FACTOR 40 - - /* Blanking time scaling factor - default 128 */ -#define CVT_K_FACTOR 128 - - /* Scaling factor weighting - default 20 */ -#define CVT_J_FACTOR 20 - -#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256 -#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ - CVT_J_FACTOR - - /* 12. Find ideal blanking duty cycle from formula */ - HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod/1000.0; - - /* 13. Blanking time */ - if (HBlankPercentage < 20) - HBlankPercentage = 20; - - HBlank = Mode->HDisplay * HBlankPercentage/(100.0 - HBlankPercentage); - HBlank -= HBlank % (2*CVT_H_GRANULARITY); - - /* 14. Find total number of pixels in a line. */ - Mode->HTotal = Mode->HDisplay + HBlank; - - /* Fill in HSync values */ - Mode->HSyncEnd = Mode->HDisplay + HBlank / 2; - - Mode->HSyncStart = Mode->HSyncEnd - - (Mode->HTotal * CVT_HSYNC_PERCENTAGE) / 100; - Mode->HSyncStart += CVT_H_GRANULARITY - - Mode->HSyncStart % CVT_H_GRANULARITY; - - /* Fill in VSync values */ - Mode->VSyncStart = Mode->VDisplay + CVT_MIN_V_PORCH; - Mode->VSyncEnd = Mode->VSyncStart + VSync; - - } else { /* Reduced blanking */ - /* Minimum vertical blanking interval time (µs) - default 460 */ -#define CVT_RB_MIN_VBLANK 460.0 - - /* Fixed number of clocks for horizontal sync */ -#define CVT_RB_H_SYNC 32.0 - - /* Fixed number of clocks for horizontal blanking */ -#define CVT_RB_H_BLANK 160.0 - - /* Fixed number of lines for vertical front porch - default 3 */ -#define CVT_RB_VFPORCH 3 - - int VBILines; - - /* 8. Estimate Horizontal period. */ - HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) / - (VDisplayRnd + 2*VMargin); - - /* 9. Find number of lines in vertical blanking */ - VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1; - - /* 10. Check if vertical blanking is sufficient */ - if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH)) - VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH; - - /* 11. Find total number of lines in vertical field */ - Mode->VTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines; - - /* 12. Find total number of pixels in a line */ - Mode->HTotal = Mode->HDisplay + CVT_RB_H_BLANK; - - /* Fill in HSync values */ - Mode->HSyncEnd = Mode->HDisplay + CVT_RB_H_BLANK / 2; - Mode->HSyncStart = Mode->HSyncEnd - CVT_RB_H_SYNC; - - /* Fill in VSync values */ - Mode->VSyncStart = Mode->VDisplay + CVT_RB_VFPORCH; - Mode->VSyncEnd = Mode->VSyncStart + VSync; - } - - /* 15/13. Find pixel clock frequency (kHz for xf86) */ - Mode->Clock = Mode->HTotal * 1000.0 / HPeriod; - Mode->Clock -= Mode->Clock % CVT_CLOCK_STEP; - - /* 16/14. Find actual Horizontal Frequency (kHz) */ - Mode->HSync = ((float) Mode->Clock) / ((float) Mode->HTotal); - - /* 17/15. Find actual Field rate */ - Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / - ((float) (Mode->HTotal * Mode->VTotal)); - - /* 18/16. Find actual vertical frame frequency */ - /* ignore - just set the mode flag for interlaced */ - if (Interlaced) - Mode->VTotal *= 2; - - { - char Name[256]; - Name[0] = 0; - - snprintf(Name, 256, "%dx%d", HDisplay, VDisplay); - - Mode->name = xnfalloc(strlen(Name) + 1); - memcpy(Mode->name, Name, strlen(Name) + 1); - } - - if (Reduced) - Mode->Flags |= V_PHSYNC | V_NVSYNC; - else - Mode->Flags |= V_NHSYNC | V_PVSYNC; - - if (Interlaced) - Mode->Flags |= V_INTERLACE; - - return Mode; -} -#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) */ diff --git a/src/i965_render.c b/src/i965_render.c index 266b461f..78f1146c 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -133,7 +133,8 @@ static void i965_get_blend_cntl(int op, PicturePtr pMask, CARD32 dst_format, * the source blend factor is 0, and the source blend value is the mask * channels multiplied by the source picture's alpha. */ - if (pMask && pMask->componentAlpha && i965_blend_op[op].src_alpha) { + if (pMask && pMask->componentAlpha && PICT_FORMAT_RGB(pMask->format) + && i965_blend_op[op].src_alpha) { if (*dblend == BRW_BLENDFACTOR_SRC_ALPHA) { *dblend = BRW_BLENDFACTOR_SRC_COLOR; } else if (*dblend == BRW_BLENDFACTOR_INV_SRC_ALPHA) { @@ -223,7 +224,8 @@ i965_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, if (op >= sizeof(i965_blend_op) / sizeof(i965_blend_op[0])) I830FALLBACK("Unsupported Composite op 0x%x\n", op); - if (pMaskPicture != NULL && pMaskPicture->componentAlpha) { + if (pMaskPicture && pMaskPicture->componentAlpha && + PICT_FORMAT_RGB(pMaskPicture->format)) { /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. @@ -234,9 +236,7 @@ i965_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, I830FALLBACK("Component alpha not supported with source " "alpha and source value blending.\n"); } - /* XXX: fallback now for mask with componentAlpha */ - I830FALLBACK("mask componentAlpha not ready.\n"); - } + } if (!i965_check_composite_texture(pSrcPicture, 0)) I830FALLBACK("Check Src picture texture\n"); @@ -337,17 +337,19 @@ static const CARD32 sf_kernel_static_mask[][4] = { /* ps kernels */ #define PS_KERNEL_NUM_GRF 32 #define PS_MAX_THREADS 32 -/* 1: no mask */ + static const CARD32 ps_kernel_static_nomask [][4] = { #include "exa_wm_nomask_prog.h" }; -/* 2: mask with componentAlpha, src * mask color, XXX: later */ static const CARD32 ps_kernel_static_maskca [][4] = { -/*#include "i965_composite_wm_maskca.h" */ +#include "exa_wm_maskca_prog.h" +}; + +static const CARD32 ps_kernel_static_maskca_srcalpha [][4] = { +#include "exa_wm_maskca_srcalpha_prog.h" }; -/* 3: mask without componentAlpha, src * mask alpha */ static const CARD32 ps_kernel_static_masknoca [][4] = { #include "exa_wm_masknoca_prog.h" }; @@ -442,13 +444,20 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, else next_offset = sf_kernel_offset + sizeof (sf_kernel_static); - /* XXX: ps_kernel may be seperated, fix with offset */ ps_kernel_offset = ALIGN(next_offset, 64); if (pMask) { - if (pMaskPicture->componentAlpha) - next_offset = ps_kernel_offset + sizeof(ps_kernel_static_maskca); - else - next_offset = ps_kernel_offset + sizeof(ps_kernel_static_masknoca); + if (pMaskPicture->componentAlpha && + PICT_FORMAT_RGB(pMaskPicture->format)) { + if (i965_blend_op[op].src_alpha) { + next_offset = ps_kernel_offset + + sizeof(ps_kernel_static_maskca_srcalpha); + } else { + next_offset = ps_kernel_offset + + sizeof(ps_kernel_static_maskca); + } + } else + next_offset = ps_kernel_offset + + sizeof(ps_kernel_static_masknoca); } else { next_offset = ps_kernel_offset + sizeof (ps_kernel_static_nomask); } @@ -492,9 +501,9 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, next_offset = default_color_offset + sizeof(*default_color_state); total_state_size = next_offset; - assert(total_state_size < EXA_LINEAR_EXTRA); + assert(total_state_size < pI830->exa_965_state->size); - state_base_offset = pI830->EXAStateMem.Start; + state_base_offset = pI830->exa_965_state->offset; state_base_offset = ALIGN(state_base_offset, 64); state_base = (char *)(pI830->FbBase + state_base_offset); @@ -689,7 +698,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, default_color_state->color[0] = 0.0; /* R */ default_color_state->color[1] = 0.0; /* G */ default_color_state->color[2] = 0.0; /* B */ - default_color_state->color[3] = 1.0; /* A */ + default_color_state->color[3] = 0.0; /* A */ src_sampler_state->ss0.default_color_mode = 0; /* GL mode */ @@ -746,7 +755,6 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, vs_state->vs6.vs_enable = 0; vs_state->vs6.vert_cache_disable = 1; - /* XXX: sf_kernel? keep it as now */ /* Set up the SF kernel to do coord interp: for each attribute, * calculate dA/dx and dA/dy. Hand these interpolation coefficients * back to SF which then hands pixels off to WM. @@ -788,10 +796,15 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, /* Set up the PS kernel (dispatched by WM) */ if (pMask) { - if (pMaskPicture->componentAlpha) - memcpy(ps_kernel, ps_kernel_static_maskca, - sizeof (ps_kernel_static_maskca)); - else + if (pMaskPicture->componentAlpha && + PICT_FORMAT_RGB(pMaskPicture->format)) { + if (i965_blend_op[op].src_alpha) + memcpy(ps_kernel, ps_kernel_static_maskca_srcalpha, + sizeof (ps_kernel_static_maskca_srcalpha)); + else + memcpy(ps_kernel, ps_kernel_static_maskca, + sizeof (ps_kernel_static_maskca)); + } else memcpy(ps_kernel, ps_kernel_static_masknoca, sizeof (ps_kernel_static_masknoca)); } else { @@ -812,7 +825,6 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, wm_state->thread2.scratch_space_base_pointer = (state_base_offset + wm_scratch_offset)>>10; wm_state->thread2.per_thread_scratch_space = 0; - // XXX: urb allocation wm_state->thread3.const_urb_entry_read_length = 0; wm_state->thread3.const_urb_entry_read_offset = 0; /* Each pair of attributes (src/mask coords) is one URB entry */ @@ -948,44 +960,41 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, VB0_VERTEXDATA | ((4 * 2 * nelem) << VB0_BUFFER_PITCH_SHIFT)); OUT_RING(state_base_offset + vb_offset); - OUT_RING(2); // max index, prim has 4 coords + OUT_RING(3); OUT_RING(0); // ignore for VERTEXDATA, but still there /* Set up our vertex elements, sourced from the single vertex buffer. */ OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * nelem) - 1)); - /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */ OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (0 << VE0_OFFSET_SHIFT)); OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | - (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | - (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) | + (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_2_SHIFT) | + (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_3_SHIFT) | (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); - /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */ - OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | - VE0_VALID | - (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | - (8 << VE0_OFFSET_SHIFT)); - OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | - (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | - (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | - (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) | - (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); - if (pMask) { OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | - (16 << VE0_OFFSET_SHIFT)); + (8 << VE0_OFFSET_SHIFT)); OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | - (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | - (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) | - (8 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); + (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_2_SHIFT) | + (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_3_SHIFT) | + (2 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); } + OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | + VE0_VALID | + (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | + ((pMask?16:8) << VE0_OFFSET_SHIFT)); /* offset vb in bytes */ + OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | + (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | + (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | + (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) | + (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); /* VUE offset in dwords */ ADVANCE_LP_RING(); } diff --git a/src/ivch/Makefile.am b/src/ivch/Makefile.am index fac074db..40e26277 100644 --- a/src/ivch/Makefile.am +++ b/src/ivch/Makefile.am @@ -3,7 +3,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ +AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes ivch_la_LTLIBRARIES = ivch.la ivch_la_LDFLAGS = -module -avoid-version diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c index 085b542a..71f41f58 100644 --- a/src/ivch/ivch.c +++ b/src/ivch/ivch.c @@ -35,7 +35,7 @@ #include "compiler.h" #include "miscstruct.h" #include "xf86i2c.h" -#include "../i830_xf86Crtc.h" +#include "xf86Crtc.h" #define DPMS_SERVER #include <X11/extensions/dpms.h> diff --git a/src/reg_dumper/.gitignore b/src/reg_dumper/.gitignore new file mode 100644 index 00000000..1b38d5c6 --- /dev/null +++ b/src/reg_dumper/.gitignore @@ -0,0 +1 @@ +intel_reg_dumper diff --git a/src/reg_dumper/Makefile.am b/src/reg_dumper/Makefile.am new file mode 100644 index 00000000..aee26d0e --- /dev/null +++ b/src/reg_dumper/Makefile.am @@ -0,0 +1,12 @@ +noinst_PROGRAMS = intel_reg_dumper + +intel_reg_dumper_SOURCES = \ + main.c \ + reg_dumper.h \ + xprintf.c \ + ../i830_debug.c + +intel_reg_dumper_LDADD = $(PCIACCESS_LIBS) + +intel_reg_dumper_CFLAGS = $(PCIACCESS_CFLAGS) $(WARN_CFLAGS) \ + -I$(srcdir)/.. -DREG_DUMPER diff --git a/src/reg_dumper/main.c b/src/reg_dumper/main.c new file mode 100644 index 00000000..50c79236 --- /dev/null +++ b/src/reg_dumper/main.c @@ -0,0 +1,105 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <pciaccess.h> +#include <err.h> + +#include "reg_dumper.h" + +int main(int argc, char **argv) +{ + struct pci_device *dev; + I830Rec i830; + ScrnInfoRec scrn; + int err, mmio_bar; + + err = pci_system_init(); + if (err != 0) { + fprintf(stderr, "Couldn't initialize PCI system: %s\n", strerror(err)); + exit(1); + } + + /* Grab the graphics card */ + dev = pci_device_find_by_slot(0, 0, 2, 0); + if (dev == NULL) + errx(1, "Couldn't find graphics card"); + + if (dev->vendor_id != 0x8086) + errx(1, "Graphics card is non-intel"); + + err = pci_device_probe(dev); + if (err != 0) { + fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err)); + exit(1); + } + + i830.PciInfo = &i830.pci_info_rec; + i830.PciInfo->chipType = dev->device_id; + + i830.pci_dev = dev; + + mmio_bar = IS_I9XX((&i830)) ? 0 : 1; + + err = pci_device_map_region(dev, mmio_bar, 1); + if (err != 0) { + fprintf(stderr, "Couldn't map MMIO region: %s\n", strerror(err)); + exit(1); + } + i830.mmio = i830.pci_dev->regions[mmio_bar].memory; + + scrn.scrnIndex = 0; + scrn.pI830 = &i830; + + i830DumpRegs(&scrn); + + return 0; +} + +void xf86DrvMsg(int scrnIndex, int severity, const char *format, ...) +{ + va_list va; + + switch (severity) { + case X_INFO: + printf("(II): "); + break; + case X_WARNING: + printf("(WW): "); + break; + case X_ERROR: + printf("(EE): "); + break; + } + + va_start(va, format); + vprintf(format, va); + va_end(va); +} diff --git a/src/reg_dumper/reg_dumper.h b/src/reg_dumper/reg_dumper.h new file mode 100644 index 00000000..a52d6622 --- /dev/null +++ b/src/reg_dumper/reg_dumper.h @@ -0,0 +1,89 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +#include <sys/types.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include "common.h" + +/** @file + * This file defines the typedefs and stub structures necessary for us to + * use i830_debug.c mostly unmodified. + */ + +typedef uint32_t CARD32; +typedef char Bool; + +#define FALSE 0 +#define TRUE 1 + +#define X_INFO 0 +#define X_WARNING 1 +#define X_ERROR 2 + +struct pci_info_rec { + uint16_t chipType; +}; + +typedef struct _i830 { + /* Fields in common with the real pI830 */ + struct pci_info_rec *PciInfo; + + /* Fields used for setting up reg_dumper */ + struct pci_device *pci_dev; + struct pci_info_rec pci_info_rec; + volatile unsigned char *mmio; +} I830Rec, *I830Ptr; + +typedef struct _scrn { + /* Fields in common with the real pScrn */ + int scrnIndex; + + /* Fields used for setting up reg_dumper */ + I830Ptr pI830; +} ScrnInfoRec, *ScrnInfoPtr; + +#define I830PTR(pScrn) (pScrn->pI830) + +#define INREG8(reg) (*(volatile uint8_t *)((pI830)->mmio + (reg))) +#define INREG16(reg) (*(volatile uint16_t *)((pI830)->mmio + (reg))) +#define INREG(reg) (*(volatile uint32_t *)((pI830)->mmio + (reg))) +#define OUTREG8(reg, val) \ + *(volatile uint8_t *)((pI830)->mmio + (reg)) = (val) +#define OUTREG16(reg, val) \ + *(volatile uint16_t *)((pI830)->mmio + (reg)) = (val) +#define OUTREG(reg, val) \ + *(volatile uint32_t *)((pI830)->mmio + (reg)) = (val) + +#define xalloc malloc +#define xfree free +#define ErrorF printf + +char *XNFprintf(const char *format, ...); +void xf86DrvMsg(int scrnIndex, int severity, const char *format, ...); +void i830DumpRegs(ScrnInfoPtr pScrn); diff --git a/src/reg_dumper/xprintf.c b/src/reg_dumper/xprintf.c new file mode 100644 index 00000000..125ae870 --- /dev/null +++ b/src/reg_dumper/xprintf.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2004 Alexander Gottwald + * + * 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 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 ABOVE LISTED COPYRIGHT HOLDER(S) 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. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#include <string.h> +#include <stdarg.h> +#include "reg_dumper.h" + +static char * +XNFvprintf(const char *format, va_list va) +{ + char *ret; + int size; + va_list va2; + + va_copy(va2, va); + size = vsnprintf(NULL, 0, format, va2); + va_end(va2); + + ret = (char *)malloc(size + 1); + if (ret == NULL) + return NULL; + + vsnprintf(ret, size + 1, format, va); + ret[size] = 0; + return ret; +} + +char * +XNFprintf(const char *format, ...) +{ + char *ret; + va_list va; + va_start(va, format); + ret = XNFvprintf(format, va); + va_end(va); + return ret; +} diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am index 927f5a77..4cf717c4 100644 --- a/src/sil164/Makefile.am +++ b/src/sil164/Makefile.am @@ -3,7 +3,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/../ +AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes sil164_la_LTLIBRARIES = sil164.la sil164_la_LDFLAGS = -module -avoid-version diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c index 453ed044..80b1b6a8 100644 --- a/src/sil164/sil164.c +++ b/src/sil164/sil164.c @@ -37,7 +37,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "compiler.h" #include "miscstruct.h" #include "xf86i2c.h" -#include "i830_xf86Crtc.h" +#include "xf86Crtc.h" #define DPMS_SERVER #include <X11/extensions/dpms.h> |