summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--src/Makefile.am9
-rw-r--r--src/common.h36
-rw-r--r--src/i810_driver.c20
-rw-r--r--src/i810_reg.h42
-rw-r--r--src/i830.h9
-rw-r--r--src/i830_bios.c90
-rw-r--r--src/i830_bios.h93
-rw-r--r--src/i830_debug.c49
-rw-r--r--src/i830_display.c73
-rw-r--r--src/i830_dri.c19
-rw-r--r--src/i830_driver.c85
-rw-r--r--src/i830_hdmi.c233
-rw-r--r--src/i830_hwmc.c5
-rw-r--r--src/i830_hwmc.h7
-rw-r--r--src/i830_lvds.c43
-rw-r--r--src/i830_memory.c15
-rw-r--r--src/i830_quirks.c9
-rw-r--r--src/i830_sdvo.c257
-rw-r--r--src/i830_sdvo.h2
-rw-r--r--src/i830_sdvo_regs.h36
-rw-r--r--src/i830_tv.c4
-rw-r--r--src/i830_video.c73
-rw-r--r--src/i830_video.h2
-rw-r--r--src/i915_hwmc.c35
-rw-r--r--src/i915_hwmc.h1
-rw-r--r--src/i915_video.c10
-rw-r--r--src/i965_render.c75
-rw-r--r--src/i965_video.c2
-rw-r--r--src/reg_dumper/.gitignore1
-rw-r--r--src/reg_dumper/Makefile.am9
-rw-r--r--src/reg_dumper/hotplug.c151
-rw-r--r--src/xvmc/I810XvMC.c2
-rw-r--r--src/xvmc/i915_structs.h81
-rw-r--r--src/xvmc/i915_xvmc.c1385
-rw-r--r--src/xvmc/intel_xvmc.c12
-rw-r--r--src/xvmc/intel_xvmc.h3
-rw-r--r--src/xvmc/intel_xvmc_dump.c31
38 files changed, 2105 insertions, 908 deletions
diff --git a/configure.ac b/configure.ac
index e62502c5..254fef4b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -202,6 +202,10 @@ if test "$DRI" = yes; then
PKG_CHECK_MODULES(DRI, [xf86driproto glproto])
AC_DEFINE(XF86DRI,1,[Enable DRI driver support])
AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support])
+ PKG_CHECK_MODULES(DRI_MM, [libdrm >= 2.4.0],[DRI_MM=yes], [DRI_MM=no])
+ if test "x$DRI_MM" = xyes; then
+ AC_DEFINE(XF86DRI_MM,1,[Extended DRI memory management])
+ fi
if test "$have_damage_h" = yes; then
AC_DEFINE(DAMAGE,1,[Use Damage extension])
fi
diff --git a/src/Makefile.am b/src/Makefile.am
index 6b812f94..e3bbdcea 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,6 +37,10 @@ AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRM_CFLAGS@ @DRI_CFLAGS@ \
intel_drv_la_LTLIBRARIES = intel_drv.la
intel_drv_la_LDFLAGS = -module -avoid-version
intel_drv_ladir = @moduledir@/drivers
+intel_drv_la_LIBADD =
+if XSERVER_LIBPCIACCESS
+intel_drv_la_LIBADD += @PCIACCESS_LIBS@
+endif
XMODE_SRCS=\
local_xf86Rename.h \
@@ -103,6 +107,7 @@ intel_drv_la_SOURCES = \
i830_driver.c \
i830_dvo.c \
i830.h \
+ i830_hdmi.c \
i830_i2c.c \
i830_io.c \
i830_lvds.c \
@@ -186,7 +191,7 @@ if HAVE_GEN4ASM
SUFFIXES = .g4a .g4b
.g4a.g4b:
- m4 -s $*.g4a > $*.g4m && intel-gen4asm -o $@ $*.g4m && rm $*.g4m
+ m4 -I$(srcdir) -s $< > $*.g4m && intel-gen4asm -o $@ $*.g4m && rm $*.g4m
$(INTEL_G4B): $(INTEL_G4I)
@@ -204,6 +209,8 @@ endif
if DRI
intel_drv_la_SOURCES += \
$(INTEL_DRI_SRCS)
+intel_drv_la_LIBADD += \
+ $(DRI_LIBS)
endif
if XVMC
diff --git a/src/common.h b/src/common.h
index 9a3e0ac3..57db6cb0 100644
--- a/src/common.h
+++ b/src/common.h
@@ -303,9 +303,24 @@ extern int I810_DEBUG;
#define PCI_CHIP_Q33_G_BRIDGE 0x29D0
#endif
-#ifndef PCI_CHIP_IGD_GM
-#define PCI_CHIP_IGD_GM 0x2A42
-#define PCI_CHIP_IGD_GM_BRIDGE 0x2A40
+#ifndef PCI_CHIP_GM45_GM
+#define PCI_CHIP_GM45_GM 0x2A42
+#define PCI_CHIP_GM45_BRIDGE 0x2A40
+#endif
+
+#ifndef PCI_CHIP_IGD_E_G
+#define PCI_CHIP_IGD_E_G 0x2E02
+#define PCI_CHIP_IGD_E_G_BRIDGE 0x2E00
+#endif
+
+#ifndef PCI_CHIP_G45_G
+#define PCI_CHIP_G45_G 0x2E22
+#define PCI_CHIP_G45_G_BRIDGE 0x2E20
+#endif
+
+#ifndef PCI_CHIP_Q45_G
+#define PCI_CHIP_Q45_G 0x2E12
+#define PCI_CHIP_Q45_G_BRIDGE 0x2E10
#endif
#if XSERVER_LIBPCIACCESS
@@ -339,19 +354,26 @@ extern int I810_DEBUG;
#define IS_I915GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I915_GM)
#define IS_I945G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_G)
#define IS_I945GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GME)
-#define IS_IGD_GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_GM)
+#define IS_GM45(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_GM45_GM)
+#define IS_G4X(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_E_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G45_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q45_G)
#define IS_I965GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME)
-#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I946_GZ || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME || IS_IGD_GM(pI810))
+#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I946_GZ || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME || IS_GM45(pI810) || IS_G4X(pI810))
#define IS_G33CLASS(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G33_G ||\
DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q35_G ||\
DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q33_G)
#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810) || IS_G33CLASS(pI810))
+#define IS_I915(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_G33CLASS(pI810))
-#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_IGD_GM(pI810))
+#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_GM45(pI810))
/* mark chipsets for using gfx VM offset for overlay */
#define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810) || IS_I965G(pI810))
+/* mark chipsets without overlay hw */
+#define OVERLAY_NOEXIST(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
/* chipsets require graphics mem for hardware status page */
-#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_IGD_GM(pI810))
+#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_GM45(pI810) || IS_G4X(pI810))
+/* chipsets require status page in non stolen memory */
+#define HWS_NEED_NONSTOLEN(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
+#define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_GM45(pI810) || IS_G4X(pI810))
#define GTT_PAGE_SIZE KB(4)
#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y))
diff --git a/src/i810_driver.c b/src/i810_driver.c
index 4b716608..8540646d 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -152,7 +152,10 @@ static const struct pci_id_match intel_device_match[] = {
INTEL_DEVICE_MATCH (PCI_CHIP_G33_G, 0 ),
INTEL_DEVICE_MATCH (PCI_CHIP_Q35_G, 0 ),
INTEL_DEVICE_MATCH (PCI_CHIP_Q33_G, 0 ),
- INTEL_DEVICE_MATCH (PCI_CHIP_IGD_GM, 0 ),
+ INTEL_DEVICE_MATCH (PCI_CHIP_GM45_GM, 0 ),
+ INTEL_DEVICE_MATCH (PCI_CHIP_IGD_E_G, 0 ),
+ INTEL_DEVICE_MATCH (PCI_CHIP_G45_G, 0 ),
+ INTEL_DEVICE_MATCH (PCI_CHIP_Q45_G, 0 ),
{ 0, 0, 0 },
};
@@ -205,7 +208,10 @@ static SymTabRec I810Chipsets[] = {
{PCI_CHIP_G33_G, "G33"},
{PCI_CHIP_Q35_G, "Q35"},
{PCI_CHIP_Q33_G, "Q33"},
- {PCI_CHIP_IGD_GM, "Intel Integrated Graphics Device"},
+ {PCI_CHIP_GM45_GM, "Mobile IntelĀ® GM45 Express Chipset"},
+ {PCI_CHIP_IGD_E_G, "Intel Integrated Graphics Device"},
+ {PCI_CHIP_G45_G, "G45/G43"},
+ {PCI_CHIP_Q45_G, "Q45/Q43"},
{-1, NULL}
};
@@ -235,7 +241,10 @@ static PciChipsets I810PciChipsets[] = {
{PCI_CHIP_G33_G, PCI_CHIP_G33_G, RES_SHARED_VGA},
{PCI_CHIP_Q35_G, PCI_CHIP_Q35_G, RES_SHARED_VGA},
{PCI_CHIP_Q33_G, PCI_CHIP_Q33_G, RES_SHARED_VGA},
- {PCI_CHIP_IGD_GM, PCI_CHIP_IGD_GM, RES_SHARED_VGA},
+ {PCI_CHIP_GM45_GM, PCI_CHIP_GM45_GM, RES_SHARED_VGA},
+ {PCI_CHIP_IGD_E_G, PCI_CHIP_IGD_E_G, RES_SHARED_VGA},
+ {PCI_CHIP_G45_G, PCI_CHIP_G45_G, RES_SHARED_VGA},
+ {PCI_CHIP_Q45_G, PCI_CHIP_Q45_G, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED }
};
@@ -799,7 +808,10 @@ I810Probe(DriverPtr drv, int flags)
case PCI_CHIP_G33_G:
case PCI_CHIP_Q35_G:
case PCI_CHIP_Q33_G:
- case PCI_CHIP_IGD_GM:
+ case PCI_CHIP_GM45_GM:
+ case PCI_CHIP_IGD_E_G:
+ case PCI_CHIP_G45_G:
+ case PCI_CHIP_Q45_G:
xf86SetEntitySharable(usedChips[i]);
/* Allocate an entity private if necessary */
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 6a82c19b..4b9ce9bd 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1218,6 +1218,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# define FP_M2_DIV_SHIFT 0
#define PORT_HOTPLUG_EN 0x61110
+# define HDMIB_HOTPLUG_INT_EN (1 << 29)
+# define HDMIC_HOTPLUG_INT_EN (1 << 28)
+# define HDMID_HOTPLUG_INT_EN (1 << 27)
# define SDVOB_HOTPLUG_INT_EN (1 << 26)
# define SDVOC_HOTPLUG_INT_EN (1 << 25)
# define TV_HOTPLUG_INT_EN (1 << 18)
@@ -1225,6 +1228,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
#define PORT_HOTPLUG_STAT 0x61114
+# define HDMIB_HOTPLUG_INT_STATUS (1 << 29)
+# define HDMIC_HOTPLUG_INT_STATUS (1 << 28)
+# define HDMID_HOTPLUG_INT_STATUS (1 << 27)
# define CRT_HOTPLUG_INT_STATUS (1 << 11)
# define TV_HOTPLUG_INT_STATUS (1 << 10)
# define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
@@ -1253,9 +1259,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
#define SDVOC_GANG_MODE (1 << 16)
+#define SDVO_ENCODING_SDVO (0x0 << 10)
+#define SDVO_ENCODING_HDMI (0x2 << 10)
+/** Requird for HDMI operation */
+#define SDVO_NULL_PACKETS_DURING_VSYNC (1 << 9)
#define SDVO_BORDER_ENABLE (1 << 7)
-/** new with 965, default is to be set */
+/** New with 965, default is to be set */
#define SDVO_VSYNC_ACTIVE_HIGH (1 << 4)
+/** New with 965, default is to be set */
#define SDVO_HSYNC_ACTIVE_HIGH (1 << 3)
/** 915/945 only, read-only bit */
#define SDVOB_PCIE_CONCURRENCY (1 << 3)
@@ -1453,6 +1464,30 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/** @} */
+#define DP_B 0x64100
+#define DPB_AUX_CH_CTL 0x64110
+#define DPB_AUX_CH_DATA1 0x64114
+#define DPB_AUX_CH_DATA2 0x64118
+#define DPB_AUX_CH_DATA3 0x6411c
+#define DPB_AUX_CH_DATA4 0x64120
+#define DPB_AUX_CH_DATA5 0x64124
+
+#define DP_C 0x64200
+#define DPC_AUX_CH_CTL 0x64210
+#define DPC_AUX_CH_DATA1 0x64214
+#define DPC_AUX_CH_DATA2 0x64218
+#define DPC_AUX_CH_DATA3 0x6421c
+#define DPC_AUX_CH_DATA4 0x64220
+#define DPC_AUX_CH_DATA5 0x64224
+
+#define DP_D 0x64300
+#define DPD_AUX_CH_CTL 0x64310
+#define DPD_AUX_CH_DATA1 0x64314
+#define DPD_AUX_CH_DATA2 0x64318
+#define DPD_AUX_CH_DATA3 0x6431c
+#define DPD_AUX_CH_DATA4 0x64320
+#define DPD_AUX_CH_DATA5 0x64324
+
/*
* Two channel clock control. Turn this on if you need clkb for two channel mode
* Overridden by global LVDS power sequencing
@@ -2272,6 +2307,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
#define G33_GMCH_GMS_STOLEN_128M (0x8 << 4)
#define G33_GMCH_GMS_STOLEN_256M (0x9 << 4)
+#define INTEL_GMCH_GMS_STOLEN_96M (0xa << 4)
+#define INTEL_GMCH_GMS_STOLEN_160M (0xb << 4)
+#define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4)
+#define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4)
+
#define I85X_CAPID 0x44
#define I85X_VARIANT_MASK 0x7
diff --git a/src/i830.h b/src/i830.h
index 5c6fa820..a8ab8c6c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -236,6 +236,7 @@ typedef struct {
#define I830_OUTPUT_SDVO 5
#define I830_OUTPUT_LVDS 6
#define I830_OUTPUT_TVOUT 7
+#define I830_OUTPUT_HDMI 8
struct _I830DVODriver {
int type;
@@ -427,7 +428,6 @@ typedef struct _I830Rec {
#ifdef INTEL_XVMC
/* For XvMC */
Bool XvMCEnabled;
- Bool IsXvMCSurface;
#endif
XF86ModReqInfo shadowReq; /* to test for later libshadow */
@@ -567,6 +567,10 @@ typedef struct _I830Rec {
OptionInfoPtr Options;
Bool lvds_24_bit_mode;
+ Bool lvds_use_ssc;
+ int lvds_ssc_freq; /* in MHz */
+
+ Bool tv_present; /* TV connector present (from VBIOS) */
Bool StolenOnly;
@@ -819,6 +823,9 @@ void i830_crt_init(ScrnInfoPtr pScrn);
/* i830_dvo.c */
void i830_dvo_init(ScrnInfoPtr pScrn);
+/* i830_hdmi.c */
+void i830_hdmi_init(ScrnInfoPtr pScrn, int output_reg);
+
/* i830_lvds.c */
void i830_lvds_init(ScrnInfoPtr pScrn);
diff --git a/src/i830_bios.c b/src/i830_bios.c
index 57ee2782..a8193fc5 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -70,6 +70,32 @@ i830DumpBIOSToFile(ScrnInfoPtr pScrn, unsigned char *bios)
fclose(f);
}
+static void *
+find_section(struct bdb_header *bdb, int section_id)
+{
+ unsigned char *base = (unsigned char *)bdb;
+ int index = 0;
+ uint16_t total, current_size;
+ unsigned char current_id;
+
+ /* skip to first section */
+ index += bdb->header_size;
+ total = bdb->bdb_size;
+
+ /* walk the sections looking for section_id */
+ while (index < total) {
+ current_id = *(base + index);
+ index++;
+ current_size = *((uint16_t *)(base + index));
+ index += 2;
+ if (current_id == section_id)
+ return base + index;
+ index += current_size;
+ }
+
+ return NULL;
+}
+
/**
* Loads the Video BIOS and checks that the VBT exists.
*
@@ -127,6 +153,70 @@ i830_bios_get (ScrnInfoPtr pScrn)
return bios;
}
+void
+i830_bios_get_ssc(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ struct vbt_header *vbt;
+ struct bdb_header *bdb;
+ struct bdb_general_features *bdb_features;
+ int vbt_off, bdb_off;
+ unsigned char *bios;
+
+ bios = i830_bios_get(pScrn);
+
+ if (bios == NULL)
+ return;
+
+ vbt_off = INTEL_BIOS_16(0x1a);
+ vbt = (struct vbt_header *)(bios + vbt_off);
+ bdb_off = vbt_off + vbt->bdb_offset;
+ bdb = (struct bdb_header *)(bios + bdb_off);
+
+ bdb_features = find_section(bdb, BDB_GENERAL_FEATURES);
+ if (!bdb_features)
+ return;
+
+ pI830->lvds_use_ssc = bdb_features->enable_ssc;
+ if (pI830->lvds_use_ssc) {
+ if (IS_I855(pI830))
+ pI830->lvds_ssc_freq = bdb_features->ssc_freq ? 66 : 48;
+ else
+ pI830->lvds_ssc_freq = bdb_features->ssc_freq ? 100 : 96;
+ }
+
+ xfree(bios);
+}
+
+void
+i830_bios_get_tv(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ struct vbt_header *vbt;
+ struct bdb_header *bdb;
+ struct bdb_general_features *bdb_features;
+ int vbt_off, bdb_off;
+ unsigned char *bios;
+
+ bios = i830_bios_get(pScrn);
+
+ if (bios == NULL)
+ return;
+
+ vbt_off = INTEL_BIOS_16(0x1a);
+ vbt = (struct vbt_header *)(bios + vbt_off);
+ bdb_off = vbt_off + vbt->bdb_offset;
+ bdb = (struct bdb_header *)(bios + bdb_off);
+
+ bdb_features = find_section(bdb, BDB_GENERAL_FEATURES);
+ if (!bdb_features)
+ return;
+
+ pI830->tv_present = bdb_features->int_tv_support;
+
+ xfree(bios);
+}
+
/**
* Returns the BIOS's fixed panel mode.
*
diff --git a/src/i830_bios.h b/src/i830_bios.h
index 95230f5a..c1ba50d7 100644
--- a/src/i830_bios.h
+++ b/src/i830_bios.h
@@ -49,6 +49,97 @@ struct bdb_header {
uint16_t bdb_size; /**< in bytes */
} __attribute__((packed));
+/*
+ * There are several types of BIOS data blocks (BDBs), each block has
+ * an ID and size in the first 3 bytes (ID in first, size in next 2).
+ * Known types are listed below.
+ */
+#define BDB_GENERAL_FEATURES 1
+#define BDB_GENERAL_DEFINITIONS 2
+#define BDB_OLD_TOGGLE_LIST 3
+#define BDB_MODE_SUPPORT_LIST 4
+#define BDB_GENERIC_MODE_TABLE 5
+#define BDB_EXT_MMIO_REGS 6
+#define BDB_SWF_IO 7
+#define BDB_SWF_MMIO 8
+#define BDB_DOT_CLOCK_TABLE 9
+#define BDB_MODE_REMOVAL_TABLE 10
+#define BDB_CHILD_DEVICE_TABLE 11
+#define BDB_DRIVER_FEATURES 12
+#define BDB_DRIVER_PERSISTENCE 13
+#define BDB_EXT_TABLE_PTRS 14
+#define BDB_DOT_CLOCK_OVERRIDE 15
+#define BDB_DISPLAY_SELECT 16
+/* 17 rsvd */
+#define BDB_DRIVER_ROTATION 18
+#define BDB_DISPLAY_REMOVE 19
+#define BDB_OEM_CUSTOM 20
+#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */
+#define BDB_SDVO_LVDS_OPTIONS 22
+#define BDB_SDVO_PANEL_DTDS 23
+#define BDB_SDVO_LVDS_PNP_IDS 24
+#define BDB_SDVO_LVDS_POWER_SEQ 25
+#define BDB_TV_OPTIONS 26
+#define BDB_LVDS_OPTIONS 40
+#define BDB_LVDS_LFP_DATA_PTRS 41
+#define BDB_LVDS_LFP_DATA 42
+#define BDB_LVDS_BACKLIGHT 43
+#define BDB_LVDS_POWER 44
+#define BDB_SKIP 254 /* VBIOS private block, ignore */
+
+struct bdb_general_features {
+ /* bits 1 */
+ unsigned char panel_fitting:2;
+ unsigned char flexaim:1;
+ unsigned char msg_enable:1;
+ unsigned char clear_screen:3;
+ unsigned char color_flip:1;
+
+ /* bits 2 */
+ unsigned char download_ext_vbt:1;
+ unsigned char enable_ssc:1;
+ unsigned char ssc_freq:1;
+ unsigned char enable_lfp_on_override:1;
+ unsigned char disable_ssc_ddt:1;
+ unsigned char rsvd8:3; /* finish byte */
+
+ /* bits 3 */
+ unsigned char disable_smooth_vision:1;
+ unsigned char single_dvi:1;
+ unsigned char rsvd9:6; /* finish byte */
+
+ /* bits 4 */
+ unsigned char legacy_monitor_detect;
+
+ /* bits 5 */
+ unsigned char int_crt_support:1;
+ unsigned char int_tv_support:1;
+ unsigned char rsvd11:6; /* finish byte */
+} __attribute__((packed));
+
+struct bdb_general_definitions {
+ /* DDC GPIO */
+ unsigned char crt_ddc_gmbus_pin;
+
+ /* DPMS bits */
+ unsigned char dpms_acpi:1;
+ unsigned char skip_boot_crt_detect:1;
+ unsigned char dpms_aim:1;
+ unsigned char rsvd1:5; /* finish byte */
+
+ /* boot device bits */
+ unsigned char boot_display[2];
+ unsigned char child_dev_size;
+
+ /* device info */
+ unsigned char tv_or_lvds_info[33];
+ unsigned char dev1[33];
+ unsigned char dev2[33];
+ unsigned char dev3[33];
+ unsigned char dev4[33];
+ /* may be another device block here on some platforms */
+};
+
#define LVDS_CAP_EDID (1 << 6)
#define LVDS_CAP_DITHER (1 << 5)
#define LVDS_CAP_PFIT_AUTO_RATIO (1 << 4)
@@ -150,6 +241,8 @@ struct vch_bdb_22 {
unsigned char *
i830_bios_get (ScrnInfoPtr pScrn);
+void i830_bios_get_ssc(ScrnInfoPtr pScrn);
+void i830_bios_get_tv(ScrnInfoPtr pScrn);
DisplayModePtr i830_bios_get_panel_mode(ScrnInfoPtr pScrn, Bool *wants_dither);
unsigned char *
diff --git a/src/i830_debug.c b/src/i830_debug.c
index e90ea22a..21e52504 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -537,15 +537,6 @@ static struct i830SnapshotRec {
DEFINEREG2(PIPEASRC, i830_debug_yxminus1),
DEFINEREG2(PIPEASTAT, i830_debug_pipestat),
- DEFINEREG(FBC_CFB_BASE),
- DEFINEREG(FBC_LL_BASE),
- DEFINEREG(FBC_CONTROL),
- DEFINEREG(FBC_COMMAND),
- DEFINEREG(FBC_STATUS),
- DEFINEREG(FBC_CONTROL2),
- DEFINEREG(FBC_FENCE_OFF),
- DEFINEREG(FBC_MOD_NUM),
-
DEFINEREG2(FPA0, i830_debug_fp),
DEFINEREG2(FPA1, i830_debug_fp),
DEFINEREG2(DPLL_A, i830_debug_dpll),
@@ -623,11 +614,45 @@ static struct i830SnapshotRec {
DEFINEREG(TV_H_CHROMA_0),
DEFINEREG(TV_H_CHROMA_59),
+ DEFINEREG(FBC_CFB_BASE),
+ DEFINEREG(FBC_LL_BASE),
+ DEFINEREG(FBC_CONTROL),
+ DEFINEREG(FBC_COMMAND),
+ DEFINEREG(FBC_STATUS),
+ DEFINEREG(FBC_CONTROL2),
+ DEFINEREG(FBC_FENCE_OFF),
+ DEFINEREG(FBC_MOD_NUM),
+
DEFINEREG(MI_MODE),
/* DEFINEREG(MI_DISPLAY_POWER_DOWN), CRL only */
DEFINEREG(MI_ARB_STATE),
DEFINEREG(MI_RDRET_STATE),
DEFINEREG(ECOSKPD),
+
+ DEFINEREG(DP_B),
+ DEFINEREG(DPB_AUX_CH_CTL),
+ DEFINEREG(DPB_AUX_CH_DATA1),
+ DEFINEREG(DPB_AUX_CH_DATA2),
+ DEFINEREG(DPB_AUX_CH_DATA3),
+ DEFINEREG(DPB_AUX_CH_DATA4),
+ DEFINEREG(DPB_AUX_CH_DATA5),
+
+ DEFINEREG(DP_C),
+ DEFINEREG(DPC_AUX_CH_CTL),
+ DEFINEREG(DPC_AUX_CH_DATA1),
+ DEFINEREG(DPC_AUX_CH_DATA2),
+ DEFINEREG(DPC_AUX_CH_DATA3),
+ DEFINEREG(DPC_AUX_CH_DATA4),
+ DEFINEREG(DPC_AUX_CH_DATA5),
+
+ DEFINEREG(DP_D),
+ DEFINEREG(DPD_AUX_CH_CTL),
+ DEFINEREG(DPD_AUX_CH_DATA1),
+ DEFINEREG(DPD_AUX_CH_DATA2),
+ DEFINEREG(DPD_AUX_CH_DATA3),
+ DEFINEREG(DPD_AUX_CH_DATA4),
+ DEFINEREG(DPD_AUX_CH_DATA5),
+
#if 0
DEFINEREG2(FENCE_NEW + 0, i810_debug_fence_new),
DEFINEREG2(FENCE_NEW + 8, i810_debug_fence_new),
@@ -697,6 +722,7 @@ void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where)
}
#endif /* !REG_DUMPER */
+#if 0
static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int min, int max)
{
I830Ptr pI830 = I830PTR(pScrn);
@@ -737,6 +763,7 @@ static void i830DumpAR(ScrnInfoPtr pScrn)
OUTREG8(0x3c0, orig_arx);
INREG8(st01); /* switch back to index mode */
}
+#endif
void i830DumpRegs (ScrnInfoPtr pScrn)
{
@@ -748,8 +775,10 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
int ref;
int dot;
int phase;
+#if 0
int msr;
int crt;
+#endif
xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsBegin\n");
for (i = 0; i < NUM_I830_SNAPSHOTREGS; i++) {
@@ -767,6 +796,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
i830_snapshot[i].name, (unsigned int)val);
}
}
+#if 0
i830DumpIndexed (pScrn, "SR", 0x3c4, 0x3c5, 0, 7);
msr = INREG8(0x3cc);
xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%02x\n",
@@ -778,6 +808,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
else
crt = 0x3b0;
i830DumpIndexed (pScrn, "CR", crt + 4, crt + 5, 0, 0x24);
+#endif
for (pipe = 0; pipe <= 1; pipe++)
{
fp = INREG(pipe == 0 ? FPA0 : FPB0);
diff --git a/src/i830_display.c b/src/i830_display.c
index 56a718de..3967b69b 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -35,6 +35,7 @@
#include <assert.h>
#include <stdlib.h>
#include <math.h>
+#include <sys/ioctl.h>
#include "xf86.h"
#include "i830.h"
@@ -667,7 +668,7 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
- if (IS_IGD_GM(pI830))
+ if (IS_GM45(pI830))
return i830_enable_fb_compression2(crtc);
i830_enable_fb_compression_8xx(crtc);
@@ -679,7 +680,7 @@ i830_disable_fb_compression(xf86CrtcPtr crtc)
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
- if (IS_IGD_GM(pI830))
+ if (IS_GM45(pI830))
return i830_disable_fb_compression2(crtc);
i830_disable_fb_compression_8xx(crtc);
@@ -692,6 +693,7 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ unsigned long uncompressed_size;
int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
int i, count = 0;
@@ -723,6 +725,19 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */
return FALSE;
+ /* Can't cache more lines than we can track */
+ if (crtc->mode.VDisplay > FBC_LL_SIZE)
+ return FALSE;
+
+ /*
+ * Make sure the compressor doesn't go past the end of our compressed
+ * buffer if the uncompressed size is large.
+ */
+ uncompressed_size = crtc->mode.HDisplay * crtc->mode.VDisplay *
+ pI830->cpp;
+ if (pI830->compressed_front_buffer->size < uncompressed_size)
+ return FALSE;
+
/*
* No checks for pixel multiply, incl. horizontal, or interlaced modes
* since they're currently unused.
@@ -730,6 +745,37 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
return TRUE;
}
+#if defined(DRM_IOCTL_MODESET_CTL) && defined(XF86DRI)
+static void i830_modeset_ctl(xf86CrtcPtr crtc, int pre)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ struct drm_modeset_ctl modeset;
+
+ modeset.crtc = intel_crtc->plane;
+
+ /*
+ * DPMS will be called many times (especially off), but we only
+ * want to catch the transition from on->off and off->on.
+ */
+ if (pre && intel_crtc->dpms_mode != DPMSModeOff) {
+ /* On -> off is a pre modeset */
+ modeset.cmd = _DRM_PRE_MODESET;
+ ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset);
+ } else if (!pre && intel_crtc->dpms_mode == DPMSModeOff) {
+ /* Off -> on means post modeset */
+ modeset.cmd = _DRM_POST_MODESET;
+ ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset);
+ }
+}
+#else
+static void i830_modeset_ctl(xf86CrtcPtr crtc, int dpms_state)
+{
+ return;
+}
+#endif /* DRM_IOCTL_MODESET_CTL && XF86DRI */
+
/**
* Sets the power management mode of the pipe and plane.
*
@@ -797,8 +843,10 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
/* Reenable compression if needed */
if (i830_use_fb_compression(crtc))
i830_enable_fb_compression(crtc);
+ i830_modeset_ctl(crtc, 0);
break;
case DPMSModeOff:
+ i830_modeset_ctl(crtc, 1);
/* Shut off compression if in use */
if (i830_use_fb_compression(crtc))
i830_disable_fb_compression(crtc);
@@ -1080,7 +1128,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT;
- int i;
+ int i, num_outputs = 0;
int refclk;
intel_clock_t clock;
uint32_t dpll = 0, fp = 0, dspcntr, pipeconf, lvds_bits = 0;
@@ -1103,6 +1151,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
lvds_bits = intel_output->lvds_bits;
break;
case I830_OUTPUT_SDVO:
+ case I830_OUTPUT_HDMI:
is_sdvo = TRUE;
if (intel_output->needs_tv_clock)
is_tv = TRUE;
@@ -1119,9 +1168,19 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
is_crt = TRUE;
break;
}
+
+ num_outputs++;
}
- if (IS_I9XX(pI830)) {
+ if (num_outputs > 1)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "clone detected, disabling SSC\n");
+
+ /* Don't use SSC when cloned */
+ if (pI830->lvds_use_ssc && num_outputs < 2) {
+ refclk = pI830->lvds_ssc_freq * 1000;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "using SSC reference clock of %d MHz\n", refclk / 1000);
+ } else if (IS_I9XX(pI830)) {
refclk = 96000;
} else {
refclk = 48000;
@@ -1174,7 +1233,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
break;
}
- if (IS_I965G(pI830))
+ if (IS_I965G(pI830) && !IS_GM45(pI830))
dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
} else {
if (is_lvds) {
@@ -1197,10 +1256,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
dpll |= 3;
}
-#if 0
- else if (is_lvds)
+ else if (is_lvds && pI830->lvds_use_ssc && num_outputs < 2)
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
-#endif
else
dpll |= PLL_REF_INPUT_DREFCLK;
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 2f3c5d39..387e9876 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -995,26 +995,35 @@ static void
I830DRIDoRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox, uint32_t dst)
{
I830Ptr pI830 = I830PTR(pScrn);
- int i, cmd, br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16);
+ unsigned int i, cmd, pitch, flags;
+
+ pitch = pScrn->displayWidth * pI830->cpp;
+ flags = 0xcc << 16; /* ROP_S */
if (pScrn->bitsPerPixel == 32) {
cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB);
- br13 |= 3 << 24;
+ flags |= 3 << 24;
} else {
cmd = (XY_SRC_COPY_BLT_CMD);
- br13 |= 1 << 24;
+ flags |= 1 << 24;
+ }
+
+ /* We can assume tiled buffers if page flipping is on */
+ if (IS_I965G(pI830)) {
+ cmd |= XY_SRC_COPY_BLT_DST_TILED | XY_SRC_COPY_BLT_SRC_TILED;
+ pitch >>= 2;
}
for (i = 0 ; i < num ; i++, pbox++) {
BEGIN_BATCH(8);
OUT_BATCH(cmd);
- OUT_BATCH(br13);
+ OUT_BATCH(flags | pitch);
OUT_BATCH((pbox->y1 << 16) | pbox->x1);
OUT_BATCH((pbox->y2 << 16) | pbox->x2);
OUT_BATCH(dst);
OUT_BATCH((pbox->y1 << 16) | pbox->x1);
- OUT_BATCH(br13 & 0xffff);
+ OUT_BATCH(pitch);
OUT_BATCH(pI830->front_buffer->offset);
ADVANCE_BATCH();
}
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5525aec4..b44db7ec 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -249,7 +249,10 @@ static SymTabRec I830Chipsets[] = {
{PCI_CHIP_G33_G, "G33"},
{PCI_CHIP_Q35_G, "Q35"},
{PCI_CHIP_Q33_G, "Q33"},
- {PCI_CHIP_IGD_GM, "Intel Integrated Graphics Device"},
+ {PCI_CHIP_GM45_GM, "Mobile IntelĀ® GM45 Express Chipset"},
+ {PCI_CHIP_IGD_E_G, "Intel Integrated Graphics Device"},
+ {PCI_CHIP_G45_G, "G45/G43"},
+ {PCI_CHIP_Q45_G, "Q45/Q43"},
{-1, NULL}
};
@@ -273,7 +276,10 @@ static PciChipsets I830PciChipsets[] = {
{PCI_CHIP_G33_G, PCI_CHIP_G33_G, RES_SHARED_VGA},
{PCI_CHIP_Q35_G, PCI_CHIP_Q35_G, RES_SHARED_VGA},
{PCI_CHIP_Q33_G, PCI_CHIP_Q33_G, RES_SHARED_VGA},
- {PCI_CHIP_IGD_GM, PCI_CHIP_IGD_GM, RES_SHARED_VGA},
+ {PCI_CHIP_GM45_GM, PCI_CHIP_GM45_GM, RES_SHARED_VGA},
+ {PCI_CHIP_IGD_E_G, PCI_CHIP_IGD_E_G, RES_SHARED_VGA},
+ {PCI_CHIP_G45_G, PCI_CHIP_G45_G, RES_SHARED_VGA},
+ {PCI_CHIP_Q45_G, PCI_CHIP_Q45_G, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED}
};
@@ -509,6 +515,10 @@ I830DetectMemory(ScrnInfoPtr pScrn)
*/
range = gtt_size + 4;
+ /* new 4 series hardware has seperate GTT stolen with GFX stolen */
+ if (IS_G4X(pI830))
+ range = 0;
+
if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
case I855_GMCH_GMS_STOLEN_1M:
@@ -542,6 +552,22 @@ I830DetectMemory(ScrnInfoPtr pScrn)
if (IS_I9XX(pI830))
memsize = MB(256) - KB(range);
break;
+ case INTEL_GMCH_GMS_STOLEN_96M:
+ if (IS_I9XX(pI830))
+ memsize = MB(96) - KB(range);
+ break;
+ case INTEL_GMCH_GMS_STOLEN_160M:
+ if (IS_I9XX(pI830))
+ memsize = MB(160) - KB(range);
+ break;
+ case INTEL_GMCH_GMS_STOLEN_224M:
+ if (IS_I9XX(pI830))
+ memsize = MB(224) - KB(range);
+ break;
+ case INTEL_GMCH_GMS_STOLEN_352M:
+ if (IS_I9XX(pI830))
+ memsize = MB(352) - KB(range);
+ break;
}
} else {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
@@ -625,7 +651,7 @@ I830MapMMIO(ScrnInfoPtr pScrn)
if (IS_I965G(pI830))
{
- if (IS_IGD_GM(pI830)) {
+ if (IS_GM45(pI830) || IS_G4X(pI830)) {
gttaddr = pI830->MMIOAddr + MB(2);
pI830->GTTMapSize = MB(2);
} else {
@@ -896,12 +922,23 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
i830_lvds_init(pScrn);
if (IS_I9XX(pI830)) {
- i830_sdvo_init(pScrn, SDVOB);
- i830_sdvo_init(pScrn, SDVOC);
+ if (INREG(SDVOB) & SDVO_DETECTED) {
+ Bool found = i830_sdvo_init(pScrn, SDVOB);
+
+ if (!found && SUPPORTS_INTEGRATED_HDMI(pI830))
+ i830_hdmi_init(pScrn, SDVOB);
+ }
+
+ if (INREG(SDVOC) & SDVO_DETECTED) {
+ Bool found = i830_sdvo_init(pScrn, SDVOC);
+
+ if (!found && SUPPORTS_INTEGRATED_HDMI(pI830))
+ i830_hdmi_init(pScrn, SDVOC);
+ }
} else {
i830_dvo_init(pScrn);
}
- if (IS_I9XX(pI830) && !IS_I915G(pI830))
+ if (IS_I9XX(pI830) && IS_MOBILE(pI830))
i830_tv_init(pScrn);
for (o = 0; o < config->num_output; o++)
@@ -934,7 +971,7 @@ i830_init_clock_gating(ScrnInfoPtr pScrn)
/* Disable clock gating reported to work incorrectly according to the specs.
*/
- if (IS_IGD_GM(pI830)) {
+ if (IS_GM45(pI830)) {
OUTREG(RENCLK_GATE_D1, 0);
OUTREG(RENCLK_GATE_D2, 0);
OUTREG(RAMCLK_GATE_D, 0);
@@ -1179,9 +1216,18 @@ i830_detect_chipset(ScrnInfoPtr pScrn)
case PCI_CHIP_Q33_G:
chipname = "Q33";
break;
- case PCI_CHIP_IGD_GM:
+ case PCI_CHIP_GM45_GM:
+ chipname = "Mobile IntelĀ® GM45 Express Chipset";
+ break;
+ case PCI_CHIP_IGD_E_G:
chipname = "Intel Integrated Graphics Device";
break;
+ case PCI_CHIP_G45_G:
+ chipname = "G45/G43";
+ break;
+ case PCI_CHIP_Q45_G:
+ chipname = "Q45/Q43";
+ break;
default:
chipname = "unknown chipset";
break;
@@ -1939,14 +1985,23 @@ i830_set_dsparb(ScrnInfoPtr pScrn)
* FIFO RAM entries equally between planes A and B.
*/
if (IS_I9XX(pI830)) {
- if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+ if (IS_I965GM(pI830) || IS_GM45(pI830))
OUTREG(DSPARB, (127 << DSPARB_CSTART_SHIFT) |
(64 << DSPARB_BSTART_SHIFT));
else
OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) |
(48 << DSPARB_BSTART_SHIFT));
} else {
- OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT);
+ if (IS_MOBILE(pI830)) {
+ /* The 830 has 288 entries, and the 855 has 256. */
+ OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT);
+ } else {
+ /* The 845/865 only have a AEND field. Though the field size would
+ * allow 128 entries, the 865 rendered the cursor wrong then.
+ * The BIOS set it up for 96.
+ */
+ OUTREG(DSPARB, 95 << DSPARB_AEND_SHIFT);
+ }
}
}
@@ -2097,7 +2152,7 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->saveRAMCLK_GATE_D = INREG(RAMCLK_GATE_D);
}
- if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+ if (IS_I965GM(pI830) || IS_GM45(pI830))
pI830->savePWRCTXA = INREG(PWRCTXA);
if (IS_MOBILE(pI830) && !IS_I830(pI830))
@@ -2167,7 +2222,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(RAMCLK_GATE_D, pI830->saveRAMCLK_GATE_D);
}
- if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+ if (IS_I965GM(pI830) || IS_GM45(pI830))
OUTREG(PWRCTXA, pI830->savePWRCTXA);
/*
@@ -2584,7 +2639,7 @@ i830_try_memory_allocation(ScrnInfoPtr pScrn)
if (!i830_allocate_2d_memory(pScrn))
goto failed;
- if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+ if (IS_I965GM(pI830) || IS_GM45(pI830))
if (!i830_allocate_pwrctx(pScrn))
goto failed;
@@ -3018,7 +3073,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
"needs 2D acceleration.\n");
pI830->XvEnabled = FALSE;
}
- if (!IS_IGD_GM(pI830) && pI830->overlay_regs == NULL) {
+ if (!OVERLAY_NOEXIST(pI830) && pI830->overlay_regs == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Disabling Xv because the overlay register buffer "
"allocation failed.\n");
@@ -3058,7 +3113,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
* alone in that case.
* Also make sure the DRM can handle the swap.
*/
- if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_IGD_GM(pI830) &&
+ if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) &&
(!pI830->directRenderingEnabled ||
(pI830->directRenderingEnabled && pI830->drmMinor >= 10))) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings "
diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c
new file mode 100644
index 00000000..b738463c
--- /dev/null
+++ b/src/i830_hdmi.c
@@ -0,0 +1,233 @@
+/*
+ * 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>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "i830.h"
+#include "xf86Modes.h"
+#include "i830_display.h"
+
+struct i830_hdmi_priv {
+ uint32_t output_reg;
+
+ uint32_t save_SDVO;
+};
+
+static int
+i830_hdmi_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
+{
+ if (mode->Clock > 165000)
+ return MODE_CLOCK_HIGH;
+
+ if (mode->Clock < 20000)
+ return MODE_CLOCK_LOW;
+
+ return MODE_OK;
+}
+
+static Bool
+i830_hdmi_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ /* The HDMI output doesn't need the pixel multiplication that SDVO does,
+ * so no fixup.
+ */
+ return TRUE;
+}
+
+static void
+i830_hdmi_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_hdmi_priv *dev_priv = intel_output->dev_priv;
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcPtr crtc = output->crtc;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ uint32_t sdvox;
+
+ sdvox = SDVO_ENCODING_HDMI |
+ SDVO_BORDER_ENABLE |
+ SDVO_VSYNC_ACTIVE_HIGH |
+ SDVO_HSYNC_ACTIVE_HIGH;
+ if (intel_crtc->pipe == 1)
+ sdvox |= SDVO_PIPE_B_SELECT;
+
+ OUTREG(dev_priv->output_reg, sdvox);
+ POSTING_READ(dev_priv->output_reg);
+}
+
+static void
+i830_hdmi_dpms(xf86OutputPtr output, int mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_hdmi_priv *dev_priv = intel_output->dev_priv;
+ I830Ptr pI830 = I830PTR(pScrn);
+ uint32_t temp;
+
+ if (mode == DPMSModeOff) {
+ temp = INREG(dev_priv->output_reg);
+ OUTREG(dev_priv->output_reg, temp & ~SDVO_ENABLE);
+ } else {
+ temp = INREG(dev_priv->output_reg);
+ OUTREG(dev_priv->output_reg, temp | SDVO_ENABLE);
+ }
+}
+
+static void
+i830_hdmi_save(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_hdmi_priv *dev_priv = intel_output->dev_priv;
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ dev_priv->save_SDVO = INREG(dev_priv->output_reg);
+}
+
+static void
+i830_hdmi_restore(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_hdmi_priv *dev_priv = intel_output->dev_priv;
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ OUTREG(dev_priv->output_reg, dev_priv->save_SDVO);
+}
+
+/**
+ * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect HDMI connection.
+ *
+ * \return TRUE if HDMI port is connected.
+ * \return FALSE if HDMI port is disconnected.
+ */
+static xf86OutputStatus
+i830_hdmi_detect(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830OutputPrivatePtr intel_output = output->driver_private;
+ struct i830_hdmi_priv *dev_priv = intel_output->dev_priv;
+ I830Ptr pI830 = I830PTR(pScrn);
+ uint32_t temp, bit;
+
+ temp = INREG(PORT_HOTPLUG_EN);
+
+ OUTREG(PORT_HOTPLUG_EN,
+ temp |
+ HDMIB_HOTPLUG_INT_EN |
+ HDMIC_HOTPLUG_INT_EN |
+ HDMID_HOTPLUG_INT_EN);
+
+ POSTING_READ(PORT_HOTPLUG_EN);
+
+ switch (dev_priv->output_reg) {
+ case SDVOB:
+ bit = HDMIB_HOTPLUG_INT_STATUS;
+ break;
+ case SDVOC:
+ bit = HDMIC_HOTPLUG_INT_STATUS;
+ break;
+ default:
+ return XF86OutputStatusUnknown;
+ }
+
+ if ((INREG(PORT_HOTPLUG_STAT) & bit) != 0)
+ return XF86OutputStatusConnected;
+ else
+ return XF86OutputStatusDisconnected;
+}
+
+static void
+i830_hdmi_destroy (xf86OutputPtr output)
+{
+ I830OutputPrivatePtr intel_output = output->driver_private;
+
+ if (intel_output != NULL) {
+ xf86DestroyI2CBusRec(intel_output->pDDCBus, FALSE, FALSE);
+ xfree(intel_output);
+ }
+}
+
+static const xf86OutputFuncsRec i830_hdmi_output_funcs = {
+ .dpms = i830_hdmi_dpms,
+ .save = i830_hdmi_save,
+ .restore = i830_hdmi_restore,
+ .mode_valid = i830_hdmi_mode_valid,
+ .mode_fixup = i830_hdmi_mode_fixup,
+ .prepare = i830_output_prepare,
+ .mode_set = i830_hdmi_mode_set,
+ .commit = i830_output_commit,
+ .detect = i830_hdmi_detect,
+ .get_modes = i830_ddc_get_modes,
+ .destroy = i830_hdmi_destroy
+};
+
+void
+i830_hdmi_init(ScrnInfoPtr pScrn, int output_reg)
+{
+ xf86OutputPtr output;
+ I830OutputPrivatePtr intel_output;
+ struct i830_hdmi_priv *dev_priv;
+
+ output = xf86OutputCreate(pScrn, &i830_hdmi_output_funcs,
+ (output_reg == SDVOB) ? "HDMI-1" : "HDMI-2");
+ if (!output)
+ return;
+ intel_output = xnfcalloc(sizeof (I830OutputPrivateRec) +
+ sizeof (struct i830_hdmi_priv), 1);
+ if (intel_output == NULL) {
+ xf86OutputDestroy(output);
+ return;
+ }
+ output->driver_private = intel_output;
+ output->interlaceAllowed = FALSE;
+ output->doubleScanAllowed = FALSE;
+
+ dev_priv = (struct i830_hdmi_priv *)(intel_output + 1);
+ dev_priv->output_reg = output_reg;
+
+ intel_output->dev_priv = dev_priv;
+ intel_output->type = I830_OUTPUT_HDMI;
+ intel_output->pipe_mask = ((1 << 0) | (1 << 1));
+ intel_output->clone_mask = (1 << I830_OUTPUT_HDMI);
+
+ /* Set up the DDC bus. */
+ if (output_reg == SDVOB)
+ I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOE, "HDMIDDC_B");
+ else
+ I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "HDMIDDC_C");
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "HDMI output %d detected\n",
+ 1 + (output_reg - SDVOB));
+}
diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
index 7586ff71..787d93da 100644
--- a/src/i830_hwmc.c
+++ b/src/i830_hwmc.c
@@ -56,7 +56,7 @@ Bool intel_xvmc_probe(ScrnInfoPtr pScrn)
return FALSE;
if (IS_I9XX(pI830)) {
- if (!IS_I965G(pI830))
+ if (IS_I915(pI830))
ret = intel_xvmc_set_driver(&i915_xvmc_driver);
/*
else
@@ -122,9 +122,10 @@ Bool intel_xvmc_screen_init(ScreenPtr pScreen)
Bool intel_xvmc_init_batch(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
+ int size = KB(64);
if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC] batch buffer",
- &(xvmc_driver->batch), 8 * 1024,
+ &(xvmc_driver->batch), size,
ALIGN_BOTH_ENDS))
return FALSE;
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
index 6920e016..4db9aea6 100644
--- a/src/i830_hwmc.h
+++ b/src/i830_hwmc.h
@@ -47,6 +47,13 @@
#define XVMC_I945_MPEG2_VLD 0x04
#define XVMC_I965_MPEG2_VLD 0x08
+/* supported surface types */
+enum {
+ SURFACE_TYPE_MPEG2_MPML = FOURCC_XVMC, /* mpeg2 MP@ML */
+ SURFACE_TYPE_MPEG1_MPML, /* mpeg1 MP@ML */
+ SURFACE_TYPE_MAX
+};
+
/* common header for context private */
struct hwmc_buffer
{
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 899c6cbf..c7f24342 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -63,6 +63,9 @@ struct i830_lvds_priv {
/* The panel needs dithering enabled */
Bool panel_wants_dither;
+ /* The panel is in DPMS off */
+ Bool dpmsoff;
+
/* restore backlight to this value */
int backlight_duty_cycle;
@@ -80,6 +83,8 @@ struct i830_lvds_priv {
* List of available kernel interfaces in priority order
*/
static char *backlight_interfaces[] = {
+ "asus-laptop",
+ "eeepc",
"thinkpad_screen",
"acpi_video1",
"acpi_video0",
@@ -129,7 +134,7 @@ i830_set_lvds_backlight_method(xf86OutputPtr output)
if (i830_kernel_backlight_available(output)) {
method = BCM_KERNEL;
- } else if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) {
+ } else if (IS_I965GM(pI830) || IS_GM45(pI830)) {
blc_pwm_ctl2 = INREG(BLC_PWM_CTL2);
if (blc_pwm_ctl2 & BLM_LEGACY_MODE2)
method = BCM_COMBO;
@@ -177,7 +182,7 @@ i830_lvds_get_backlight_max_native(xf86OutputPtr output)
uint32_t pwm_ctl = INREG(BLC_PWM_CTL);
int val;
- if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) {
+ if (IS_I965GM(pI830) || IS_GM45(pI830)) {
val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >>
BACKLIGHT_MODULATION_FREQ_SHIFT2);
} else {
@@ -334,6 +339,7 @@ i830_lvds_get_backlight_kernel(xf86OutputPtr output)
return 0;
}
+ memset(val, 0, sizeof(val));
if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1)
goto out_err;
@@ -388,6 +394,10 @@ i830SetLVDSPanelPower(xf86OutputPtr output, Bool on)
uint32_t pp_status;
if (on) {
+ /* if we're going from on->on, be aware to current level. */
+ if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff)
+ dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
+
/*
* If we're going from off->on we may need to turn on the backlight.
* We should use the saved value whenever possible, but on some
@@ -405,12 +415,13 @@ i830SetLVDSPanelPower(xf86OutputPtr output, Bool on)
} while ((pp_status & PP_ON) == 0);
dev_priv->set_backlight(output, dev_priv->backlight_duty_cycle);
+ dev_priv->dpmsoff = FALSE;
} else {
/*
* Only save the current backlight value if we're going from
* on to off.
*/
- if (INREG(PP_CONTROL) & POWER_TARGET_ON)
+ if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff)
dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
dev_priv->set_backlight(output, 0);
@@ -418,6 +429,8 @@ i830SetLVDSPanelPower(xf86OutputPtr output, Bool on)
do {
pp_status = INREG(PP_STATUS);
} while (pp_status & PP_ON);
+
+ dev_priv->dpmsoff = TRUE;
}
}
@@ -440,14 +453,15 @@ i830_lvds_save (xf86OutputPtr output)
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
- if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+ if (IS_I965GM(pI830) || IS_GM45(pI830))
pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2);
pI830->savePP_ON = INREG(LVDSPP_ON);
pI830->savePP_OFF = INREG(LVDSPP_OFF);
pI830->savePP_CONTROL = INREG(PP_CONTROL);
pI830->savePP_CYCLE = INREG(PP_CYCLE);
pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL);
- dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
+ if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff)
+ dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
}
static void
@@ -456,7 +470,7 @@ i830_lvds_restore(xf86OutputPtr output)
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
- if (IS_I965GM(pI830) || IS_IGD_GM(pI830))
+ if (IS_I965GM(pI830) || IS_GM45(pI830))
OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2);
OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL);
OUTREG(LVDSPP_ON, pI830->savePP_ON);
@@ -1081,7 +1095,10 @@ i830_lvds_set_property(xf86OutputPtr output, Atom property,
"RRConfigureOutputProperty error, %d\n", ret);
}
/* Set the current value of the backlight property */
- data = dev_priv->get_backlight(output);
+ if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff)
+ data = dev_priv->get_backlight(output);
+ else
+ data = dev_priv->backlight_duty_cycle;
ret = RRChangeOutputProperty(output->randr_output, backlight_atom,
XA_INTEGER, 32, PropModeReplace, 1, &data,
FALSE, TRUE);
@@ -1130,6 +1147,8 @@ i830_lvds_set_property(xf86OutputPtr output, Atom property,
static Bool
i830_lvds_get_property(xf86OutputPtr output, Atom property)
{
+ ScrnInfoPtr pScrn = output->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
I830OutputPrivatePtr intel_output = output->driver_private;
struct i830_lvds_priv *dev_priv = intel_output->dev_priv;
int ret;
@@ -1140,8 +1159,11 @@ i830_lvds_get_property(xf86OutputPtr output, Atom property)
*/
if (property == backlight_atom) {
int val;
- val = dev_priv->get_backlight(output);
- dev_priv->backlight_duty_cycle = val;
+ if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff) {
+ val = dev_priv->get_backlight(output);
+ dev_priv->backlight_duty_cycle = val;
+ } else
+ val = dev_priv->backlight_duty_cycle;
ret = RRChangeOutputProperty(output->randr_output, backlight_atom,
XA_INTEGER, 32, PropModeReplace, 1, &val,
FALSE, TRUE);
@@ -1319,6 +1341,9 @@ i830_lvds_init(ScrnInfoPtr pScrn)
goto disable_exit;
}
+ /* Update pI830 w/SSC info, if any */
+ i830_bios_get_ssc(pScrn);
+
skip_panel_fixed_mode_setup:
/* Blacklist machines with BIOSes that list an LVDS panel without actually
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 3d6e245f..08a22019 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -450,7 +450,7 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
/* Overlay and cursors, if physical, need to be allocated outside
* of the kernel memory manager.
*/
- if (!OVERLAY_NOPHYSICAL(pI830) && !IS_IGD_GM(pI830)) {
+ if (!OVERLAY_NOPHYSICAL(pI830) && !OVERLAY_NOEXIST(pI830)) {
mmsize -= ROUND_TO(OVERLAY_SIZE, GTT_PAGE_SIZE);
}
if (pI830->CursorNeedsPhysical) {
@@ -462,7 +462,8 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
/* Can't do GEM on stolen memory */
mmsize -= pI830->stolen_size;
- if (HWS_NEED_GFX(pI830) && IS_IGD_GM(pI830))
+ /* new chipsets need non-stolen status page */
+ if (HWS_NEED_GFX(pI830) && HWS_NEED_NONSTOLEN(pI830))
mmsize -= HWSTATUS_PAGE_SIZE;
/* Create the aperture allocation */
@@ -1050,7 +1051,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn)
if (!pI830->XvEnabled)
return TRUE;
- if (IS_IGD_GM(pI830))
+ if (OVERLAY_NOEXIST(pI830))
return TRUE;
if (!OVERLAY_NOPHYSICAL(pI830))
@@ -1304,7 +1305,7 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
goto out;
}
- if (IS_IGD_GM(pI830)) {
+ if (IS_GM45(pI830)) {
/* Update i830_display.c too if compression ratio changes */
compressed_size = fb_height * (pScrn->displayWidth / 4);
} else {
@@ -1331,7 +1332,7 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
goto out;
}
- if (!IS_IGD_GM(pI830)) {
+ if (!IS_GM45(pI830)) {
pI830->compressed_ll_buffer =
i830_allocate_memory(pScrn, "compressed ll buffer",
FBC_LL_SIZE + FBC_LL_PAD, KB(4),
@@ -1681,7 +1682,7 @@ i830_allocate_hwstatus(ScrnInfoPtr pScrn)
* (i.e. not through buffer objects).
*/
flags = NEED_LIFETIME_FIXED;
- if (IS_IGD_GM(pI830))
+ if (HWS_NEED_NONSTOLEN(pI830))
flags |= NEED_NON_STOLEN;
pI830->hw_status = i830_allocate_memory(pScrn, "HW status",
HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, flags);
@@ -2054,6 +2055,7 @@ I830CheckAvailableMemory(ScrnInfoPtr pScrn)
return maxPages * 4;
}
+#ifdef INTEL_XVMC
/*
* Allocate memory for MC compensation
*/
@@ -2075,3 +2077,4 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
return TRUE;
}
+#endif
diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 1bd8885c..5eb01be5 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -266,7 +266,9 @@ static i830_quirk i830_quirk_list[] = {
{ PCI_CHIP_I965_GM, 0x144d, 0xc510, quirk_ignore_tv },
/* HP Compaq 6730s has no TV output */
- { PCI_CHIP_IGD_GM, 0x103c, 0x30e8, quirk_ignore_tv },
+ { PCI_CHIP_GM45_GM, 0x103c, 0x30e8, quirk_ignore_tv },
+ /* HP Pavilion ze4944ea needs pipe A force quirk (See LP: #242389) */
+ { PCI_CHIP_GM45_GM, 0x103c, 0x3084, quirk_pipea_force },
/* Thinkpad R31 needs pipe A force quirk */
{ PCI_CHIP_I830_M, 0x1014, 0x0505, quirk_pipea_force },
@@ -284,10 +286,15 @@ static i830_quirk i830_quirk_list[] = {
{ PCI_CHIP_I915_GM, 0x1179, 0x0001, quirk_pipea_force },
/* Intel 855GM hardware (See LP: #216490) */
{ PCI_CHIP_I855_GM, 0x1028, 0x00c8, quirk_pipea_force },
+ /* Intel 855GM hardware (See Novell Bugzilla #406123) */
+ { PCI_CHIP_I855_GM, 0x10cf, 0x1215, quirk_pipea_force },
/* ThinkPad X40 needs pipe A force quirk */
{ PCI_CHIP_I855_GM, 0x1014, 0x0557, quirk_pipea_force },
+ /* ThinkPad T60 needs pipe A force quirk (bug #16494) */
+ { PCI_CHIP_I945_GM, 0x17aa, 0x201a, quirk_pipea_force },
+
/* Sony vaio PCG-r600HFP (fix bug 13722) */
{ PCI_CHIP_I830_M, 0x104d, 0x8100, quirk_ivch_dvob },
/* Sony vaio VGN-SZ4MN (See LP: #212163) */
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 331059bf..d9b76d40 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -92,6 +92,9 @@ struct i830_sdvo_priv {
*/
struct i830_sdvo_tv_format tv_format;
+ /** supported encoding mode, used to determine whether HDMI is supported */
+ struct i830_sdvo_encode encode;
+
/** DDC bus used by this SDVO output */
uint8_t ddc_bus;
@@ -229,6 +232,19 @@ const static struct _sdvo_cmd_name {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS),
+ /* HDMI op code */
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE),
};
static I2CSlaveAddr slaveAddr;
@@ -741,6 +757,190 @@ i830_sdvo_get_mode_from_dtd(DisplayModePtr mode, struct i830_sdvo_dtd *dtd)
}
static Bool
+i830_sdvo_get_supp_encode(xf86OutputPtr output, struct i830_sdvo_encode *encode)
+{
+ uint8_t status;
+
+ i830_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
+ status = i830_sdvo_read_response(output, encode, sizeof(*encode));
+ if (status != SDVO_CMD_STATUS_SUCCESS) {
+ memset(encode, 0, sizeof(*encode));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+i830_sdvo_set_encode(xf86OutputPtr output, uint8_t mode)
+{
+ uint8_t status;
+
+ i830_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1);
+ status = i830_sdvo_read_response(output, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
+}
+
+static Bool
+i830_sdvo_set_colorimetry(xf86OutputPtr output, uint8_t mode)
+{
+ uint8_t status;
+
+ i830_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+ status = i830_sdvo_read_response(output, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
+}
+
+#if 0
+static Bool
+i830_sdvo_set_pixel_repli(xf86OutputPtr output, uint8_t repli)
+{
+ uint8_t status;
+
+ i830_sdvo_write_cmd(output, SDVO_CMD_SET_PIXEL_REPLI, &repli, 1);
+ status = i830_sdvo_read_response(output, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
+}
+#endif
+
+static void i830_sdvo_dump_hdmi_buf(xf86OutputPtr output)
+{
+ int i, j;
+ uint8_t set_buf_index[2];
+ uint8_t av_split;
+ uint8_t buf_size;
+ uint8_t buf[48];
+ uint8_t *pos;
+
+ i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
+ i830_sdvo_read_response(output, &av_split, 1);
+
+ for (i = 0; i <= av_split; i++) {
+ set_buf_index[0] = i; set_buf_index[1] = 0;
+ i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX,
+ set_buf_index, 2);
+ i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
+ i830_sdvo_read_response(output, &buf_size, 1);
+
+ pos = buf;
+ for (j = 0; j <= buf_size; j += 8) {
+ i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA, NULL, 0);
+ i830_sdvo_read_response(output, pos, 8);
+ pos += 8;
+ }
+ }
+}
+
+static void i830_sdvo_set_hdmi_buf(xf86OutputPtr output, int index,
+ uint8_t *data, int8_t size, uint8_t tx_rate)
+{
+ uint8_t set_buf_index[2];
+
+ set_buf_index[0] = index;
+ set_buf_index[1] = 0;
+
+ i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
+
+ for (; size > 0; size -= 8) {
+ i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8);
+ data += 8;
+ }
+
+ i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
+}
+
+static uint8_t i830_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
+{
+ uint8_t csum = 0;
+ int i;
+
+ for (i = 0; i < size; i++)
+ csum += data[i];
+
+ return 0x100 - csum;
+}
+
+#define DIP_TYPE_AVI 0x82
+#define DIP_VERSION_AVI 0x2
+#define DIP_LEN_AVI 13
+
+struct dip_infoframe {
+ uint8_t type;
+ uint8_t version;
+ uint8_t len;
+ uint8_t checksum;
+ union {
+ struct {
+ /* Packet Byte #1 */
+ uint8_t S:2;
+ uint8_t B:2;
+ uint8_t A:1;
+ uint8_t Y:2;
+ uint8_t rsvd1:1;
+ /* Packet Byte #2 */
+ uint8_t R:4;
+ uint8_t M:2;
+ uint8_t C:2;
+ /* Packet Byte #3 */
+ uint8_t SC:2;
+ uint8_t Q:2;
+ uint8_t EC:3;
+ uint8_t ITC:1;
+ /* Packet Byte #4 */
+ uint8_t VIC:7;
+ uint8_t rsvd2:1;
+ /* Packet Byte #5 */
+ uint8_t PR:4;
+ uint8_t rsvd3:4;
+ /* Packet Byte #6~13 */
+ uint16_t top_bar_end;
+ uint16_t bottom_bar_start;
+ uint16_t left_bar_end;
+ uint16_t right_bar_start;
+ } avi;
+ struct {
+ /* Packet Byte #1 */
+ uint8_t CC:3;
+ uint8_t rsvd1:1;
+ uint8_t CT:4;
+ /* Packet Byte #2 */
+ uint8_t SS:2;
+ uint8_t SF:3;
+ uint8_t rsvd2:3;
+ /* Packet Byte #3 */
+ uint8_t CXT:5;
+ uint8_t rsvd3:3;
+ /* Packet Byte #4 */
+ uint8_t CA;
+ /* Packet Byte #5 */
+ uint8_t rsvd4:3;
+ uint8_t LSV:4;
+ uint8_t DM_INH:1;
+ } audio;
+ uint8_t payload[28];
+ } __attribute__ ((packed)) u;
+} __attribute__((packed));
+
+static void i830_sdvo_set_avi_infoframe(xf86OutputPtr output,
+ DisplayModePtr mode)
+{
+ struct dip_infoframe avi_if = {
+ .type = DIP_TYPE_AVI,
+ .version = DIP_VERSION_AVI,
+ .len = DIP_LEN_AVI,
+ };
+
+ avi_if.u.avi.PR = i830_sdvo_get_pixel_multiplier(mode) - 1;
+ avi_if.checksum = i830_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
+ 4 + avi_if.len);
+ i830_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
+ SDVO_HBUF_TX_VSYNC);
+}
+
+static Bool
i830_sdvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
@@ -827,6 +1027,9 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
&in_out, sizeof(in_out));
status = i830_sdvo_read_response(output, NULL, 0);
+ if (dev_priv->encode.hdmi_rev)
+ i830_sdvo_set_avi_infoframe(output, mode);
+
i830_sdvo_get_dtd_from_mode(&input_dtd, mode);
/* If it's a TV, we already set the output timing in mode_fixup.
@@ -1203,6 +1406,15 @@ i830_sdvo_dump_device(xf86OutputPtr output)
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_TV_FORMAT);
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT);
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS);
+
+ i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPP_ENCODE);
+ i830_sdvo_dump_cmd(output, SDVO_CMD_GET_ENCODE);
+ i830_sdvo_dump_cmd(output, SDVO_CMD_GET_PIXEL_REPLI);
+ i830_sdvo_dump_cmd(output, SDVO_CMD_GET_COLORIMETRY_CAP);
+ i830_sdvo_dump_cmd(output, SDVO_CMD_GET_COLORIMETRY);
+ i830_sdvo_dump_cmd(output, SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER);
+ i830_sdvo_dump_cmd(output, SDVO_CMD_GET_AUDIO_STAT);
+ i830_sdvo_dump_hdmi_buf(output);
}
void
@@ -1503,7 +1715,7 @@ i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv)
dev_priv->ddc_bus = 1 << num_bits;
}
-void
+Bool
i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
{
xf86OutputPtr output;
@@ -1518,19 +1730,21 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
output = xf86OutputCreate (pScrn, &i830_sdvo_output_funcs,NULL);
if (!output)
- return;
+ return FALSE;
intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) +
sizeof (struct i830_sdvo_priv), 1);
if (!intel_output)
{
xf86OutputDestroy (output);
- return;
+ return FALSE;
}
output->driver_private = intel_output;
+ dev_priv = (struct i830_sdvo_priv *) (intel_output + 1);
+ intel_output->dev_priv = dev_priv;
+
output->interlaceAllowed = FALSE;
output->doubleScanAllowed = FALSE;
- dev_priv = (struct i830_sdvo_priv *) (intel_output + 1);
intel_output->type = I830_OUTPUT_SDVO;
intel_output->pipe_mask = ((1 << 0) | (1 << 1));
intel_output->clone_mask = (1 << I830_OUTPUT_SDVO);
@@ -1546,7 +1760,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
if (i2cbus == NULL)
{
xf86OutputDestroy (output);
- return;
+ return FALSE;
}
if (output_device == SDVOB) {
@@ -1568,11 +1782,10 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
"Failed to initialize %s I2C device\n",
SDVO_NAME(dev_priv));
xf86OutputDestroy (output);
- return;
+ return FALSE;
}
intel_output->pI2CBus = i2cbus;
- intel_output->dev_priv = dev_priv;
/* Read the regs to test if we can talk to the device */
for (i = 0; i < 0x40; i++) {
@@ -1581,7 +1794,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
"No SDVO device found on SDVO%c\n",
output_device == SDVOB ? 'B' : 'C');
xf86OutputDestroy (output);
- return;
+ return FALSE;
}
}
@@ -1594,7 +1807,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
if (ddcbus == NULL)
{
xf86OutputDestroy (output);
- return;
+ return FALSE;
}
if (output_device == SDVOB)
ddcbus->BusName = "SDVOB DDC Bus";
@@ -1611,7 +1824,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
if (!xf86I2CBusInit(ddcbus))
{
xf86OutputDestroy (output);
- return;
+ return FALSE;
}
intel_output->pI2CBus = i2cbus;
@@ -1620,17 +1833,22 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
i830_sdvo_get_capabilities(output, &dev_priv->caps);
- if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
- {
- dev_priv->controlled_output = SDVO_OUTPUT_TMDS0;
- output->subpixel_order = SubPixelHorizontalRGB;
- name_prefix="TMDS";
- }
- else if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
+ if (dev_priv->caps.output_flags & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
{
- dev_priv->controlled_output = SDVO_OUTPUT_TMDS1;
+ if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
+ dev_priv->controlled_output = SDVO_OUTPUT_TMDS0;
+ else
+ dev_priv->controlled_output = SDVO_OUTPUT_TMDS1;
output->subpixel_order = SubPixelHorizontalRGB;
name_prefix="TMDS";
+
+ i830_sdvo_get_supp_encode(output, &dev_priv->encode);
+ if (dev_priv->encode.hdmi_rev != 0) {
+ /* enable hdmi encoding mode if supported */
+ i830_sdvo_set_encode(output, SDVO_ENCODE_HDMI);
+ i830_sdvo_set_colorimetry(output, SDVO_COLORIMETRY_RGB256);
+ name_prefix = "HDMI";
+ }
}
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
{
@@ -1670,7 +1888,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
if (!xf86OutputRename (output, name))
{
xf86OutputDestroy (output);
- return;
+ return FALSE;
}
i830_sdvo_select_ddc_bus(dev_priv);
@@ -1718,4 +1936,5 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SCART1, "SCART1");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_LVDS1, "LVDS1");
+ return TRUE;
}
diff --git a/src/i830_sdvo.h b/src/i830_sdvo.h
index 1368e43b..798a88df 100644
--- a/src/i830_sdvo.h
+++ b/src/i830_sdvo.h
@@ -25,7 +25,7 @@
*
*/
-void
+Bool
i830_sdvo_init(ScrnInfoPtr pScrn, int output_device);
int
diff --git a/src/i830_sdvo_regs.h b/src/i830_sdvo_regs.h
index dc2522a3..747f2cdd 100644
--- a/src/i830_sdvo_regs.h
+++ b/src/i830_sdvo_regs.h
@@ -511,3 +511,39 @@ struct i830_sdvo_enhancements_arg {
# define SDVO_CONTROL_BUS_DDC2 (1 << 2)
# define SDVO_CONTROL_BUS_DDC3 (1 << 3)
+/* HDMI op codes */
+#define SDVO_CMD_GET_SUPP_ENCODE 0x9d
+#define SDVO_CMD_GET_ENCODE 0x9e
+#define SDVO_CMD_SET_ENCODE 0x9f
+ #define SDVO_ENCODE_DVI 0x0
+ #define SDVO_ENCODE_HDMI 0x1
+#define SDVO_CMD_SET_PIXEL_REPLI 0x8b
+#define SDVO_CMD_GET_PIXEL_REPLI 0x8c
+#define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d
+#define SDVO_CMD_SET_COLORIMETRY 0x8e
+ #define SDVO_COLORIMETRY_RGB256 0x0
+ #define SDVO_COLORIMETRY_RGB220 0x1
+ #define SDVO_COLORIMETRY_YCrCb422 0x3
+ #define SDVO_COLORIMETRY_YCrCb444 0x4
+#define SDVO_CMD_GET_COLORIMETRY 0x8f
+#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90
+#define SDVO_CMD_SET_AUDIO_STAT 0x91
+#define SDVO_CMD_GET_AUDIO_STAT 0x92
+#define SDVO_CMD_SET_HBUF_INDEX 0x93
+#define SDVO_CMD_GET_HBUF_INDEX 0x94
+#define SDVO_CMD_GET_HBUF_INFO 0x95
+#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96
+#define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97
+#define SDVO_CMD_SET_HBUF_DATA 0x98
+#define SDVO_CMD_GET_HBUF_DATA 0x99
+#define SDVO_CMD_SET_HBUF_TXRATE 0x9a
+#define SDVO_CMD_GET_HBUF_TXRATE 0x9b
+ #define SDVO_HBUF_TX_DISABLED (0 << 6)
+ #define SDVO_HBUF_TX_ONCE (2 << 6)
+ #define SDVO_HBUF_TX_VSYNC (3 << 6)
+#define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c
+
+struct i830_sdvo_encode{
+ uint8_t dvi_rev;
+ uint8_t hdmi_rev;
+} __attribute__ ((packed));
diff --git a/src/i830_tv.c b/src/i830_tv.c
index cde929a7..651f77b3 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1715,6 +1715,10 @@ i830_tv_init(ScrnInfoPtr pScrn)
(tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
return;
+ i830_bios_get_tv(pScrn);
+ if (!pI830->tv_present) /* VBIOS claims no TV connector */
+ return;
+
output = xf86OutputCreate (pScrn, &i830_tv_output_funcs, "TV");
if (!output)
diff --git a/src/i830_video.c b/src/i830_video.c
index e1095781..486f6708 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -620,7 +620,7 @@ I830InitVideo(ScreenPtr pScreen)
}
/* Set up overlay video if we can do it at this depth. */
- if (!IS_IGD_GM(pI830) && pScrn->bitsPerPixel != 8 &&
+ if (!OVERLAY_NOEXIST(pI830) && pScrn->bitsPerPixel != 8 &&
pI830->overlay_regs != NULL)
{
overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
@@ -2210,7 +2210,8 @@ I830PutImage(ScrnInfoPtr pScrn,
I830OverlayRegPtr overlay;
PixmapPtr pPixmap;
INT32 x1, x2, y1, y2;
- int srcPitch, srcPitch2 = 0, dstPitch, destId;
+ int srcPitch = 0, srcPitch2 = 0, dstPitch, destId;
+ int dstPitch2 = 0;
int top, left, npixels, nlines, size;
BoxRec dstBox;
int pitchAlignMask;
@@ -2285,13 +2286,11 @@ I830PutImage(ScrnInfoPtr pScrn,
case FOURCC_I420:
srcPitch = (width + 0x3) & ~0x3;
srcPitch2 = ((width >> 1) + 0x3) & ~0x3;
+ break;
#ifdef INTEL_XVMC
- if (pI830->IsXvMCSurface) {
- srcPitch = (width + 0x3ff) & ~0x3ff;
- srcPitch2 = ((width >> 1) + 0x3ff) & ~0x3ff;
- }
-#endif
+ case FOURCC_XVMC:
break;
+#endif
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
@@ -2304,6 +2303,11 @@ I830PutImage(ScrnInfoPtr pScrn,
*/
if (pPriv->textured) {
pitchAlignMask = 3;
+#ifdef INTEL_XVMC
+ /* for i915 xvmc, hw requires at least 1kb aligned surface */
+ if ((id == FOURCC_XVMC) && IS_I915(pI830))
+ pitchAlignMask = 0x3ff;
+#endif
} else {
if (IS_I965G(pI830))
pitchAlignMask = 255;
@@ -2317,9 +2321,6 @@ I830PutImage(ScrnInfoPtr pScrn,
switch (destId) {
case FOURCC_YV12:
case FOURCC_I420:
-#ifdef INTEL_XVMC
- case FOURCC_XVMC:
-#endif
if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
size = dstPitch * width * 3;
@@ -2339,7 +2340,14 @@ I830PutImage(ScrnInfoPtr pScrn,
size = dstPitch * height;
}
break;
- default:
+#ifdef INTEL_XVMC
+ case FOURCC_XVMC:
+ dstPitch = ((width / 2) + pitchAlignMask ) & ~pitchAlignMask;
+ dstPitch2 = (width + pitchAlignMask ) & ~pitchAlignMask;
+ size = 0;
+ break;
+#endif
+ default:
dstPitch = 0;
size = 0;
break;
@@ -2384,24 +2392,35 @@ I830PutImage(ScrnInfoPtr pScrn,
(pPriv->doubleBuffer ? size * 2 : size);
/* fixup pointers */
- pPriv->YBuf0offset = pPriv->buf->offset;
- if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
- pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width);
- pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2);
- if(pPriv->doubleBuffer) {
- pPriv->YBuf1offset = pPriv->YBuf0offset + size;
- pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width);
- pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2);
- }
+#ifdef INTEL_XVMC
+ if (id == FOURCC_XVMC && IS_I915(pI830)) {
+ pPriv->YBuf0offset = (uint32_t)buf;
+ pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height);
+ pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2);
+ destId = FOURCC_YV12;
} else {
- pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height);
- pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2);
- if(pPriv->doubleBuffer) {
- pPriv->YBuf1offset = pPriv->YBuf0offset + size;
- pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height);
- pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2);
+#endif
+ pPriv->YBuf0offset = pPriv->buf->offset;
+ if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width);
+ pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2);
+ if(pPriv->doubleBuffer) {
+ pPriv->YBuf1offset = pPriv->YBuf0offset + size;
+ pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * width);
+ pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * width / 2);
+ }
+ } else {
+ pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height);
+ pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height / 2);
+ if(pPriv->doubleBuffer) {
+ pPriv->YBuf1offset = pPriv->YBuf0offset + size;
+ pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height);
+ pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height / 2);
+ }
}
+#ifdef INTEL_XVMC
}
+#endif
/* Pick the idle buffer */
if (!pPriv->textured && *pI830->overlayOn && pPriv->doubleBuffer)
@@ -2473,7 +2492,7 @@ I830PutImage(ScrnInfoPtr pScrn,
src_w, src_h, drw_w, drw_h, pPixmap);
} else {
I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
- dstPitch, x1, y1, x2, y2,
+ dstPitch, dstPitch2, x1, y1, x2, y2,
src_w, src_h, drw_w, drw_h, pPixmap);
}
if (pPriv->textured) {
diff --git a/src/i830_video.h b/src/i830_video.h
index 52e6b4f8..91f767f9 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -78,7 +78,7 @@ typedef struct {
void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
int id, RegionPtr dstRegion, short width,
- short height, int video_pitch,
+ short height, int video_pitch, int video_pitch2,
int x1, int y1, int x2, int y2,
short src_w, short src_h,
short drw_w, short drw_h,
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
index 50e11068..659638e1 100644
--- a/src/i915_hwmc.c
+++ b/src/i915_hwmc.c
@@ -111,7 +111,7 @@ static XF86MCImageIDList yv12_subpicture_list =
static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
{
- FOURCC_YV12,
+ SURFACE_TYPE_MPEG2_MPML,
XVMC_CHROMA_FORMAT_420,
0,
720,
@@ -127,7 +127,7 @@ static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface =
{
- FOURCC_YV12,
+ SURFACE_TYPE_MPEG1_MPML,
XVMC_CHROMA_FORMAT_420,
0,
720,
@@ -319,8 +319,8 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
I830Ptr pI830 = I830PTR(pScrn);
int flags = ALIGN_BOTH_ENDS;
- if (IS_I915G(pI830) || IS_I915GM(pI830) ||
- IS_I945G(pI830) || IS_I945GM(pI830))
+ /* on 915G/GM, load indirect can only use physical address...sigh */
+ if (IS_I915G(pI830) || IS_I915GM(pI830))
flags |= NEED_PHYSICAL_ADDR;
if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Static Indirect State",
@@ -353,14 +353,14 @@ static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *c
return FALSE;
}
- if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer",
+ if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Correction Data Buffer",
&(ctxpriv->mcCorrdata), 512 * 1024,
ALIGN_BOTH_ENDS)) {
return FALSE;
}
- if (0)
- i830_describe_allocations(pScrn, 1, "");
+ if (1)
+ i830_describe_allocations(pScrn, 1, "i915_mc: ");
return TRUE;
}
@@ -500,29 +500,32 @@ static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
contextRec->sis.handle = ctxpriv->sis_handle;
contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset;
contextRec->sis.size = ctxpriv->mcStaticIndirectState->size;
- contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr;
contextRec->ssb.handle = ctxpriv->ssb_handle;
contextRec->ssb.offset = ctxpriv->mcSamplerState->offset;
contextRec->ssb.size = ctxpriv->mcSamplerState->size;
- contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr;
contextRec->msb.handle = ctxpriv->msb_handle;
contextRec->msb.offset = ctxpriv->mcMapState->offset;
contextRec->msb.size = ctxpriv->mcMapState->size;
- contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr;
contextRec->psp.handle = ctxpriv->psp_handle;
contextRec->psp.offset = ctxpriv->mcPixelShaderProgram->offset;
contextRec->psp.size = ctxpriv->mcPixelShaderProgram->size;
- contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr;
contextRec->psc.handle = ctxpriv->psc_handle;
contextRec->psc.offset = ctxpriv->mcPixelShaderConstants->offset;
contextRec->psc.size = ctxpriv->mcPixelShaderConstants->size;
- contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr;
contextRec->corrdata.handle = ctxpriv->corrdata_handle;
contextRec->corrdata.offset = ctxpriv->mcCorrdata->offset;
contextRec->corrdata.size = ctxpriv->mcCorrdata->size;
contextRec->sarea_priv_offset = sizeof(XF86DRISAREARec);
contextRec->deviceID = pI830DRI->deviceID;
+ if (IS_I915G(pI830) || IS_I915GM(pI830)) {
+ contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr;
+ contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr;
+ contextRec->msb.bus_addr = ctxpriv->mcMapState->bus_addr;
+ contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr;
+ contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr;
+ }
+
pXvMC->ncontexts++;
pXvMC->contexts[i] = pContext->context_id;
pXvMC->ctxprivs[i] = ctxpriv;
@@ -787,7 +790,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
short height, Bool sync, RegionPtr clipBoxes, pointer data,
DrawablePtr pDraw)
{
- I830Ptr pI830 = I830PTR(pScrn);
I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
struct intel_xvmc_command *xvmc_cmd = (struct intel_xvmc_command *)buf;
int ret;
@@ -803,10 +805,8 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
return 1;
}
- buf = pI830->FbBase +
- pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset;
- id = xvmc_cmd->real_id;
- pI830->IsXvMCSurface = 1;
+ /* use char *buf to hold our surface offset...hacky! */
+ buf = (unsigned char *)pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset;
break;
default:
return 0;
@@ -816,7 +816,6 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
ret = pXvMC->savePutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h,
drw_w, drw_h, id, buf, width, height, sync, clipBoxes,
data, pDraw);
- pI830->IsXvMCSurface = 0;
return ret;
}
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
index 7d90afcc..8f6557da 100644
--- a/src/i915_hwmc.h
+++ b/src/i915_hwmc.h
@@ -29,6 +29,7 @@
#include "i830_hwmc.h"
+/* i915 hw requires surface to be at least 1KB aligned */
#define STRIDE(w) (((w) + 0x3ff) & ~0x3ff)
#define SIZE_Y420(w, h) (h * STRIDE(w))
#define SIZE_UV420(w, h) ((h >> 1) * STRIDE(w >> 1))
diff --git a/src/i915_video.c b/src/i915_video.c
index e27854ee..e2954a76 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -42,7 +42,7 @@
void
I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
RegionPtr dstRegion,
- short width, short height, int video_pitch,
+ short width, short height, int video_pitch, int video_pitch2,
int x1, int y1, int x2, int y2,
short src_w, short src_h, short drw_w, short drw_h,
PixmapPtr pPixmap)
@@ -271,7 +271,13 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
OUT_BATCH(ms3);
- OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT);
+ /* check to see if Y has special pitch than normal double u/v pitch,
+ * e.g i915 XvMC hw requires at least 1K alignment, so Y pitch might
+ * be same as U/V's.*/
+ if (video_pitch2)
+ OUT_BATCH(((video_pitch2 / 4) - 1) << MS4_PITCH_SHIFT);
+ else
+ OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT);
OUT_BATCH(pPriv->UBuf0offset);
ms3 = MAPSURF_8BIT | MT_8BIT_I8 | MS3_USE_FENCE_REGS;
diff --git a/src/i965_render.c b/src/i965_render.c
index 4a8f9b86..1cbfe242 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -59,6 +59,9 @@ do { \
} while(0)
#endif
+#define MAX_VERTEX_PER_COMPOSITE 24
+#define MAX_VERTEX_BUFFERS 256
+
struct blendinfo {
Bool dst_alpha;
Bool src_alpha;
@@ -500,7 +503,7 @@ typedef struct _gen4_state {
struct brw_cc_viewport cc_viewport;
PAD64 (brw_cc_viewport, 0);
- float vb[(2 + 3 + 3) * 3]; /* (dst, src, mask) 3 vertices, 4 bytes */
+ float vb[MAX_VERTEX_PER_COMPOSITE * MAX_VERTEX_BUFFERS];
} gen4_state_t;
/** Private data for gen4 render accel implementation. */
@@ -510,6 +513,8 @@ struct gen4_render_state {
int binding_table_index;
int surface_state_index;
+ int vb_offset;
+ int vertex_size;
};
/**
@@ -968,6 +973,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
i830WaitSync(pScrn);
render_state->binding_table_index = 0;
render_state->surface_state_index = 0;
+ render_state->vb_offset = 0;
}
binding_table = card_state->binding_table +
@@ -1035,7 +1041,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
BEGIN_BATCH(12);
/* Match Mesa driver setup */
- if (IS_IGD_GM(pI830))
+ if (IS_GM45(pI830) || IS_G4X(pI830))
OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
else
OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
@@ -1195,6 +1201,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
int selem = is_affine ? 2 : 3;
uint32_t w_component;
uint32_t src_format;
+
+ render_state->vertex_size = 4 * (2 + nelem * selem);
if (is_affine)
{
@@ -1206,17 +1214,9 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
src_format = BRW_SURFACEFORMAT_R32G32B32_FLOAT;
w_component = BRW_VFCOMPONENT_STORE_SRC;
}
- BEGIN_BATCH(pMask?12:10);
- /* Set up the pointer to our (single) vertex buffer */
- OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3);
- OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
- VB0_VERTEXDATA |
- ((4 * (2 + nelem * selem)) << VB0_BUFFER_PITCH_SHIFT));
- OUT_BATCH(state_base_offset + offsetof(gen4_state_t, vb));
- OUT_BATCH(3);
- OUT_BATCH(0); // ignore for VERTEXDATA, but still there
-
+ BEGIN_BATCH(pMask?7:5);
/* Set up our vertex elements, sourced from the single vertex buffer.
+ * that will be set up later.
*/
OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * (1 + nelem)) - 1));
@@ -1271,6 +1271,7 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
gen4_state_t *card_state = pI830->gen4_render_state->card_state;
+ struct gen4_render_state *render_state = pI830->gen4_render_state;
Bool has_mask;
Bool is_affine_src, is_affine_mask, is_affine;
float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
@@ -1351,12 +1352,12 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
}
}
- /* Wait for any existing composite rectangles to land before we overwrite
- * the VB with the next one.
- */
- i830WaitSync(pScrn);
+ if (render_state->vb_offset + MAX_VERTEX_PER_COMPOSITE >= ARRAY_SIZE(card_state->vb)) {
+ i830WaitSync(pScrn);
+ render_state->vb_offset = 0;
+ }
- i = 0;
+ i = render_state->vb_offset;
/* rect (x2,y2) */
vb[i++] = (float)(dstX + w);
vb[i++] = (float)(dstY + h);
@@ -1400,20 +1401,32 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
}
assert (i * 4 <= sizeof(card_state->vb));
- {
- BEGIN_BATCH(6);
- OUT_BATCH(BRW_3DPRIMITIVE |
- BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
- (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) |
- (0 << 9) | /* CTG - indirect vertex count */
- 4);
- OUT_BATCH(3); /* vertex count per instance */
- OUT_BATCH(0); /* start vertex offset */
- OUT_BATCH(1); /* single instance */
- OUT_BATCH(0); /* start instance location */
- OUT_BATCH(0); /* index buffer offset, ignored */
- ADVANCE_BATCH();
- }
+ BEGIN_BATCH(12);
+ OUT_BATCH(MI_FLUSH);
+ /* Set up the pointer to our (single) vertex buffer */
+ OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3);
+ OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) |
+ VB0_VERTEXDATA |
+ (render_state->vertex_size << VB0_BUFFER_PITCH_SHIFT));
+ OUT_BATCH(render_state->card_state_offset + offsetof(gen4_state_t, vb) +
+ render_state->vb_offset * 4);
+ OUT_BATCH(3);
+ OUT_BATCH(0); // ignore for VERTEXDATA, but still there
+
+ OUT_BATCH(BRW_3DPRIMITIVE |
+ BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
+ (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) |
+ (0 << 9) | /* CTG - indirect vertex count */
+ 4);
+ OUT_BATCH(3); /* vertex count per instance */
+ OUT_BATCH(0); /* start vertex offset */
+ OUT_BATCH(1); /* single instance */
+ OUT_BATCH(0); /* start instance location */
+ OUT_BATCH(0); /* index buffer offset, ignored */
+ ADVANCE_BATCH();
+
+ render_state->vb_offset = i;
+
#ifdef I830DEBUG
ErrorF("sync after 3dprimitive\n");
I830Sync(pScrn);
diff --git a/src/i965_video.c b/src/i965_video.c
index 485c89a0..4c79259b 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -584,7 +584,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
{
BEGIN_BATCH(12);
/* Match Mesa driver setup */
- if (IS_IGD_GM(pI830))
+ if (IS_GM45(pI830) || IS_G4X(pI830))
OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
else
OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
diff --git a/src/reg_dumper/.gitignore b/src/reg_dumper/.gitignore
index f72a165e..b0f9b6f2 100644
--- a/src/reg_dumper/.gitignore
+++ b/src/reg_dumper/.gitignore
@@ -1,3 +1,4 @@
+intel_hotplug
intel_idle
intel_reg_dumper
intel_stepping
diff --git a/src/reg_dumper/Makefile.am b/src/reg_dumper/Makefile.am
index 1c8db204..11275814 100644
--- a/src/reg_dumper/Makefile.am
+++ b/src/reg_dumper/Makefile.am
@@ -1,4 +1,4 @@
-noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping intel_statuspage
+noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping intel_statuspage intel_hotplug
intel_reg_dumper_SOURCES = \
main.c \
@@ -12,6 +12,12 @@ intel_idle_SOURCES = \
xprintf.c \
../i830_debug.c
+intel_hotplug_SOURCES = \
+ hotplug.c \
+ reg_dumper.h \
+ xprintf.c \
+ ../i830_debug.c
+
intel_stepping_SOURCES = \
stepping.c
@@ -20,6 +26,7 @@ intel_statuspage_SOURCES = \
reg_dumper.h \
util.c
+intel_hotplug_LDADD = $(PCIACCESS_LIBS)
intel_reg_dumper_LDADD = $(PCIACCESS_LIBS)
intel_idle_LDADD = $(PCIACCESS_LIBS)
intel_stepping_LDADD = $(PCIACCESS_LIBS)
diff --git a/src/reg_dumper/hotplug.c b/src/reg_dumper/hotplug.c
new file mode 100644
index 00000000..68fe5842
--- /dev/null
+++ b/src/reg_dumper/hotplug.c
@@ -0,0 +1,151 @@
+/*
+ * 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 <unistd.h>
+
+#include "reg_dumper.h"
+#include "../i810_reg.h"
+
+struct idle_flags {
+ uint32_t instdone_flag;
+ char *name;
+ unsigned int count;
+};
+
+int main(int argc, char **argv)
+{
+ struct pci_device *dev;
+ I830Rec i830;
+ I830Ptr pI830 = &i830;
+ ScrnInfoRec scrn;
+ int err, mmio_bar;
+ void *mmio;
+ int i;
+
+ 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");
+
+ err = pci_device_probe(dev);
+ if (err != 0) {
+ fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err));
+ exit(1);
+ }
+
+ if (dev->vendor_id != 0x8086)
+ errx(1, "Graphics card is non-intel");
+
+ 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_range (dev,
+ dev->regions[mmio_bar].base_addr,
+ dev->regions[mmio_bar].size,
+ PCI_DEV_MAP_FLAG_WRITABLE,
+ &mmio);
+
+ if (err != 0) {
+ fprintf(stderr, "Couldn't map MMIO region: %s\n", strerror(err));
+ exit(1);
+ }
+ i830.mmio = mmio;
+
+ scrn.scrnIndex = 0;
+ scrn.pI830 = &i830;
+
+ OUTREG(SDVOB, (0x0 << 10));
+ OUTREG(SDVOC, (0x0 << 10));
+
+ OUTREG(PORT_HOTPLUG_EN,
+ (1 << 29) |
+ (1 << 28) |
+ (1 << 27) |
+ SDVOB_HOTPLUG_INT_EN |
+ SDVOC_HOTPLUG_INT_EN |
+ (1 << 24) |
+ CRT_HOTPLUG_INT_EN |
+ TV_HOTPLUG_INT_EN |
+ CRT_HOTPLUG_INT_EN);
+
+ for (i = 0;; i++) {
+ OUTREG(PORT_HOTPLUG_STAT,
+ (1 << 20) |
+ (1 << 19) |
+ (1 << 18) |
+ (1 << 17) |
+ CRT_HOTPLUG_INT_STATUS |
+ TV_HOTPLUG_INT_STATUS |
+ SDVOC_HOTPLUG_INT_STATUS |
+ SDVOB_HOTPLUG_INT_STATUS);
+ INREG(PORT_HOTPLUG_STAT);
+
+ usleep(500 * 1000);
+
+ printf("%5d: 0x%08x\n", i, INREG(PORT_HOTPLUG_STAT));
+ sleep(1);
+ }
+
+ 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/xvmc/I810XvMC.c b/src/xvmc/I810XvMC.c
index 03be2514..ce5395ac 100644
--- a/src/xvmc/I810XvMC.c
+++ b/src/xvmc/I810XvMC.c
@@ -130,7 +130,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
int surface_type_id, int width, int height, int flags,
XvMCContext *context) {
i810XvMCContext *pI810XvMC;
- char busIdString[10];
int priv_count;
uint *priv_data;
uint magic;
@@ -217,7 +216,6 @@ Status XvMCCreateContext(Display *display, XvPortID port,
/* Open DRI Device */
if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) {
printf("DRM Device for i810 could not be opened.\n");
- free(busIdString);
free(pI810XvMC);
return BadAccess;
} /* !pI810XvMC->fd */
diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
index a25d7349..b5185cb7 100644
--- a/src/xvmc/i915_structs.h
+++ b/src/xvmc/i915_structs.h
@@ -28,6 +28,8 @@
#ifndef _I915_STRUCTS_H
#define _I915_STRUCTS_H
+#include <stdint.h>
+
/* MI_INSTRUCTION */
#define CMD_MI 0x00
@@ -352,7 +354,7 @@ struct i915_3dstate_dest_buffer_variables_mpeg
unsigned rcontrol : 1;
unsigned decode_mode : 2;
} dw1;
-
+
struct {
unsigned pad0 : 1;
unsigned picture_coding_type : 2;
@@ -372,6 +374,15 @@ struct i915_3dstate_dest_buffer_variables_mpeg
} dw2;
};
+struct i915_mc_static_indirect_state_buffer {
+ struct i915_3dstate_buffer_info dest_y;
+ struct i915_3dstate_buffer_info dest_u;
+ struct i915_3dstate_buffer_info dest_v;
+ struct i915_3dstate_dest_buffer_variables dest_buf;
+ struct i915_3dstate_dest_buffer_variables_mpeg dest_buf_mpeg;
+ struct i915_3dstate_buffer_info corr;
+};
+
#define MAP_MAP0 0x0001
#define MAP_MAP1 0x0002
#define MAP_MAP2 0x0004
@@ -432,7 +443,18 @@ struct i915_3dstate_map_state
unsigned map_mask : 16;
unsigned pad0 : 16;
} dw1;
-// struct texture_map *tms;
+};
+
+struct i915_mc_map_state {
+ struct i915_3dstate_map_state y_map;
+ struct texture_map y_forward;
+ struct texture_map y_backward;
+ struct i915_3dstate_map_state u_map;
+ struct texture_map u_forward;
+ struct texture_map u_backward;
+ struct i915_3dstate_map_state v_map;
+ struct texture_map v_forward;
+ struct texture_map v_backward;
};
#define SAMPLER_SAMPLER0 0x0001
@@ -532,6 +554,9 @@ struct i915_3dstate_sampler_state
unsigned sampler_masker : 16;
unsigned pad0 : 16;
} dw1;
+ /* we always use two samplers for mc */
+ struct texture_sampler sampler0;
+ struct texture_sampler sampler1;
};
struct arithmetic_inst
@@ -641,17 +666,48 @@ union shader_inst
struct declaration_inst d;
};
+struct i915_3dstate_pixel_shader_header {
+ unsigned length : 9;
+ unsigned pad0 : 6;
+ unsigned retain : 1;
+ unsigned opcode : 13;
+ unsigned type : 3;
+};
+
struct i915_3dstate_pixel_shader_program
{
- struct {
- unsigned length : 9;
- unsigned pad0 : 6;
- unsigned retain : 1;
- unsigned opcode : 13;
- unsigned type : 3;
- } dw0;
-
- // union shader_inst *insts;
+ struct i915_3dstate_pixel_shader_header shader0;
+ /* mov oC, c0.0000 */
+ uint32_t inst0[3];
+
+ struct i915_3dstate_pixel_shader_header shader1;
+ /* dcl t0.xy */
+ /* dcl t1.xy */
+ /* dcl_2D s0 */
+ /* texld r0, t0, s0 */
+ /* mov oC, r0 */
+ uint32_t inst1[3*5];
+
+ struct i915_3dstate_pixel_shader_header shader2;
+ /* dcl t2.xy */
+ /* dcl t3.xy */
+ /* dcl_2D s1 */
+ /* texld r0, t2, s1 */
+ /* mov oC, r0 */
+ uint32_t inst2[3*5];
+
+ struct i915_3dstate_pixel_shader_header shader3;
+ /* dcl t0.xy */
+ /* dcl t1.xy */
+ /* dcl t2.xy */
+ /* dcl t3.xy */
+ /* dcl_2D s0 */
+ /* dcl_2D s1 */
+ /* texld r0, t0, s0 */
+ /* texld r0, t2, s1 */
+ /* add r0, r0, r1*/
+ /* mov oC, r0 */
+ uint32_t inst3[3*10];
};
#define REG_CR0 0x00000001
@@ -707,7 +763,8 @@ struct i915_3dstate_pixel_shader_constants
struct {
unsigned reg_mask;
} dw1;
- // struct shader_constant *consts;
+ /* we only need one constant */
+ struct shader_constant value;
};
#define BLOCK_SIS 0x01
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
index 519de5a3..c32073a1 100644
--- a/src/xvmc/i915_xvmc.c
+++ b/src/xvmc/i915_xvmc.c
@@ -39,9 +39,9 @@
SIZE_Y420(surface->width, surface->height))
typedef union {
- short s[4];
- uint u[2];
-} su_t;
+ int16_t component[2];
+ int32_t v;
+} vector_t;
#if 0
static int findOverlap(unsigned int width, unsigned int height,
@@ -81,577 +81,6 @@ static int findOverlap(unsigned int width, unsigned int height,
}
#endif
-static void i915_flush(int map, int render)
-{
- struct i915_mi_flush mi_flush;
-
- memset(&mi_flush, 0, sizeof(mi_flush));
- mi_flush.dw0.type = CMD_MI;
- mi_flush.dw0.opcode = OPC_MI_FLUSH;
- mi_flush.dw0.map_cache_invalidate = map;
- mi_flush.dw0.render_cache_flush_inhibit = render;
-
- intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
-}
-
-/* for MC picture rendering */
-static void i915_mc_static_indirect_state_buffer(XvMCContext *context,
- XvMCSurface *surface,
- unsigned int picture_structure,
- unsigned int flags,
- unsigned int picture_coding_type)
-{
- struct i915_3dstate_buffer_info *buffer_info;
- struct i915_3dstate_dest_buffer_variables *dest_buffer_variables;
- struct i915_3dstate_dest_buffer_variables_mpeg *dest_buffer_variables_mpeg;
- i915XvMCSurface *pI915Surface = (i915XvMCSurface *)surface->privData;
- i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
- unsigned int w = surface->width;
-
- /* 3DSTATE_BUFFER_INFO */
- /* DEST Y */
- buffer_info = (struct i915_3dstate_buffer_info *)pI915XvMC->sis.map;
- memset(buffer_info, 0, sizeof(*buffer_info));
- buffer_info->dw0.type = CMD_3D;
- buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
- buffer_info->dw0.length = 1;
- buffer_info->dw1.aux_id = 0;
- buffer_info->dw1.buffer_id = BUFFERID_COLOR_BACK;
- buffer_info->dw1.fence_regs = 0; /* disabled */ /* FIXME: tiled y for performance */
- buffer_info->dw1.tiled_surface = 0; /* linear */
- buffer_info->dw1.walk = TILEWALK_XMAJOR;
- buffer_info->dw1.pitch = (pI915Surface->yStride >> 2); /* in DWords */
- buffer_info->dw2.base_address = (YOFFSET(pI915Surface) >> 2); /* starting DWORD address */
-
- /* DEST U */
- ++buffer_info;
- memset(buffer_info, 0, sizeof(*buffer_info));
- buffer_info->dw0.type = CMD_3D;
- buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
- buffer_info->dw0.length = 1;
- buffer_info->dw1.aux_id = 0;
- buffer_info->dw1.buffer_id = BUFFERID_COLOR_AUX;
- buffer_info->dw1.fence_regs = 0;
- buffer_info->dw1.tiled_surface = 0;
- buffer_info->dw1.walk = TILEWALK_XMAJOR;
- buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2); /* in DWords */
- buffer_info->dw2.base_address = (UOFFSET(pI915Surface) >> 2); /* starting DWORD address */
-
- /* DEST V */
- ++buffer_info;
- memset(buffer_info, 0, sizeof(*buffer_info));
- buffer_info->dw0.type = CMD_3D;
- buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
- buffer_info->dw0.length = 1;
- buffer_info->dw1.aux_id = 1;
- buffer_info->dw1.buffer_id = BUFFERID_COLOR_AUX;
- buffer_info->dw1.fence_regs = 0;
- buffer_info->dw1.tiled_surface = 0;
- buffer_info->dw1.walk = TILEWALK_XMAJOR;
- buffer_info->dw1.pitch = (pI915Surface->uvStride >> 2); /* in Dwords */
- buffer_info->dw2.base_address = (VOFFSET(pI915Surface) >> 2); /* starting DWORD address */
-
- /* 3DSTATE_DEST_BUFFER_VARIABLES */
- dest_buffer_variables = (struct i915_3dstate_dest_buffer_variables *)(++buffer_info);
- memset(dest_buffer_variables, 0, sizeof(*dest_buffer_variables));
- dest_buffer_variables->dw0.type = CMD_3D;
- dest_buffer_variables->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES;
- dest_buffer_variables->dw0.length = 0;
- dest_buffer_variables->dw1.dest_v_bias = 8; /* 0.5 */
- dest_buffer_variables->dw1.dest_h_bias = 8; /* 0.5 */
- dest_buffer_variables->dw1.color_fmt = COLORBUFFER_8BIT;
- dest_buffer_variables->dw1.v_ls = 0;
- dest_buffer_variables->dw1.v_ls_offset = 0;
-
- if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
- ;
- } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) {
- dest_buffer_variables->dw1.v_ls = 1;
- } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) {
- dest_buffer_variables->dw1.v_ls = 1;
- dest_buffer_variables->dw1.v_ls_offset = 1;
- }
-
- /* 3DSTATE_DEST_BUFFER_VARIABLES_MPEG */
- dest_buffer_variables_mpeg = (struct i915_3dstate_dest_buffer_variables_mpeg *)(++dest_buffer_variables);
- memset(dest_buffer_variables_mpeg, 0, sizeof(*dest_buffer_variables_mpeg));
- dest_buffer_variables_mpeg->dw0.type = CMD_3D;
- dest_buffer_variables_mpeg->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG;
- dest_buffer_variables_mpeg->dw0.length = 1;
- dest_buffer_variables_mpeg->dw1.decode_mode = MPEG_DECODE_MC;
- dest_buffer_variables_mpeg->dw1.rcontrol = 0; /* for MPEG-1/MPEG-2 */
- dest_buffer_variables_mpeg->dw1.bidir_avrg_control = 0; /* for MPEG-1/MPEG-2/MPEG-4 */
- dest_buffer_variables_mpeg->dw1.abort_on_error = 1;
- dest_buffer_variables_mpeg->dw1.intra8 = 0; /* 16-bit formatted correction data */
- dest_buffer_variables_mpeg->dw1.tff = 1;
-
- if (picture_structure & XVMC_FRAME_PICTURE) {
- ;
- } else if (picture_structure & XVMC_TOP_FIELD) {
- if (flags & XVMC_SECOND_FIELD)
- dest_buffer_variables_mpeg->dw1.tff = 0;
- else
- dest_buffer_variables_mpeg->dw1.tff = 1;
- } else if (picture_structure & XVMC_BOTTOM_FIELD) {
- if (flags & XVMC_SECOND_FIELD)
- dest_buffer_variables_mpeg->dw1.tff = 1;
- else
- dest_buffer_variables_mpeg->dw1.tff = 0;
- }
-
- dest_buffer_variables_mpeg->dw1.v_subsample_factor = MC_SUB_1V;
- dest_buffer_variables_mpeg->dw1.h_subsample_factor = MC_SUB_1H;
- dest_buffer_variables_mpeg->dw1.picture_width = (w >> 4); /* in macroblocks */
- dest_buffer_variables_mpeg->dw2.picture_coding_type = picture_coding_type;
-
- /* 3DSATE_BUFFER_INFO */
- /* CORRECTION DATA */
- buffer_info = (struct i915_3dstate_buffer_info *)(++dest_buffer_variables_mpeg);
- memset(buffer_info, 0, sizeof(*buffer_info));
- buffer_info->dw0.type = CMD_3D;
- buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
- buffer_info->dw0.length = 1;
- buffer_info->dw1.aux_id = 0;
- buffer_info->dw1.buffer_id = BUFFERID_MC_INTRA_CORR;
- buffer_info->dw1.aux_id = 0;
- buffer_info->dw1.fence_regs = 0;
- buffer_info->dw1.tiled_surface = 0;
- buffer_info->dw1.walk = 0;
- buffer_info->dw1.pitch = 0;
- buffer_info->dw2.base_address = (pI915XvMC->corrdata.offset >> 2); /* starting DWORD address */
-}
-
-static void i915_mc_map_state_buffer(XvMCContext *context,
- i915XvMCSurface *privTarget,
- i915XvMCSurface *privPast,
- i915XvMCSurface *privFuture)
-{
- struct i915_3dstate_map_state *map_state;
- struct texture_map *tm;
- i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
- unsigned int w = context->width, h = context->height;
-
- /* 3DSATE_MAP_STATE: Y */
- map_state = (struct i915_3dstate_map_state *)pI915XvMC->msb.map;
- memset(map_state, 0, sizeof(*map_state));
- map_state->dw0.type = CMD_3D;
- map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE;
- map_state->dw0.retain = 1;
- map_state->dw0.length = 6;
- map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1;
-
- /* texture map: Forward (Past) */
- tm = (struct texture_map *)(++map_state);
- memset(tm, 0, sizeof(*tm));
- tm->tm0.v_ls_offset = 0;
- tm->tm0.v_ls = 0;
- tm->tm0.base_address = (YOFFSET(privPast) >> 2);
- tm->tm1.tile_walk = TILEWALK_XMAJOR; /* FIXME: tiled y for performace */
- tm->tm1.tiled_surface = 0;
- tm->tm1.utilize_fence_regs = 0;
- tm->tm1.texel_fmt = 0; /* 8bit */
- tm->tm1.surface_fmt = 1; /* 8bit */
- tm->tm1.width = w - 1;
- tm->tm1.height = h - 1;
- tm->tm2.depth = 0;
- tm->tm2.max_lod = 0;
- tm->tm2.cube_face = 0;
- tm->tm2.pitch = (privPast->yStride >> 2) - 1; /* in DWords - 1 */
-
- /* texture map: Backward (Future) */
- ++tm;
- memset(tm, 0, sizeof(*tm));
- tm->tm0.v_ls_offset = 0;
- tm->tm0.v_ls = 0;
- tm->tm0.base_address = (YOFFSET(privFuture) >> 2);
- tm->tm1.tile_walk = TILEWALK_XMAJOR;
- tm->tm1.tiled_surface = 0;
- tm->tm1.utilize_fence_regs = 0;
- tm->tm1.texel_fmt = 0; /* 8bit */
- tm->tm1.surface_fmt = 1; /* 8bit */
- tm->tm1.width = w - 1;
- tm->tm1.height = h - 1;
- tm->tm2.depth = 0;
- tm->tm2.max_lod = 0;
- tm->tm2.cube_face = 0;
- tm->tm2.pitch = (privFuture->yStride >> 2) - 1;
-
- /* 3DSATE_MAP_STATE: U */
- map_state = (struct i915_3dstate_map_state *)(++tm);
- memset(map_state, 0, sizeof(*map_state));
- map_state->dw0.type = CMD_3D;
- map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE;
- map_state->dw0.retain = 1;
- map_state->dw0.length = 6;
- map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1;
-
- /* texture map: Forward */
- tm = (struct texture_map *)(++map_state);
- memset(tm, 0, sizeof(*tm));
- tm->tm0.v_ls_offset = 0;
- tm->tm0.v_ls = 0;
- tm->tm0.base_address = (UOFFSET(privPast) >> 2);
- tm->tm1.tile_walk = TILEWALK_XMAJOR;
- tm->tm1.tiled_surface = 0;
- tm->tm1.utilize_fence_regs = 0;
- tm->tm1.texel_fmt = 0; /* 8bit */
- tm->tm1.surface_fmt = 1; /* 8bit */
- tm->tm1.width = (w >> 1) - 1;
- tm->tm1.height = (h >> 1) - 1;
- tm->tm2.depth = 0;
- tm->tm2.max_lod = 0;
- tm->tm2.cube_face = 0;
- tm->tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */
-
- /* texture map: Backward */
- ++tm;
- memset(tm, 0, sizeof(*tm));
- tm->tm0.v_ls_offset = 0;
- tm->tm0.v_ls = 0;
- tm->tm0.base_address = (UOFFSET(privFuture) >> 2);
- tm->tm1.tile_walk = TILEWALK_XMAJOR;
- tm->tm1.tiled_surface = 0;
- tm->tm1.utilize_fence_regs = 0;
- tm->tm1.texel_fmt = 0;
- tm->tm1.surface_fmt = 1;
- tm->tm1.width = (w >> 1) - 1;
- tm->tm1.height = (h >> 1) - 1;
- tm->tm2.depth = 0;
- tm->tm2.max_lod = 0;
- tm->tm2.cube_face = 0;
- tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;
-
- /* 3DSATE_MAP_STATE: V */
- map_state = (struct i915_3dstate_map_state *)(++tm);
- memset(map_state, 0, sizeof(*map_state));
- map_state->dw0.type = CMD_3D;
- map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE;
- map_state->dw0.retain = 1;
- map_state->dw0.length = 6;
- map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1;
-
- /* texture map: Forward */
- tm = (struct texture_map *)(++map_state);
- memset(tm, 0, sizeof(*tm));
- tm->tm0.v_ls_offset = 0;
- tm->tm0.v_ls = 0;
- tm->tm0.base_address = (VOFFSET(privPast) >> 2);
- tm->tm1.tile_walk = TILEWALK_XMAJOR;
- tm->tm1.tiled_surface = 0;
- tm->tm1.utilize_fence_regs = 0;
- tm->tm1.texel_fmt = 0;
- tm->tm1.surface_fmt = 1;
- tm->tm1.width = (w >> 1) - 1;
- tm->tm1.height = (h >> 1) - 1;
- tm->tm2.depth = 0;
- tm->tm2.max_lod = 0;
- tm->tm2.cube_face = 0;
- tm->tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */
-
- /* texture map: Backward */
- ++tm;
- memset(tm, 0, sizeof(*tm));
- tm->tm0.v_ls_offset = 0;
- tm->tm0.v_ls = 0;
- tm->tm0.base_address = (VOFFSET(privFuture) >> 2);
- tm->tm1.tile_walk = TILEWALK_XMAJOR;
- tm->tm1.tiled_surface = 0;
- tm->tm1.utilize_fence_regs = 0;
- tm->tm1.texel_fmt = 0;
- tm->tm1.surface_fmt = 1;
- tm->tm1.width = (w >> 1) - 1;
- tm->tm1.height = (h >> 1) - 1;
- tm->tm2.depth = 0;
- tm->tm2.max_lod = 0;
- tm->tm2.cube_face = 0;
- tm->tm2.pitch = (privFuture->uvStride >> 2) - 1;
-}
-
-static void i915_mc_load_sis_msb_buffers(XvMCContext *context)
-{
- struct i915_3dstate_load_indirect *load_indirect;
- sis_state *sis = NULL;
- msb_state *msb = NULL;
- i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
- void *base = NULL;
- unsigned int size;
- int mem_select = 1;
-
- /* 3DSTATE_LOAD_INDIRECT */
- size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*msb);
- base = calloc(1, size);
- load_indirect = (struct i915_3dstate_load_indirect *)base;
- load_indirect->dw0.type = CMD_3D;
- load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
- load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB;
- load_indirect->dw0.length = (size >> 2) - 2;
-
- if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
- pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
- pI915XvMC->deviceID == PCI_CHIP_I945_G ||
- pI915XvMC->deviceID == PCI_CHIP_I945_GM)
- mem_select = 0;
-
- load_indirect->dw0.mem_select = mem_select;
-
- /* SIS */
- sis = (sis_state *)(++load_indirect);
- sis->dw0.valid = 1;
- sis->dw0.force = 1;
- sis->dw1.length = 16; // 4 * 3 + 2 + 3 - 1
-
- if (mem_select)
- sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
- else
- sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2);
-
- /* MSB */
- msb = (msb_state *)(++sis);
- msb->dw0.valid = 1;
- msb->dw0.force = 1;
- msb->dw1.length = 23; // 3 * 8 - 1
-
- if (mem_select)
- msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
- else
- msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2);
-
- intelBatchbufferData(base, size, 0);
- free(base);
-}
-
-static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
-{
- struct i915_3dmpeg_set_origin set_origin;
-
- /* 3DMPEG_SET_ORIGIN */
- memset(&set_origin, 0, sizeof(set_origin));
- set_origin.dw0.type = CMD_3D;
- set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN;
- set_origin.dw0.length = 0;
- set_origin.dw1.h_origin = mb->x;
- set_origin.dw1.v_origin = mb->y;
-
- intelBatchbufferData(&set_origin, sizeof(set_origin), 0);
-}
-
-static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb)
-{
- struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture;
-
- /* 3DMPEG_MACROBLOCK_IPICTURE */
- memset(&macroblock_ipicture, 0, sizeof(macroblock_ipicture));
- macroblock_ipicture.dw0.type = CMD_3D;
- macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE;
- macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-
- intelBatchbufferData(&macroblock_ipicture, sizeof(macroblock_ipicture), 0);
-}
-
-#if 0
-static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
-{
- struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
-
- /* 3DMPEG_MACROBLOCK(0mv) */
- memset(&macroblock_0mv, 0, sizeof(macroblock_0mv));
- macroblock_0mv.header.dw0.type = CMD_3D;
- macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
- macroblock_0mv.header.dw0.length = 0;
- macroblock_0mv.header.dw1.mb_intra = 1; /* should be 1 */
- macroblock_0mv.header.dw1.forward = 0; /* should be 0 */
- macroblock_0mv.header.dw1.backward = 0; /* should be 0 */
- macroblock_0mv.header.dw1.h263_4mv = 0; /* should be 0 */
- macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-
-/*
- if (!mb->coded_block_pattern)
- macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
-*/
-
- macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3);
- macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf;
- macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
- macroblock_0mv.header.dw1.skipped_macroblocks = 0;
-
- intelBatchbufferData(&macroblock_0mv, sizeof(macroblock_0mv), 0);
-}
-#endif
-
-static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
-{
- struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv;
-
- /* Motion Vectors */
- su_t fmv;
- su_t bmv;
-
- /* 3DMPEG_MACROBLOCK(1fbmv) */
- memset(&macroblock_1fbmv, 0, sizeof(macroblock_1fbmv));
- macroblock_1fbmv.header.dw0.type = CMD_3D;
- macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
- macroblock_1fbmv.header.dw0.length = 2;
- macroblock_1fbmv.header.dw1.mb_intra = 0; /* should be 0 */
- macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
- macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
- macroblock_1fbmv.header.dw1.h263_4mv = 0; /* should be 0 */
- macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-
- if (!(mb->coded_block_pattern & 0x3f))
- macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
-
- macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
- macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
- macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
- macroblock_1fbmv.header.dw1.skipped_macroblocks = 0;
-
- fmv.s[0] = mb->PMV[0][0][0];
- fmv.s[1] = mb->PMV[0][0][1];
- bmv.s[0] = mb->PMV[0][1][0];
- bmv.s[1] = mb->PMV[0][1][1];
-
- macroblock_1fbmv.dw2 = fmv.u[0];
- macroblock_1fbmv.dw3 = bmv.u[0];
-
- intelBatchbufferData(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
-}
-
-static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
-{
- struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
-
- /* Motion Vectors */
- su_t fmv;
- su_t bmv;
-
- /* 3DMPEG_MACROBLOCK(2fbmv) */
- memset(&macroblock_2fbmv, 0, sizeof(macroblock_2fbmv));
- macroblock_2fbmv.header.dw0.type = CMD_3D;
- macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
- macroblock_2fbmv.header.dw0.length = 4;
- macroblock_2fbmv.header.dw1.mb_intra = 0; /* should be 0 */
- macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
- macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
- macroblock_2fbmv.header.dw1.h263_4mv = 0; /* should be 0 */
- macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
-
- if (!(mb->coded_block_pattern & 0x3f))
- macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
-
- macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
- macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
- macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
- macroblock_2fbmv.header.dw1.skipped_macroblocks = 0;
-
- fmv.s[0] = mb->PMV[0][0][0];
- fmv.s[1] = mb->PMV[0][0][1];
- fmv.s[2] = mb->PMV[1][0][0];
- fmv.s[3] = mb->PMV[1][0][1];
- bmv.s[0] = mb->PMV[0][1][0];
- bmv.s[1] = mb->PMV[0][1][1];
- bmv.s[2] = mb->PMV[1][1][0];
- bmv.s[3] = mb->PMV[1][1][1];
-
- if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
- if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) {
- fmv.s[0] = mb->PMV[0][0][0];
- fmv.s[1] = mb->PMV[0][0][1] >> 1;
- fmv.s[2] = mb->PMV[1][0][0];
- fmv.s[3] = mb->PMV[1][0][1] >> 1;
- bmv.s[0] = mb->PMV[0][1][0];
- bmv.s[1] = mb->PMV[0][1][1] >> 1;
- bmv.s[2] = mb->PMV[1][1][0];
- bmv.s[3] = mb->PMV[1][1][1] >> 1;
- } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) {
- fmv.s[0] = mb->PMV[0][0][0];
- fmv.s[1] = mb->PMV[0][0][1] >> 1;
- fmv.s[2] = mb->PMV[0][0][0];
- fmv.s[3] = mb->PMV[0][0][1] >> 1; // MPEG2 MV[0][1] isn't used
- bmv.s[0] = mb->PMV[1][0][0];
- bmv.s[1] = mb->PMV[1][0][1] >> 1;
- bmv.s[2] = mb->PMV[1][1][0];
- bmv.s[3] = mb->PMV[1][1][1] >> 1;
- }
- }
-
- macroblock_2fbmv.dw2 = fmv.u[0];
- macroblock_2fbmv.dw3 = bmv.u[0];
- macroblock_2fbmv.dw4 = fmv.u[1];
- macroblock_2fbmv.dw5 = bmv.u[1];
-
- intelBatchbufferData(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
-}
-
-/* for MC context initialization */
-static void i915_mc_sampler_state_buffer(XvMCContext *context)
-{
- struct i915_3dstate_sampler_state *sampler_state;
- struct texture_sampler *ts;
- i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
-
- /* 3DSATE_SAMPLER_STATE */
- sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
- memset(sampler_state, 0, sizeof(*sampler_state));
- sampler_state->dw0.type = CMD_3D;
- sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE;
- sampler_state->dw0.length = 6;
- sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1;
-
- /* Sampler 0 */
- ts = (struct texture_sampler *)(++sampler_state);
- memset(ts, 0, sizeof(*ts));
- ts->ts0.reverse_gamma = 0;
- ts->ts0.planar2packet = 0;
- ts->ts0.color_conversion = 0;
- ts->ts0.chromakey_index = 0;
- ts->ts0.base_level = 0;
- ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */
- ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */
- ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */
- ts->ts0.lod_bias = 0; /* 0.0 */
- ts->ts0.shadow_enable = 0;
- ts->ts0.max_anisotropy = ANISORATIO_2;
- ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
- ts->ts1.min_lod = 0; /* 0.0 Maximum Mip Level */
- ts->ts1.kill_pixel = 0;
- ts->ts1.keyed_texture_filter = 0;
- ts->ts1.chromakey_enable = 0;
- ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
- ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
- ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
- ts->ts1.normalized_coor = 0;
- ts->ts1.map_index = 0;
- ts->ts1.east_deinterlacer = 0;
- ts->ts2.default_color = 0;
-
- /* Sampler 1 */
- ++ts;
- memset(ts, 0, sizeof(*ts));
- ts->ts0.reverse_gamma = 0;
- ts->ts0.planar2packet = 0;
- ts->ts0.color_conversion = 0;
- ts->ts0.chromakey_index = 0;
- ts->ts0.base_level = 0;
- ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */
- ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */
- ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */
- ts->ts0.lod_bias = 0; /* 0.0 */
- ts->ts0.shadow_enable = 0;
- ts->ts0.max_anisotropy = ANISORATIO_2;
- ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
- ts->ts1.min_lod = 0; /* 0.0 Maximum Mip Level */
- ts->ts1.kill_pixel = 0;
- ts->ts1.keyed_texture_filter = 0;
- ts->ts1.chromakey_enable = 0;
- ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
- ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
- ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
- ts->ts1.normalized_coor = 0;
- ts->ts1.map_index = 1;
- ts->ts1.east_deinterlacer = 0;
- ts->ts2.default_color = 0;
-}
-
static void i915_inst_arith(unsigned int *inst,
unsigned int op,
unsigned int dest,
@@ -695,191 +124,245 @@ static void i915_inst_texld(unsigned int *inst,
*inst = T2_MBZ;
}
-static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
+static void i915_emit_batch(void *data, int size, int flag)
+{
+ intelBatchbufferData(data, size, flag);
+}
+
+/* one time context initialization buffer */
+static uint32_t *one_time_load_state_imm1;
+static uint32_t *one_time_load_indirect;
+static int one_time_load_state_imm1_size, one_time_load_indirect_size;
+
+/* load indirect buffer for mc rendering */
+static uint32_t *mc_render_load_indirect;
+static int mc_render_load_indirect_size;
+
+static void i915_mc_one_time_context_init(XvMCContext *context)
{
- struct i915_3dstate_pixel_shader_program *pixel_shader_program;
- i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
- unsigned int *inst;
unsigned int dest, src0, src1, src2;
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+ int i;
+ struct i915_3dstate_sampler_state *sampler_state;
+ struct i915_3dstate_pixel_shader_program *pixel_shader_program;
+ struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
- /* Shader 0 */
+ /* sampler static state */
+ sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
+ /* pixel shader static state */
pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
+ /* pixel shader contant static state */
+ pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map;
+
+ memset(sampler_state, 0, sizeof(*sampler_state));
+ sampler_state->dw0.type = CMD_3D;
+ sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE;
+ sampler_state->dw0.length = 6;
+ sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1;
+
+ sampler_state->sampler0.ts0.reverse_gamma = 0;
+ sampler_state->sampler0.ts0.planar2packet = 0;
+ sampler_state->sampler0.ts0.color_conversion = 0;
+ sampler_state->sampler0.ts0.chromakey_index = 0;
+ sampler_state->sampler0.ts0.base_level = 0;
+ sampler_state->sampler0.ts0.mip_filter = MIPFILTER_NONE; /* NONE */
+ sampler_state->sampler0.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */
+ sampler_state->sampler0.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */
+ sampler_state->sampler0.ts0.lod_bias = 0; /* 0.0 */
+ sampler_state->sampler0.ts0.shadow_enable = 0;
+ sampler_state->sampler0.ts0.max_anisotropy = ANISORATIO_2;
+ sampler_state->sampler0.ts0.shadow_function = PREFILTEROP_ALWAYS;
+ sampler_state->sampler0.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */
+ sampler_state->sampler0.ts1.kill_pixel = 0;
+ sampler_state->sampler0.ts1.keyed_texture_filter = 0;
+ sampler_state->sampler0.ts1.chromakey_enable = 0;
+ sampler_state->sampler0.ts1.tcx_control = TEXCOORDMODE_CLAMP;
+ sampler_state->sampler0.ts1.tcy_control = TEXCOORDMODE_CLAMP;
+ sampler_state->sampler0.ts1.tcz_control = TEXCOORDMODE_CLAMP;
+ sampler_state->sampler0.ts1.normalized_coor = 0;
+ sampler_state->sampler0.ts1.map_index = 0;
+ sampler_state->sampler0.ts1.east_deinterlacer = 0;
+ sampler_state->sampler0.ts2.default_color = 0;
+
+ sampler_state->sampler1.ts0.reverse_gamma = 0;
+ sampler_state->sampler1.ts0.planar2packet = 0;
+ sampler_state->sampler1.ts0.color_conversion = 0;
+ sampler_state->sampler1.ts0.chromakey_index = 0;
+ sampler_state->sampler1.ts0.base_level = 0;
+ sampler_state->sampler1.ts0.mip_filter = MIPFILTER_NONE; /* NONE */
+ sampler_state->sampler1.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */
+ sampler_state->sampler1.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */
+ sampler_state->sampler1.ts0.lod_bias = 0; /* 0.0 */
+ sampler_state->sampler1.ts0.shadow_enable = 0;
+ sampler_state->sampler1.ts0.max_anisotropy = ANISORATIO_2;
+ sampler_state->sampler1.ts0.shadow_function = PREFILTEROP_ALWAYS;
+ sampler_state->sampler1.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */
+ sampler_state->sampler1.ts1.kill_pixel = 0;
+ sampler_state->sampler1.ts1.keyed_texture_filter = 0;
+ sampler_state->sampler1.ts1.chromakey_enable = 0;
+ sampler_state->sampler1.ts1.tcx_control = TEXCOORDMODE_CLAMP;
+ sampler_state->sampler1.ts1.tcy_control = TEXCOORDMODE_CLAMP;
+ sampler_state->sampler1.ts1.tcz_control = TEXCOORDMODE_CLAMP;
+ sampler_state->sampler1.ts1.normalized_coor = 0;
+ sampler_state->sampler1.ts1.map_index = 1;
+ sampler_state->sampler1.ts1.east_deinterlacer = 0;
+ sampler_state->sampler1.ts2.default_color = 0;
+
memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
- pixel_shader_program->dw0.type = CMD_3D;
- pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
- pixel_shader_program->dw0.retain = 1;
- pixel_shader_program->dw0.length = 2;
- /* mov oC, c0.0000 */
- inst = (unsigned int*)(++pixel_shader_program);
+ pixel_shader_program->shader0.type = CMD_3D;
+ pixel_shader_program->shader0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+ pixel_shader_program->shader0.retain = 1;
+ pixel_shader_program->shader0.length = 2; /* 1 inst */
+ i = 0;
+
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_CONST, 0);
src1 = 0;
src2 = 0;
- i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
- A0_DEST_SATURATE, src0, src1, src2);
- inst += 3;
-
- /* Shader 1 */
- pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
- memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
- pixel_shader_program->dw0.type = CMD_3D;
- pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
- pixel_shader_program->dw0.retain = 1;
- pixel_shader_program->dw0.length = 14;
+ i915_inst_arith(&pixel_shader_program->inst0[i], A0_MOV,
+ dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2);
+
+ pixel_shader_program->shader1.type = CMD_3D;
+ pixel_shader_program->shader1.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+ pixel_shader_program->shader1.retain = 1;
+ pixel_shader_program->shader1.length = 14; /* 5 inst */
+ i = 0;
/* dcl t0.xy */
- inst = (unsigned int*)(++pixel_shader_program);
- i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
+ i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
+ i+=3;
/* dcl t1.xy */
- inst += 3;
- i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
+ i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
/* dcl_2D s0 */
- inst += 3;
- i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
+ i += 3;
+ i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
/* texld r0, t0, s0 */
- inst += 3;
+ i += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_T, 0); /* COORD */
src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
- i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+ i915_inst_texld(&pixel_shader_program->inst1[i], T0_TEXLD, dest, src0, src1);
/* mov oC, r0 */
- inst += 3;
+ i += 3;
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = src2 = 0;
- i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
+ i915_inst_arith(&pixel_shader_program->inst1[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL,
A0_DEST_SATURATE, src0, src1, src2);
- inst += 3;
- /* Shader 2 */
- pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
- memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
- pixel_shader_program->dw0.type = CMD_3D;
- pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
- pixel_shader_program->dw0.retain = 1;
- pixel_shader_program->dw0.length = 14;
+
+ pixel_shader_program->shader2.type = CMD_3D;
+ pixel_shader_program->shader2.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+ pixel_shader_program->shader2.retain = 1;
+ pixel_shader_program->shader2.length = 14; /* 5 inst */
+ i = 0;
/* dcl t2.xy */
- inst = (unsigned int*)(++pixel_shader_program);
- i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
+ i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
/* dcl t3.xy */
- inst += 3;
- i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
+ i += 3;
+ i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
/* dcl_2D s1 */
- inst += 3;
- i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+ i += 3;
+ i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
/* texld r0, t2, s1 */
- inst += 3;
+ i += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_T, 2); /* COORD */
src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
- i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+ i915_inst_texld(&pixel_shader_program->inst2[i], T0_TEXLD, dest, src0, src1);
/* mov oC, r0 */
- inst += 3;
+ i += 3;
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = src2 = 0;
- i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
+ i915_inst_arith(&pixel_shader_program->inst2[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL,
A0_DEST_SATURATE, src0, src1, src2);
- inst += 3;
/* Shader 3 */
- pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
- memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
- pixel_shader_program->dw0.type = CMD_3D;
- pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
- pixel_shader_program->dw0.retain = 1;
- pixel_shader_program->dw0.length = 29;
+ pixel_shader_program->shader3.type = CMD_3D;
+ pixel_shader_program->shader3.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
+ pixel_shader_program->shader3.retain = 1;
+ pixel_shader_program->shader3.length = 29; /* 10 inst */
+ i = 0;
/* dcl t0.xy */
- inst = (unsigned int*)(++pixel_shader_program);
- i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
+ i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
/* dcl t1.xy */
- inst += 3;
- i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
+ i += 3;
+ i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
/* dcl t2.xy */
- inst += 3;
- i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
+ i += 3;
+ i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
/* dcl t3.xy */
- inst += 3;
- i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
+ i += 3;
+ i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
/* dcl_2D s0 */
- inst += 3;
- i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
+ i += 3;
+ i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
/* dcl_2D s1 */
- inst += 3;
- i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+ i += 3;
+ i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
/* texld r0, t0, s0 */
- inst += 3;
+ i += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_T, 0); /* COORD */
src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
- i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+ i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1);
/* texld r1, t2, s1 */
- inst += 3;
+ i += 3;
dest = UREG(REG_TYPE_R, 1);
src0 = UREG(REG_TYPE_T, 2); /* COORD */
src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
- i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+ i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1);
/* add r0, r0, r1 */
- inst += 3;
+ i += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = UREG(REG_TYPE_R, 1);
src2 = 0;
- i915_inst_arith(inst, A0_ADD, dest, A0_DEST_CHANNEL_ALL,
+ i915_inst_arith(&pixel_shader_program->inst3[i], A0_ADD, dest, A0_DEST_CHANNEL_ALL,
0 /* A0_DEST_SATURATE */, src0, src1, src2);
/* mul oC, r0, c0 */
- inst += 3;
+ i += 3;
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = UREG(REG_TYPE_CONST, 0);
src2 = 0;
- i915_inst_arith(inst, A0_MUL, dest, A0_DEST_CHANNEL_ALL,
+ i915_inst_arith(&pixel_shader_program->inst3[i], A0_MUL, dest, A0_DEST_CHANNEL_ALL,
A0_DEST_SATURATE, src0, src1, src2);
- inst += 3;
-}
-
-static void i915_mc_pixel_shader_constants_buffer(XvMCContext *context)
-{
- struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
- i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
- float *value;
- pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map;
memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants));
pixel_shader_constants->dw0.type = CMD_3D;
pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS;
pixel_shader_constants->dw0.length = 4;
pixel_shader_constants->dw1.reg_mask = REG_CR0;
- value = (float *)(++pixel_shader_constants);
- *(value++) = 0.5;
- *(value++) = 0.5;
- *(value++) = 0.5;
- *(value++) = 0.5;
+ pixel_shader_constants->value.x = 0.5;
+ pixel_shader_constants->value.y = 0.5;
+ pixel_shader_constants->value.z = 0.5;
+ pixel_shader_constants->value.w = 0.5;
+
}
-static void i915_mc_one_time_state_initialization(XvMCContext *context)
+static void i915_mc_one_time_state_init(XvMCContext *context)
{
- struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL;
struct s3_dword *s3 = NULL;
struct s6_dword *s6 = NULL;
- struct i915_3dstate_load_indirect *load_indirect = NULL;
dis_state *dis = NULL;
ssb_state *ssb = NULL;
psp_state *psp = NULL;
psc_state *psc = NULL;
i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
- unsigned int size;
- void *base = NULL;
- int mem_select = 1;
+ struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1;
+ struct i915_3dstate_load_indirect *load_indirect;
+ int mem_select;
/* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
- size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
- base = calloc(1, size);
- load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)base;
+ one_time_load_state_imm1_size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
+ one_time_load_state_imm1 = calloc(1, one_time_load_state_imm1_size);
+ load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)one_time_load_state_imm1;
load_state_immediate_1->dw0.type = CMD_3D;
load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1;
load_state_immediate_1->dw0.load_s3 = 1;
load_state_immediate_1->dw0.load_s6 = 1;
- load_state_immediate_1->dw0.length = (size >> 2) - 2;
+ load_state_immediate_1->dw0.length = (one_time_load_state_imm1_size >> 2) - 2;
s3 = (struct s3_dword *)(++load_state_immediate_1);
s3->set0_pcd = 1;
@@ -905,33 +388,31 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context)
s6->color_buffer_write = 1;
s6->triangle_pv = 0;
- intelBatchbufferData(base, size, 0);
- free(base);
-
/* 3DSTATE_LOAD_INDIRECT */
- size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc);
- base = calloc(1, size);
- load_indirect = (struct i915_3dstate_load_indirect *)base;
+ one_time_load_indirect_size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc);
+ one_time_load_indirect = calloc(1, one_time_load_indirect_size);
+ load_indirect = (struct i915_3dstate_load_indirect *)one_time_load_indirect;
load_indirect->dw0.type = CMD_3D;
load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC;
- load_indirect->dw0.length = (size >> 2) - 2;
+ load_indirect->dw0.length = (one_time_load_indirect_size >> 2) - 2;
if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
- pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
- pI915XvMC->deviceID == PCI_CHIP_I945_G ||
- pI915XvMC->deviceID == PCI_CHIP_I945_GM)
- mem_select = 0;
+ pI915XvMC->deviceID == PCI_CHIP_I915_GM)
+ mem_select = 0; /* use physical address */
+ else
+ mem_select = 1; /* use gfx address */
load_indirect->dw0.mem_select = mem_select;
- /* DIS */
+
+ /* Dynamic indirect state buffer */
dis = (dis_state *)(++load_indirect);
dis->dw0.valid = 0;
dis->dw0.reset = 0;
dis->dw0.buffer_address = 0;
- /* SSB */
+ /* Sample state buffer */
ssb = (ssb_state *)(++dis);
ssb->dw0.valid = 1;
ssb->dw0.force = 1;
@@ -940,20 +421,20 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context)
if (mem_select)
ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
else
- ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
+ ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
- /* PSP */
+ /* Pixel shader program buffer */
psp = (psp_state *)(++ssb);
psp->dw0.valid = 1;
psp->dw0.force = 1;
psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
if (mem_select)
- psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
+ psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
else
- psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
+ psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
- /* PSC */
+ /* Pixel shader constant buffer */
psc = (psc_state *)(++psp);
psc->dw0.valid = 1;
psc->dw0.force = 1;
@@ -963,9 +444,483 @@ static void i915_mc_one_time_state_initialization(XvMCContext *context)
psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2);
else
psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2);
+}
- intelBatchbufferData(base, size, 0);
- free(base);
+static void i915_mc_one_time_state_emit(void)
+{
+ i915_emit_batch(one_time_load_state_imm1, one_time_load_state_imm1_size, 0);
+ i915_emit_batch(one_time_load_indirect, one_time_load_indirect_size, 0);
+}
+
+static void i915_mc_static_indirect_state_init(XvMCContext *context)
+{
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+ struct i915_mc_static_indirect_state_buffer *buffer_info =
+ (struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map;
+
+ memset(buffer_info, 0, sizeof(*buffer_info));
+ /* dest Y */
+ buffer_info->dest_y.dw0.type = CMD_3D;
+ buffer_info->dest_y.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+ buffer_info->dest_y.dw0.length = 1;
+ buffer_info->dest_y.dw1.aux_id = 0;
+ buffer_info->dest_y.dw1.buffer_id = BUFFERID_COLOR_BACK;
+ buffer_info->dest_y.dw1.fence_regs = 0; /* disabled */ /* FIXME: tiled y for performance */
+ buffer_info->dest_y.dw1.tiled_surface = 0; /* linear */
+ buffer_info->dest_y.dw1.walk = TILEWALK_XMAJOR;
+
+ /* dest U */
+ buffer_info->dest_u.dw0.type = CMD_3D;
+ buffer_info->dest_u.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+ buffer_info->dest_u.dw0.length = 1;
+ buffer_info->dest_u.dw1.aux_id = 0;
+ buffer_info->dest_u.dw1.buffer_id = BUFFERID_COLOR_AUX;
+ buffer_info->dest_u.dw1.fence_regs = 0;
+ buffer_info->dest_u.dw1.tiled_surface = 0;
+ buffer_info->dest_u.dw1.walk = TILEWALK_XMAJOR;
+
+ /* dest V */
+ buffer_info->dest_v.dw0.type = CMD_3D;
+ buffer_info->dest_v.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+ buffer_info->dest_v.dw0.length = 1;
+ buffer_info->dest_v.dw1.aux_id = 1;
+ buffer_info->dest_v.dw1.buffer_id = BUFFERID_COLOR_AUX;
+ buffer_info->dest_v.dw1.fence_regs = 0;
+ buffer_info->dest_v.dw1.tiled_surface = 0;
+ buffer_info->dest_v.dw1.walk = TILEWALK_XMAJOR;
+
+ buffer_info->dest_buf.dw0.type = CMD_3D;
+ buffer_info->dest_buf.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES;
+ buffer_info->dest_buf.dw0.length = 0;
+ buffer_info->dest_buf.dw1.dest_v_bias = 8; /* 0.5 */
+ buffer_info->dest_buf.dw1.dest_h_bias = 8; /* 0.5 */
+ buffer_info->dest_buf.dw1.color_fmt = COLORBUFFER_8BIT;
+ buffer_info->dest_buf.dw1.v_ls = 0; /* fill later */
+ buffer_info->dest_buf.dw1.v_ls_offset = 0; /* fill later */
+
+ buffer_info->dest_buf_mpeg.dw0.type = CMD_3D;
+ buffer_info->dest_buf_mpeg.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG;
+ buffer_info->dest_buf_mpeg.dw0.length = 1;
+ buffer_info->dest_buf_mpeg.dw1.decode_mode = MPEG_DECODE_MC;
+ buffer_info->dest_buf_mpeg.dw1.rcontrol = 0; /* for MPEG-1/MPEG-2 */
+ buffer_info->dest_buf_mpeg.dw1.bidir_avrg_control = 0; /* for MPEG-1/MPEG-2/MPEG-4 */
+ buffer_info->dest_buf_mpeg.dw1.abort_on_error = 1;
+ buffer_info->dest_buf_mpeg.dw1.intra8 = 0; /* 16-bit formatted correction data */
+ buffer_info->dest_buf_mpeg.dw1.tff = 1; /* fill later */
+
+ buffer_info->dest_buf_mpeg.dw1.v_subsample_factor = MC_SUB_1V;
+ buffer_info->dest_buf_mpeg.dw1.h_subsample_factor = MC_SUB_1H;
+
+ buffer_info->corr.dw0.type = CMD_3D;
+ buffer_info->corr.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
+ buffer_info->corr.dw0.length = 1;
+ buffer_info->corr.dw1.aux_id = 0;
+ buffer_info->corr.dw1.buffer_id = BUFFERID_MC_INTRA_CORR;
+ buffer_info->corr.dw1.aux_id = 0;
+ buffer_info->corr.dw1.fence_regs = 0;
+ buffer_info->corr.dw1.tiled_surface = 0;
+ buffer_info->corr.dw1.walk = 0;
+ buffer_info->corr.dw1.pitch = 0;
+ buffer_info->corr.dw2.base_address = (pI915XvMC->corrdata.offset >> 2); /* starting DWORD address */
+}
+
+static void i915_mc_static_indirect_state_set(XvMCContext *context, XvMCSurface *dest,
+ unsigned int picture_structure, unsigned int flags, unsigned int picture_coding_type)
+{
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+ i915XvMCSurface *pI915Surface = (i915XvMCSurface *)dest->privData;
+ struct i915_mc_static_indirect_state_buffer *buffer_info =
+ (struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map;
+ unsigned int w = dest->width;
+
+ buffer_info->dest_y.dw1.pitch = (pI915Surface->yStride >> 2); /* in DWords */
+ buffer_info->dest_y.dw2.base_address = (YOFFSET(pI915Surface) >> 2); /* starting DWORD address */
+ buffer_info->dest_u.dw1.pitch = (pI915Surface->uvStride >> 2); /* in DWords */
+ buffer_info->dest_u.dw2.base_address = (UOFFSET(pI915Surface) >> 2); /* starting DWORD address */
+ buffer_info->dest_v.dw1.pitch = (pI915Surface->uvStride >> 2); /* in Dwords */
+ buffer_info->dest_v.dw2.base_address = (VOFFSET(pI915Surface) >> 2); /* starting DWORD address */
+
+ if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
+ ;
+ } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) {
+ buffer_info->dest_buf.dw1.v_ls = 1;
+ } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) {
+ buffer_info->dest_buf.dw1.v_ls = 1;
+ buffer_info->dest_buf.dw1.v_ls_offset = 1;
+ }
+
+ if (picture_structure & XVMC_FRAME_PICTURE) {
+ ;
+ } else if (picture_structure & XVMC_TOP_FIELD) {
+ if (flags & XVMC_SECOND_FIELD)
+ buffer_info->dest_buf_mpeg.dw1.tff = 0;
+ else
+ buffer_info->dest_buf_mpeg.dw1.tff = 1;
+ } else if (picture_structure & XVMC_BOTTOM_FIELD) {
+ if (flags & XVMC_SECOND_FIELD)
+ buffer_info->dest_buf_mpeg.dw1.tff = 1;
+ else
+ buffer_info->dest_buf_mpeg.dw1.tff = 0;
+ }
+
+ buffer_info->dest_buf_mpeg.dw1.picture_width = (dest->width >> 4); /* in macroblocks */
+ buffer_info->dest_buf_mpeg.dw2.picture_coding_type = picture_coding_type;
+}
+
+static void i915_mc_map_state_init(XvMCContext *context)
+{
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+ unsigned int w = context->width;
+ unsigned int h = context->height;
+ struct i915_mc_map_state *map_state;
+
+ map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map;
+
+ memset(map_state, 0, sizeof(*map_state));
+
+ /* 3DSATE_MAP_STATE: Y */
+ map_state->y_map.dw0.type = CMD_3D;
+ map_state->y_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
+ map_state->y_map.dw0.retain = 1;
+ map_state->y_map.dw0.length = 6;
+ map_state->y_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+
+ /* Y Forward (Past) */
+ map_state->y_forward.tm0.v_ls_offset = 0;
+ map_state->y_forward.tm0.v_ls = 0;
+ map_state->y_forward.tm1.tile_walk = TILEWALK_XMAJOR;
+ map_state->y_forward.tm1.tiled_surface = 0;
+ map_state->y_forward.tm1.utilize_fence_regs = 0;
+ map_state->y_forward.tm1.texel_fmt = 0; /* 8bit */
+ map_state->y_forward.tm1.surface_fmt = 1; /* 8bit */
+ map_state->y_forward.tm1.width = w - 1;
+ map_state->y_forward.tm1.height = h - 1;
+ map_state->y_forward.tm2.depth = 0;
+ map_state->y_forward.tm2.max_lod = 0;
+ map_state->y_forward.tm2.cube_face = 0;
+
+ /* Y Backward (Future) */
+ map_state->y_backward.tm0.v_ls_offset = 0;
+ map_state->y_backward.tm0.v_ls = 0;
+ map_state->y_backward.tm1.tile_walk = TILEWALK_XMAJOR;
+ map_state->y_backward.tm1.tiled_surface = 0;
+ map_state->y_backward.tm1.utilize_fence_regs = 0;
+ map_state->y_backward.tm1.texel_fmt = 0; /* 8bit */
+ map_state->y_backward.tm1.surface_fmt = 1; /* 8bit */
+ map_state->y_backward.tm1.width = w - 1;
+ map_state->y_backward.tm1.height = h - 1;
+ map_state->y_backward.tm2.depth = 0;
+ map_state->y_backward.tm2.max_lod = 0;
+ map_state->y_backward.tm2.cube_face = 0;
+
+ /* 3DSATE_MAP_STATE: U */
+ map_state->u_map.dw0.type = CMD_3D;
+ map_state->u_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
+ map_state->u_map.dw0.retain = 1;
+ map_state->u_map.dw0.length = 6;
+ map_state->u_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+
+ /* U Forward */
+ map_state->u_forward.tm0.v_ls_offset = 0;
+ map_state->u_forward.tm0.v_ls = 0;
+ map_state->u_forward.tm1.tile_walk = TILEWALK_XMAJOR;
+ map_state->u_forward.tm1.tiled_surface = 0;
+ map_state->u_forward.tm1.utilize_fence_regs = 0;
+ map_state->u_forward.tm1.texel_fmt = 0; /* 8bit */
+ map_state->u_forward.tm1.surface_fmt = 1; /* 8bit */
+ map_state->u_forward.tm1.width = (w >> 1) - 1;
+ map_state->u_forward.tm1.height = (h >> 1) - 1;
+ map_state->u_forward.tm2.depth = 0;
+ map_state->u_forward.tm2.max_lod = 0;
+ map_state->u_forward.tm2.cube_face = 0;
+
+ /* U Backward */
+ map_state->u_backward.tm0.v_ls_offset = 0;
+ map_state->u_backward.tm0.v_ls = 0;
+ map_state->u_backward.tm1.tile_walk = TILEWALK_XMAJOR;
+ map_state->u_backward.tm1.tiled_surface = 0;
+ map_state->u_backward.tm1.utilize_fence_regs = 0;
+ map_state->u_backward.tm1.texel_fmt = 0;
+ map_state->u_backward.tm1.surface_fmt = 1;
+ map_state->u_backward.tm1.width = (w >> 1) - 1;
+ map_state->u_backward.tm1.height = (h >> 1) - 1;
+ map_state->u_backward.tm2.depth = 0;
+ map_state->u_backward.tm2.max_lod = 0;
+ map_state->u_backward.tm2.cube_face = 0;
+
+ /* 3DSATE_MAP_STATE: V */
+ map_state->v_map.dw0.type = CMD_3D;
+ map_state->v_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
+ map_state->v_map.dw0.retain = 1;
+ map_state->v_map.dw0.length = 6;
+ map_state->v_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
+
+ /* V Forward */
+ map_state->v_forward.tm0.v_ls_offset = 0;
+ map_state->v_forward.tm0.v_ls = 0;
+ map_state->v_forward.tm1.tile_walk = TILEWALK_XMAJOR;
+ map_state->v_forward.tm1.tiled_surface = 0;
+ map_state->v_forward.tm1.utilize_fence_regs = 0;
+ map_state->v_forward.tm1.texel_fmt = 0;
+ map_state->v_forward.tm1.surface_fmt = 1;
+ map_state->v_forward.tm1.width = (w >> 1) - 1;
+ map_state->v_forward.tm1.height = (h >> 1) - 1;
+ map_state->v_forward.tm2.depth = 0;
+ map_state->v_forward.tm2.max_lod = 0;
+ map_state->v_forward.tm2.cube_face = 0;
+
+ /* V Backward */
+ map_state->v_backward.tm0.v_ls_offset = 0;
+ map_state->v_backward.tm0.v_ls = 0;
+ map_state->v_backward.tm1.tile_walk = TILEWALK_XMAJOR;
+ map_state->v_backward.tm1.tiled_surface = 0;
+ map_state->v_backward.tm1.utilize_fence_regs = 0;
+ map_state->v_backward.tm1.texel_fmt = 0;
+ map_state->v_backward.tm1.surface_fmt = 1;
+ map_state->v_backward.tm1.width = (w >> 1) - 1;
+ map_state->v_backward.tm1.height = (h >> 1) - 1;
+ map_state->v_backward.tm2.depth = 0;
+ map_state->v_backward.tm2.max_lod = 0;
+ map_state->v_backward.tm2.cube_face = 0;
+}
+
+static void i915_mc_map_state_set(XvMCContext *context,
+ i915XvMCSurface *privPast,
+ i915XvMCSurface *privFuture)
+{
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+ struct i915_mc_map_state *map_state;
+
+ map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map;
+
+ map_state->y_forward.tm0.base_address = (YOFFSET(privPast) >> 2);
+ map_state->y_forward.tm2.pitch = (privPast->yStride >> 2) - 1; /* in DWords - 1 */
+ map_state->y_backward.tm0.base_address = (YOFFSET(privFuture) >> 2);
+ map_state->y_backward.tm2.pitch = (privFuture->yStride >> 2) - 1;
+ map_state->u_forward.tm0.base_address = (UOFFSET(privPast) >> 2);
+ map_state->u_forward.tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */
+ map_state->u_backward.tm0.base_address = (UOFFSET(privFuture) >> 2);
+ map_state->u_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1;
+ map_state->v_forward.tm0.base_address = (VOFFSET(privPast) >> 2);
+ map_state->v_forward.tm2.pitch = (privPast->uvStride >> 2) - 1; /* in DWords - 1 */
+ map_state->v_backward.tm0.base_address = (VOFFSET(privFuture) >> 2);
+ map_state->v_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1;
+}
+
+static void i915_flush(int map, int render)
+{
+ struct i915_mi_flush mi_flush;
+
+ memset(&mi_flush, 0, sizeof(mi_flush));
+ mi_flush.dw0.type = CMD_MI;
+ mi_flush.dw0.opcode = OPC_MI_FLUSH;
+ mi_flush.dw0.map_cache_invalidate = map;
+ mi_flush.dw0.render_cache_flush_inhibit = render;
+
+ intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
+}
+
+static void i915_mc_load_indirect_render_init(XvMCContext *context)
+{
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+ sis_state *sis;
+ msb_state *msb;
+ struct i915_3dstate_load_indirect *load_indirect;
+ int mem_select;
+
+ mc_render_load_indirect_size = sizeof(*load_indirect) + sizeof(*sis)
+ + sizeof(*msb);
+ mc_render_load_indirect = calloc(1, mc_render_load_indirect_size);
+
+ load_indirect = (struct i915_3dstate_load_indirect *)mc_render_load_indirect;
+ load_indirect->dw0.type = CMD_3D;
+ load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
+ load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB;
+ load_indirect->dw0.length = (mc_render_load_indirect_size >> 2) - 2;
+
+ if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
+ pI915XvMC->deviceID == PCI_CHIP_I915_GM)
+ mem_select = 0;
+ else
+ mem_select = 1;
+
+ load_indirect->dw0.mem_select = mem_select;
+
+ /* Static Indirect state buffer (dest buffer info) */
+ sis = (sis_state *)(++load_indirect);
+ sis->dw0.valid = 1;
+ sis->dw0.force = 1;
+ sis->dw1.length = 16; /* 4 * 3 + 2 + 3 - 1 */
+
+ if (mem_select)
+ sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
+ else
+ sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2);
+
+ /* Map state buffer (reference buffer info) */
+ msb = (msb_state *)(++sis);
+ msb->dw0.valid = 1;
+ msb->dw0.force = 1;
+ msb->dw1.length = 23; /* 3 * 8 - 1 */
+
+ if (mem_select)
+ msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
+ else
+ msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2);
+}
+
+static void i915_mc_load_indirect_render_emit(void)
+{
+ i915_emit_batch(mc_render_load_indirect, mc_render_load_indirect_size, 0);
+}
+
+static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
+{
+ struct i915_3dmpeg_set_origin set_origin;
+
+ /* 3DMPEG_SET_ORIGIN */
+ memset(&set_origin, 0, sizeof(set_origin));
+ set_origin.dw0.type = CMD_3D;
+ set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN;
+ set_origin.dw0.length = 0;
+ set_origin.dw1.h_origin = mb->x;
+ set_origin.dw1.v_origin = mb->y;
+
+ intelBatchbufferData(&set_origin, sizeof(set_origin), 0);
+}
+
+static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb)
+{
+ struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture;
+
+ /* 3DMPEG_MACROBLOCK_IPICTURE */
+ memset(&macroblock_ipicture, 0, sizeof(macroblock_ipicture));
+ macroblock_ipicture.dw0.type = CMD_3D;
+ macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE;
+ macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+
+ intelBatchbufferData(&macroblock_ipicture, sizeof(macroblock_ipicture), 0);
+}
+
+#if 0
+static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
+{
+ struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
+
+ /* 3DMPEG_MACROBLOCK(0mv) */
+ memset(&macroblock_0mv, 0, sizeof(macroblock_0mv));
+ macroblock_0mv.header.dw0.type = CMD_3D;
+ macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
+ macroblock_0mv.header.dw0.length = 0;
+ macroblock_0mv.header.dw1.mb_intra = 1; /* should be 1 */
+ macroblock_0mv.header.dw1.forward = 0; /* should be 0 */
+ macroblock_0mv.header.dw1.backward = 0; /* should be 0 */
+ macroblock_0mv.header.dw1.h263_4mv = 0; /* should be 0 */
+ macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+
+/*
+ if (!mb->coded_block_pattern)
+ macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
+*/
+
+ macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3);
+ macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf;
+ macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
+ macroblock_0mv.header.dw1.skipped_macroblocks = 0;
+
+ intelBatchbufferData(&macroblock_0mv, sizeof(macroblock_0mv), 0);
+}
+#endif
+
+static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
+{
+ struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv;
+ vector_t mv0[2];
+
+ /* 3DMPEG_MACROBLOCK(1fbmv) */
+ memset(&macroblock_1fbmv, 0, sizeof(macroblock_1fbmv));
+ macroblock_1fbmv.header.dw0.type = CMD_3D;
+ macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
+ macroblock_1fbmv.header.dw0.length = 2;
+ macroblock_1fbmv.header.dw1.mb_intra = 0; /* should be 0 */
+ macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
+ macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
+ macroblock_1fbmv.header.dw1.h263_4mv = 0; /* should be 0 */
+ macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+
+ if (!(mb->coded_block_pattern & 0x3f))
+ macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
+
+ macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
+ macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
+ macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
+ macroblock_1fbmv.header.dw1.skipped_macroblocks = 0;
+
+ mv0[0].component[0] = mb->PMV[0][0][0];
+ mv0[0].component[1] = mb->PMV[0][0][1];
+ mv0[1].component[0] = mb->PMV[0][1][0];
+ mv0[1].component[1] = mb->PMV[0][1][1];
+
+ macroblock_1fbmv.dw2 = mv0[0].v;
+ macroblock_1fbmv.dw3 = mv0[1].v;
+
+ intelBatchbufferData(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
+}
+
+static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
+{
+ struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
+ vector_t mv0[2];
+ vector_t mv1[2];
+
+ /* 3DMPEG_MACROBLOCK(2fbmv) */
+ memset(&macroblock_2fbmv, 0, sizeof(macroblock_2fbmv));
+ macroblock_2fbmv.header.dw0.type = CMD_3D;
+ macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
+ macroblock_2fbmv.header.dw0.length = 4;
+ macroblock_2fbmv.header.dw1.mb_intra = 0; /* should be 0 */
+ macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
+ macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
+ macroblock_2fbmv.header.dw1.h263_4mv = 0; /* should be 0 */
+ macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
+
+ if (!(mb->coded_block_pattern & 0x3f))
+ macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
+
+ macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
+ macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
+ macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
+ macroblock_2fbmv.header.dw1.skipped_macroblocks = 0;
+
+ mv0[0].component[0] = mb->PMV[0][0][0];
+ mv0[0].component[1] = mb->PMV[0][0][1];
+ mv0[1].component[0] = mb->PMV[0][1][0];
+ mv0[1].component[1] = mb->PMV[0][1][1];
+ mv1[0].component[0] = mb->PMV[1][0][0];
+ mv1[0].component[1] = mb->PMV[1][0][1];
+ mv1[1].component[0] = mb->PMV[1][1][0];
+ mv1[1].component[1] = mb->PMV[1][1][1];
+
+ if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
+ if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) {
+ mv0[0].component[1] = mb->PMV[0][0][1] >> 1;
+ mv0[1].component[1] = mb->PMV[0][1][1] >> 1;
+ mv1[0].component[1] = mb->PMV[1][0][1] >> 1;
+ mv1[1].component[1] = mb->PMV[1][1][1] >> 1;
+ } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) {
+ mv0[0].component[1] = mb->PMV[0][0][1] >> 1;
+ mv0[1].component[1] = mb->PMV[0][1][1] >> 1; // MPEG2 MV[0][1] isn't used
+ mv1[0].component[1] = mb->PMV[1][0][1] >> 1;
+ mv1[1].component[1] = mb->PMV[1][1][1] >> 1;
+ }
+ }
+
+ macroblock_2fbmv.dw2 = mv0[0].v;
+ macroblock_2fbmv.dw3 = mv0[1].v;
+ macroblock_2fbmv.dw4 = mv1[0].v;
+ macroblock_2fbmv.dw5 = mv1[1].v;
+
+ intelBatchbufferData(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
}
#if 0
@@ -1646,9 +1601,7 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
pI915XvMC->psc.size = tmpComm->psc.size;
if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
- pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
- pI915XvMC->deviceID == PCI_CHIP_I945_G ||
- pI915XvMC->deviceID == PCI_CHIP_I945_GM) {
+ pI915XvMC->deviceID == PCI_CHIP_I915_GM) {
pI915XvMC->sis.bus_addr = tmpComm->sis.bus_addr;
pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr;
pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr;
@@ -1683,6 +1636,16 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
pI915XvMC->last_flip = 0;
pI915XvMC->port = context->port;
pI915XvMC->ref = 1;
+
+ /* pre-init state buffers */
+ i915_mc_one_time_context_init(context);
+ i915_mc_one_time_state_init(context);
+
+ i915_mc_static_indirect_state_init(context);
+
+ i915_mc_map_state_init(context);
+
+ i915_mc_load_indirect_render_init(context);
return Success;
}
@@ -1695,6 +1658,10 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
/* Pass Control to the X server to destroy the drm_context_t */
i915_release_resource(display,context);
+
+ free(one_time_load_state_imm1);
+ free(one_time_load_indirect);
+ free(mc_render_load_indirect);
return Success;
}
@@ -1850,9 +1817,8 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
if (!(privTarget = target_surface->privData))
return XvMCBadSurface;
- /* Test For YV12 Surface */
- if (context->surface_type_id != FOURCC_YV12) {
- XVMC_ERR("HWMC only possible on YV12 Surfaces.");
+ if (context->surface_type_id >= SURFACE_TYPE_MAX) {
+ XVMC_ERR("Unsupprted surface_type_id %d.", context->surface_type_id);
return BadValue;
}
@@ -1938,16 +1904,15 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
// i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB
// | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC);
- i915_mc_sampler_state_buffer(context);
- i915_mc_pixel_shader_program_buffer(context);
- i915_mc_pixel_shader_constants_buffer(context);
- i915_mc_one_time_state_initialization(context);
+ i915_mc_one_time_state_emit();
+
+ i915_mc_static_indirect_state_set(context, target_surface, picture_structure,
+ flags, picture_coding_type);
+ /* setup reference surfaces */
+ i915_mc_map_state_set(context, privPast, privFuture);
+
+ i915_mc_load_indirect_render_emit();
- i915_mc_static_indirect_state_buffer(context, target_surface,
- picture_structure, flags,
- picture_coding_type);
- i915_mc_map_state_buffer(context, privTarget, privPast, privFuture);
- i915_mc_load_sis_msb_buffers(context);
i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
index ae357aa5..8fabb35e 100644
--- a/src/xvmc/intel_xvmc.c
+++ b/src/xvmc/intel_xvmc.c
@@ -98,9 +98,17 @@ unsigned int mb_bytes_420[] = {
768 /* 111111 */
};
+int DEBUG;
+
static int error_base;
static int event_base;
+static void intel_xvmc_debug_init(void)
+{
+ if (getenv("INTEL_XVMC_DEBUG"))
+ DEBUG = 1;
+}
+
/* locking */
static void intel_xvmc_try_heavy_lock(drm_context_t ctx)
{
@@ -282,6 +290,8 @@ Status XvMCCreateContext(Display *display, XvPortID port,
return BadValue;
}
+ intel_xvmc_debug_init();
+
/* Open DRI Device */
if((fd = drmOpen("i915", NULL)) < 0) {
XVMC_ERR("DRM Device could not be opened.");
@@ -588,7 +598,7 @@ Status XvMCCreateBlocks(Display *display, XvMCContext *context,
*/
Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block)
{
- if (!display || block)
+ if (!display || !block)
return BadValue;
if (block->blocks)
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
index 31196238..c4dfd770 100644
--- a/src/xvmc/intel_xvmc.h
+++ b/src/xvmc/intel_xvmc.h
@@ -38,6 +38,7 @@
#include <string.h>
#include <assert.h>
#include <signal.h>
+#include <stdint.h>
#include <xf86drm.h>
#include "i830_common.h"
@@ -56,7 +57,7 @@
#include "intel_batchbuffer.h"
-#define DEBUG 0
+extern int DEBUG;
#define XVMC_ERR(s, arg...) \
do { \
diff --git a/src/xvmc/intel_xvmc_dump.c b/src/xvmc/intel_xvmc_dump.c
index 12fc52a5..419bd0d8 100644
--- a/src/xvmc/intel_xvmc_dump.c
+++ b/src/xvmc/intel_xvmc_dump.c
@@ -116,18 +116,25 @@ void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure
fprintf(fp, "intra ");
fprintf(fp, ") ");
fprintf(fp, "mc type ");
- if (mb->motion_type & XVMC_PREDICTION_FIELD)
- fprintf(fp, "(field) ");
- else if (mb->motion_type & XVMC_PREDICTION_FRAME)
- fprintf(fp, "(frame) ");
- else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME)
- fprintf(fp, "(dual-prime) ");
- else if (mb->motion_type & XVMC_PREDICTION_16x8)
- fprintf(fp, "(16x8) ");
- else if (mb->motion_type & XVMC_PREDICTION_4MV)
- fprintf(fp, "(4MV) ");
- else
- fprintf(fp, "(none) ");
+ if (picture_structure == XVMC_FRAME_PICTURE) {
+ if (mb->motion_type & XVMC_PREDICTION_FIELD)
+ fprintf(fp, "(field) ");
+ else if (mb->motion_type & XVMC_PREDICTION_FRAME)
+ fprintf(fp, "(frame) ");
+ else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME)
+ fprintf(fp, "(dual-prime) ");
+ else
+ fprintf(fp, "(unknown %d) ", mb->motion_type);
+ } else { /* field */
+ if (mb->motion_type & XVMC_PREDICTION_FIELD)
+ fprintf(fp, "(field) ");
+ else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME)
+ fprintf(fp, "(dual-prime) ");
+ else if (mb->motion_type & XVMC_PREDICTION_16x8)
+ fprintf(fp, "(16x8) ");
+ else
+ fprintf(fp, "(unknown %d) ", mb->motion_type);
+ }
if (mb->dct_type == XVMC_DCT_TYPE_FRAME)
fprintf(fp, "dct type (frame) ");