summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyu.z.wang@intel.com>2008-03-20 10:31:57 +0800
committerZhenyu Wang <zhenyu.z.wang@intel.com>2008-03-20 10:31:57 +0800
commit224c36cc14a7552bc5df793ad582f0ea5349eb1e (patch)
tree8cf03bb242d4e4f07f2889acfbb4b4029b72f22d /src
parent4b9b7b007d729f94b01b0031d8ae478134b501da (diff)
parent03ccffd5b9b8108166ea143884a1a0a6417f3236 (diff)
Merge branch 'xvmc'
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am15
-rw-r--r--src/brw_defines.h26
-rw-r--r--src/brw_structs.h107
-rw-r--r--src/i830.h16
-rw-r--r--src/i830_driver.c28
-rw-r--r--src/i830_hwmc.c154
-rw-r--r--src/i830_hwmc.h106
-rw-r--r--src/i830_memory.c22
-rw-r--r--src/i830_video.c65
-rw-r--r--src/i915_hwmc.c873
-rw-r--r--src/i915_hwmc.h61
-rw-r--r--src/xvmc/Makefile.am20
-rw-r--r--src/xvmc/driDrawable.c174
-rw-r--r--src/xvmc/driDrawable.h64
-rw-r--r--src/xvmc/i915_program.h276
-rw-r--r--src/xvmc/i915_structs.h973
-rw-r--r--src/xvmc/i915_xvmc.c2535
-rw-r--r--src/xvmc/i915_xvmc.h117
-rw-r--r--src/xvmc/intel_batchbuffer.c271
-rw-r--r--src/xvmc/intel_batchbuffer.h42
-rw-r--r--src/xvmc/intel_xvmc.c1069
-rw-r--r--src/xvmc/intel_xvmc.h252
-rw-r--r--src/xvmc/xf86dri.c601
-rw-r--r--src/xvmc/xf86dri.h111
-rw-r--r--src/xvmc/xf86dristr.h390
25 files changed, 8359 insertions, 9 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 8fc21d3e..7df69b61 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -61,6 +61,13 @@ INTEL_DRI_SRCS = \
i810_hwmc.c \
i830_dri.h
+INTEL_XVMC_SRCS = \
+ i830_hwmc.h \
+ i830_hwmc.c \
+ i915_hwmc.c \
+ i915_hwmc.h
+
+
intel_drv_la_SOURCES = \
brw_defines.h \
brw_structs.h \
@@ -147,7 +154,8 @@ EXTRA_DIST = \
$(XMODE_SRCS) \
$(INTEL_G4A) \
$(INTEL_G4H) \
- $(INTEL_DRI_SRCS)
+ $(INTEL_DRI_SRCS) \
+ $(INTEL_XVMC_SRCS)
if HAVE_GEN4ASM
@@ -193,6 +201,11 @@ intel_drv_la_SOURCES += \
$(INTEL_DRI_SRCS)
endif
+if XVMC
+intel_drv_la_SOURCES += \
+ $(INTEL_XVMC_SRCS)
+endif
+
install-data-local: install-intel_drv_laLTLIBRARIES
(cd $(DESTDIR)$(intel_drv_ladir) && rm -f i810_drv.so && ln -s intel_drv.so i810_drv.so)
diff --git a/src/brw_defines.h b/src/brw_defines.h
index 93aed544..13cb4396 100644
--- a/src/brw_defines.h
+++ b/src/brw_defines.h
@@ -842,6 +842,30 @@
#define R02_PRIM_END 0x1
#define R02_PRIM_START 0x2
-
+/* media pipeline */
+
+#define BRW_VFE_MODE_GENERIC 0x0
+#define BRW_VFE_MODE_VLD_MPEG2 0x1
+#define BRW_VFE_MODE_IS 0x2
+#define BRW_VFE_MODE_AVC_MC 0x4
+#define BRW_VFE_MODE_AVC_IT 0x7
+#define BRW_VFE_MODE_VC1_IT 0xB
+
+#define BRW_VFE_DEBUG_COUNTER_FREE 0
+#define BRW_VFE_DEBUG_COUNTER_FROZEN 1
+#define BRW_VFE_DEBUG_COUNTER_ONCE 2
+#define BRW_VFE_DEBUG_COUNTER_ALWAYS 3
+
+/* VLD_STATE */
+#define BRW_MPEG_TOP_FIELD 1
+#define BRW_MPEG_BOTTOM_FIELD 2
+#define BRW_MPEG_FRAME 3
+#define BRW_MPEG_QSCALE_LINEAR 0
+#define BRW_MPEG_QSCALE_NONLINEAR 1
+#define BRW_MPEG_ZIGZAG_SCAN 0
+#define BRW_MPEG_ALTER_VERTICAL_SCAN 1
+#define BRW_MPEG_I_PICTURE 1
+#define BRW_MPEG_P_PICTURE 2
+#define BRW_MPEG_B_PICTURE 3
#endif
diff --git a/src/brw_structs.h b/src/brw_structs.h
index d4fc5c67..ef7906b4 100644
--- a/src/brw_structs.h
+++ b/src/brw_structs.h
@@ -1342,5 +1342,112 @@ struct brw_instruction
} bits3;
};
+/* media pipeline */
+
+struct brw_vfe_state {
+ struct {
+ unsigned int per_thread_scratch_space:4;
+ unsigned int pad3:3;
+ unsigned int extend_vfe_state_present:1;
+ unsigned int pad2:2;
+ unsigned int scratch_base:22;
+ } vfe0;
+
+ struct {
+ unsigned int debug_counter_control:2;
+ unsigned int children_present:1;
+ unsigned int vfe_mode:4;
+ unsigned int pad2:2;
+ unsigned int num_urb_entries:7;
+ unsigned int urb_entry_alloc_size:9;
+ unsigned int max_threads:7;
+ } vfe1;
+
+ struct {
+ unsigned int pad4:4;
+ unsigned int interface_descriptor_base:28;
+ } vfe2;
+};
+
+struct brw_vld_state {
+ struct {
+ unsigned int pad6:6;
+ unsigned int scan_order:1;
+ unsigned int intra_vlc_format:1;
+ unsigned int quantizer_scale_type:1;
+ unsigned int concealment_motion_vector:1;
+ unsigned int frame_predict_frame_dct:1;
+ unsigned int top_field_first:1;
+ unsigned int picture_structure:2;
+ unsigned int intra_dc_precision:2;
+ unsigned int f_code_0_0:4;
+ unsigned int f_code_0_1:4;
+ unsigned int f_code_1_0:4;
+ unsigned int f_code_1_1:4;
+ } vld0;
+
+ struct {
+ unsigned int pad2:9;
+ unsigned int picture_coding_type:2;
+ unsigned int pad:21;
+ } vld1;
+
+ struct {
+ unsigned int index_0:4;
+ unsigned int index_1:4;
+ unsigned int index_2:4;
+ unsigned int index_3:4;
+ unsigned int index_4:4;
+ unsigned int index_5:4;
+ unsigned int index_6:4;
+ unsigned int index_7:4;
+ } desc_remap_table0;
+
+ struct {
+ unsigned int index_8:4;
+ unsigned int index_9:4;
+ unsigned int index_10:4;
+ unsigned int index_11:4;
+ unsigned int index_12:4;
+ unsigned int index_13:4;
+ unsigned int index_14:4;
+ unsigned int index_15:4;
+ } desc_remap_table1;
+};
+
+struct brw_interface_descriptor {
+ struct {
+ unsigned int grf_reg_blocks:4;
+ unsigned int pad:2;
+ unsigned int kernel_start_pointer:26;
+ } desc0;
+
+ struct {
+ unsigned int pad:7;
+ unsigned int software_exception:1;
+ unsigned int pad2:3;
+ unsigned int maskstack_exception:1;
+ unsigned int pad3:1;
+ unsigned int illegal_opcode_exception:1;
+ unsigned int pad4:2;
+ unsigned int floating_point_mode:1;
+ unsigned int thread_priority:1;
+ unsigned int single_program_flow:1;
+ unsigned int pad5:1;
+ unsigned int const_urb_entry_read_offset:6;
+ unsigned int const_urb_entry_read_len:6;
+ } desc1;
+
+ struct {
+ unsigned int pad:2;
+ unsigned int sampler_count:3;
+ unsigned int sampler_state_pointer:27;
+ } desc2;
+
+ struct {
+ unsigned int binding_table_entry_count:5;
+ unsigned int binding_table_pointer:27;
+ } desc3;
+};
#endif
diff --git a/src/i830.h b/src/i830.h
index 512938cd..c84e8023 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -118,6 +118,12 @@ typedef struct _I830OutputRec I830OutputRec, *I830OutputPtr;
#define I830_KERNEL_TEX (1 << 1) /* Allocate texture memory pool */
#endif
+#ifdef XvMCExtension
+#ifdef ENABLE_XVMC
+#define INTEL_XVMC 1
+#endif
+#endif
+
typedef struct _I830Rec *I830Ptr;
typedef void (*I830WriteIndexedByteFunc)(I830Ptr pI830, IOADDRESS addr,
@@ -406,6 +412,12 @@ typedef struct _I830Rec {
/* For Xvideo */
i830_memory *overlay_regs;
#endif
+#ifdef INTEL_XVMC
+ /* For XvMC */
+ Bool XvMCEnabled;
+ Bool IsXvMCSurface;
+#endif
+
XF86ModReqInfo shadowReq; /* to test for later libshadow */
Rotation rotation;
void (*PointerMoved)(int, int, int);
@@ -746,6 +758,10 @@ extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn);
Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn);
Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn);
Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn);
+#ifdef INTEL_XVMC
+Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
+ i830_memory **buffer, unsigned long size, int flags);
+#endif
extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index d5b260c4..98f4261c 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -199,6 +199,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830_bios.h"
#include "i830_video.h"
+#ifdef INTEL_XVMC
+#define _INTEL_XVMC_SERVER_
+#include "i830_hwmc.h"
+#endif
+
#ifdef XF86DRI
#include "dri.h"
#include <sys/ioctl.h>
@@ -298,7 +303,10 @@ typedef enum {
OPTION_INTELTEXPOOL,
#endif
OPTION_TRIPLEBUFFER,
- OPTION_FORCEENABLEPIPEA
+ OPTION_FORCEENABLEPIPEA,
+#ifdef INTEL_XVMC
+ OPTION_XVMC,
+#endif
} I830Opts;
static OptionInfoRec I830Options[] = {
@@ -322,6 +330,9 @@ static OptionInfoRec I830Options[] = {
#endif
{OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_FORCEENABLEPIPEA, "ForceEnablePipeA", OPTV_BOOLEAN, {0}, FALSE},
+#ifdef INTEL_XVMC
+ {OPTION_XVMC, "XvMC", OPTV_BOOLEAN, {0}, TRUE},
+#endif
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
/* *INDENT-ON* */
@@ -1620,6 +1631,15 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->TripleBuffer ? "en" : "dis");
#endif
+#ifdef INTEL_XVMC
+ pI830->XvMCEnabled = FALSE;
+ from = (!pI830->directRenderingDisabled &&
+ xf86GetOptValBool(pI830->Options, OPTION_XVMC,
+ &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n",
+ pI830->XvMCEnabled ? "en" : "dis");
+#endif
+
/*
* If the driver can do gamma correction, it should call xf86SetGamma() here.
*/
@@ -3078,6 +3098,12 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
static void
I830FreeScreen(int scrnIndex, int flags)
{
+#ifdef INTEL_XVMC
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ I830Ptr pI830 = I830PTR(pScrn);
+ if (pI830->XvMCEnabled)
+ intel_xvmc_finish(xf86Screens[scrnIndex]);
+#endif
I830FreeRec(xf86Screens[scrnIndex]);
if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
vgaHWFreeHWRec(xf86Screens[scrnIndex]);
diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c
new file mode 100644
index 00000000..7586ff71
--- /dev/null
+++ b/src/i830_hwmc.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Zhenyu Wang <zhenyu.z.wang@intel.com>
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define _INTEL_XVMC_SERVER_
+#include "i830.h"
+#include "i830_hwmc.h"
+
+struct intel_xvmc_driver *xvmc_driver;
+
+/* set global current driver for xvmc */
+Bool intel_xvmc_set_driver(struct intel_xvmc_driver *d)
+{
+ if (xvmc_driver) {
+ ErrorF("XvMC driver already set!\n");
+ return FALSE;
+ } else
+ xvmc_driver = d;
+ return TRUE;
+}
+
+/* check chip type and load xvmc driver */
+/* This must be first called! */
+Bool intel_xvmc_probe(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ Bool ret = FALSE;
+
+ if (!pI830->XvMCEnabled)
+ return FALSE;
+
+ if (IS_I9XX(pI830)) {
+ if (!IS_I965G(pI830))
+ ret = intel_xvmc_set_driver(&i915_xvmc_driver);
+ /*
+ else
+ ret = intel_xvmc_set_driver(&i965_xvmc_driver);
+ */
+ } else {
+ ErrorF("Your chipset doesn't support XvMC.\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void intel_xvmc_finish(ScrnInfoPtr pScrn)
+{
+ if (!xvmc_driver)
+ return;
+ (*xvmc_driver->fini)(pScrn);
+}
+
+Bool intel_xvmc_driver_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if (!xvmc_driver) {
+ ErrorF("Failed to probe XvMC driver.\n");
+ return FALSE;
+ }
+
+ if (!(*xvmc_driver->init)(pScrn, xv_adaptor)) {
+ ErrorF("XvMC driver initialize failed.\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+Bool intel_xvmc_screen_init(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
+
+ if (!xvmc_driver)
+ return FALSE;
+
+ if (xf86XvMCScreenInit(pScreen, 1, &xvmc_driver->adaptor)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[XvMC] %s driver initialized.\n",
+ xvmc_driver->name);
+ } else {
+ intel_xvmc_finish(pScrn);
+ pI830->XvMCEnabled = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[XvMC] Failed to initialize XvMC.\n");
+ return FALSE;
+ }
+
+ xf86XvMCRegisterDRInfo(pScreen, INTEL_XVMC_LIBNAME,
+ pDRIInfo->busIdString,
+ INTEL_XVMC_MAJOR, INTEL_XVMC_MINOR, INTEL_XVMC_PATCHLEVEL);
+ return TRUE;
+}
+
+Bool intel_xvmc_init_batch(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC] batch buffer",
+ &(xvmc_driver->batch), 8 * 1024,
+ ALIGN_BOTH_ENDS))
+ return FALSE;
+
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(xvmc_driver->batch->offset+pI830->LinearAddr),
+ xvmc_driver->batch->size, DRM_AGP, 0,
+ &xvmc_driver->batch_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(batchbuffer_handle) failed!\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void intel_xvmc_fini_batch(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (xvmc_driver->batch_handle) {
+ drmRmMap(pI830->drmSubFD, xvmc_driver->batch_handle);
+ xvmc_driver->batch_handle = 0;
+ }
+ if (xvmc_driver->batch) {
+ i830_free_memory(pScrn, xvmc_driver->batch);
+ xvmc_driver->batch = NULL;
+ }
+}
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h
new file mode 100644
index 00000000..6920e016
--- /dev/null
+++ b/src/i830_hwmc.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Zhenyu Wang <zhenyu.z.wang@intel.com>
+ *
+ */
+#ifndef I830_HWMC_H
+#define I830_HWMC_H
+
+#define INTEL_XVMC_LIBNAME "IntelXvMC"
+#define INTEL_XVMC_MAJOR 0
+#define INTEL_XVMC_MINOR 1
+#define INTEL_XVMC_PATCHLEVEL 0
+
+#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
+
+/*
+ * Commands that client submits through XvPutImage:
+ */
+
+#define INTEL_XVMC_COMMAND_DISPLAY 0x00
+#define INTEL_XVMC_COMMAND_UNDISPLAY 0x01
+
+/* hw xvmc support type */
+#define XVMC_I915_MPEG2_MC 0x01
+#define XVMC_I965_MPEG2_MC 0x02
+#define XVMC_I945_MPEG2_VLD 0x04
+#define XVMC_I965_MPEG2_VLD 0x08
+
+/* common header for context private */
+struct hwmc_buffer
+{
+ drm_handle_t handle;
+ unsigned long offset;
+ unsigned long size;
+ unsigned long bus_addr;
+};
+
+struct _intel_xvmc_common {
+ unsigned int type;
+ unsigned int sarea_size;
+ struct hwmc_buffer batchbuffer;
+};
+
+/* Intel private XvMC command to DDX driver */
+struct intel_xvmc_command {
+ unsigned int command;
+ unsigned int ctxNo;
+ unsigned int srfNo;
+ unsigned int subPicNo;
+ unsigned int flags;
+ unsigned int real_id;
+ unsigned int pad[6];
+};
+
+#ifdef _INTEL_XVMC_SERVER_
+#include <xf86xvmc.h>
+
+struct intel_xvmc_driver {
+ char *name;
+ XF86MCAdaptorPtr adaptor;
+ unsigned int flag;
+ i830_memory *batch;
+ drm_handle_t batch_handle;
+
+ /* more items for xvmv surface manage? */
+ Bool (*init)(ScrnInfoPtr, XF86VideoAdaptorPtr);
+ void (*fini)(ScrnInfoPtr);
+ void* devPrivate;
+};
+
+extern struct intel_xvmc_driver *xvmc_driver;
+extern struct intel_xvmc_driver i915_xvmc_driver;
+/* extern struct intel_xvmc_driver i965_xvmc_driver; */
+
+extern Bool intel_xvmc_set_driver(struct intel_xvmc_driver *);
+extern Bool intel_xvmc_probe(ScrnInfoPtr);
+extern Bool intel_xvmc_driver_init(ScreenPtr, XF86VideoAdaptorPtr);
+extern Bool intel_xvmc_screen_init(ScreenPtr);
+extern void intel_xvmc_finish(ScrnInfoPtr);
+extern int intel_xvmc_put_image_size(ScrnInfoPtr);
+extern Bool intel_xvmc_init_batch(ScrnInfoPtr);
+extern void intel_xvmc_fini_batch(ScrnInfoPtr);
+#endif
+
+#endif
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 2cac26b7..9e23c3ca 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -2015,3 +2015,25 @@ I830CheckAvailableMemory(ScrnInfoPtr pScrn)
return maxPages * 4;
}
+
+/*
+ * Allocate memory for MC compensation
+ */
+Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
+ i830_memory **buffer, unsigned long size,
+ int flags)
+{
+ *buffer = i830_allocate_memory(pScrn, name, size,
+ GTT_PAGE_SIZE, flags);
+
+ if (!*buffer) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate memory for %s.\n", name);
+ return FALSE;
+ }
+
+ if (!i830_bind_memory(pScrn, *buffer))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/src/i830_video.c b/src/i830_video.c
index c25e9921..0d0a9a03 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -75,6 +75,12 @@
#include "dixstruct.h"
#include "fourcc.h"
+#ifdef INTEL_XVMC
+#define _INTEL_XVMC_SERVER_
+#include "i830_hwmc.h"
+#include "i915_hwmc.h"
+#endif
+
#ifndef USE_USLEEP_FOR_VIDEO
#define USE_USLEEP_FOR_VIDEO 0
#endif
@@ -254,13 +260,39 @@ static XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = {
{XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"}
};
-#define NUM_IMAGES 4
+#define NUM_IMAGES 5
static XF86ImageRec Images[NUM_IMAGES] = {
XVIMAGE_YUY2,
XVIMAGE_YV12,
XVIMAGE_I420,
- XVIMAGE_UYVY
+ XVIMAGE_UYVY,
+#ifdef INTEL_XVMC
+ {
+ /*
+ * Below, a dummy picture type that is used in XvPutImage only to do
+ * an overlay update. Introduced for the XvMC client lib.
+ * Defined to have a zero data size.
+ */
+ FOURCC_XVMC,
+ XvYUV,
+ LSBFirst,
+ {'X', 'V', 'M', 'C',
+ 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00,
+ 0x38, 0x9B, 0x71},
+ 12,
+ XvPlanar,
+ 3,
+ 0, 0, 0, 0,
+ 8, 8, 8,
+ 1, 2, 2,
+ 1, 2, 2,
+ {'Y', 'V', 'U',
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ XvTopToBottom
+ },
+#endif
};
typedef struct {
@@ -592,10 +624,21 @@ I830InitVideo(ScreenPtr pScreen)
}
I830InitOffscreenImages(pScreen);
}
+#ifdef INTEL_XVMC
+ Bool ret = FALSE;
+ if (intel_xvmc_probe(pScrn)) {
+ if (texturedAdaptor)
+ ret = intel_xvmc_driver_init(pScreen, texturedAdaptor);
+ }
+#endif
if (num_adaptors)
xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+#ifdef INTEL_XVMC
+ if (ret)
+ intel_xvmc_screen_init(pScreen);
+#endif
xfree(adaptors);
}
@@ -2277,8 +2320,14 @@ I830PutImage(ScrnInfoPtr pScrn,
switch (id) {
case FOURCC_YV12:
case FOURCC_I420:
- srcPitch = (width + 3) & ~3;
- srcPitch2 = ((width >> 1) + 3) & ~3;
+ srcPitch = (width + 0x3) & ~0x3;
+ srcPitch2 = ((width >> 1) + 0x3) & ~0x3;
+#ifdef INTEL_XVMC
+ if (pI830->IsXvMCSurface) {
+ srcPitch = (width + 0x3ff) & ~0x3ff;
+ srcPitch2 = ((width >> 1) + 0x3ff) & ~0x3ff;
+ }
+#endif
if (pPriv->textured && IS_I965G(pI830))
destId = FOURCC_YUY2;
break;
@@ -2533,6 +2582,14 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn,
ErrorF("size is %d\n", size);
#endif
break;
+#ifdef INTEL_XVMC
+ case FOURCC_XVMC:
+ *h = (*h + 1) & ~1;
+ size = sizeof(struct intel_xvmc_command);
+ if (pitches)
+ pitches[0] = size;
+ break;
+#endif
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c
new file mode 100644
index 00000000..cdcef5a8
--- /dev/null
+++ b/src/i915_hwmc.c
@@ -0,0 +1,873 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Xiang Haihao <haihao.xiang@intel.com>
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "compiler.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86fbman.h"
+#include "regionstr.h"
+
+#include "i830.h"
+#include "i830_dri.h"
+#include "i830_video.h"
+#include "xf86xv.h"
+#include "xf86xvmc.h"
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/XvMC.h>
+#include "xaa.h"
+#include "xaalocal.h"
+#include "dixstruct.h"
+#include "fourcc.h"
+
+#if defined(X_NEED_XVPRIV_H) || defined (_XF86_FOURCC_H_)
+#include "xf86xvpriv.h"
+#endif
+
+#define _INTEL_XVMC_SERVER_
+#include "i915_hwmc.h"
+
+#define I915_XVMC_MAX_BUFFERS 2
+#define I915_XVMC_MAX_CONTEXTS 4
+#define I915_XVMC_MAX_SURFACES 20
+
+typedef struct _I915XvMCSurfacePriv
+{
+ i830_memory *surface;
+ unsigned long offsets[I915_XVMC_MAX_BUFFERS];
+ drm_handle_t surface_handle;
+} I915XvMCSurfacePriv;
+
+typedef struct _I915XvMCContextPriv
+{
+ i830_memory *mcStaticIndirectState;
+ drm_handle_t sis_handle;
+ i830_memory *mcSamplerState;
+ drm_handle_t ssb_handle;
+ i830_memory *mcMapState;
+ drm_handle_t msb_handle;
+ i830_memory *mcPixelShaderProgram;
+ drm_handle_t psp_handle;
+ i830_memory *mcPixelShaderConstants;
+ drm_handle_t psc_handle;
+ i830_memory *mcCorrdata;
+ drm_handle_t corrdata_handle;
+} I915XvMCContextPriv;
+
+typedef struct _I915XvMC
+{
+ XID contexts[I915_XVMC_MAX_CONTEXTS];
+ XID surfaces[I915_XVMC_MAX_SURFACES];
+ I915XvMCSurfacePriv *sfprivs[I915_XVMC_MAX_SURFACES];
+ I915XvMCContextPriv *ctxprivs[I915_XVMC_MAX_CONTEXTS];
+ int ncontexts,nsurfaces;
+ PutImageFuncPtr savePutImage;
+} I915XvMC, *I915XvMCPtr;
+
+#define ARRARY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+static int yv12_subpicture_index_list[2] =
+{
+ FOURCC_IA44,
+ FOURCC_AI44
+};
+
+static XF86MCImageIDList yv12_subpicture_list =
+{
+ ARRARY_SIZE(yv12_subpicture_index_list),
+ yv12_subpicture_index_list
+};
+
+static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface =
+{
+ FOURCC_YV12,
+ XVMC_CHROMA_FORMAT_420,
+ 0,
+ 720,
+ 576,
+ 720,
+ 576,
+ XVMC_MPEG_2,
+ /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,*/
+ 0,
+ /* &yv12_subpicture_list*/
+ NULL,
+};
+
+static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface =
+{
+ FOURCC_YV12,
+ XVMC_CHROMA_FORMAT_420,
+ 0,
+ 720,
+ 576,
+ 720,
+ 576,
+ XVMC_MPEG_1,
+ /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING,*/
+ 0,
+ /* &yv12_subpicture_list*/
+ NULL,
+};
+
+static XF86MCSurfaceInfoPtr ppSI[2] =
+{
+ (XF86MCSurfaceInfoPtr)&i915_YV12_mpg2_surface,
+ (XF86MCSurfaceInfoPtr)&i915_YV12_mpg1_surface
+};
+
+/* List of subpicture types that we support */
+static XF86ImageRec ia44_subpicture = XVIMAGE_IA44;
+static XF86ImageRec ai44_subpicture = XVIMAGE_AI44;
+
+static XF86ImagePtr i915_subpicture_list[2] =
+{
+ (XF86ImagePtr)&ia44_subpicture,
+ (XF86ImagePtr)&ai44_subpicture
+};
+
+
+/*
+ * Init and clean up the screen private parts of XvMC.
+ */
+static void initI915XvMC(I915XvMCPtr xvmc)
+{
+ unsigned int i;
+
+ for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
+ xvmc->contexts[i] = 0;
+ xvmc->ctxprivs[i] = NULL;
+ }
+
+ for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
+ xvmc->surfaces[i] = 0;
+ xvmc->sfprivs[i] = NULL;
+ }
+ xvmc->ncontexts = 0;
+ xvmc->nsurfaces = 0;
+}
+
+static void cleanupI915XvMC(I915XvMCPtr xvmc)
+{
+ int i;
+
+ for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
+ xvmc->contexts[i] = 0;
+ if (xvmc->ctxprivs[i]) {
+ xfree(xvmc->ctxprivs[i]);
+ xvmc->ctxprivs[i] = NULL;
+ }
+ }
+
+ for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
+ xvmc->surfaces[i] = 0;
+ if (xvmc->sfprivs[i]) {
+ xfree(xvmc->sfprivs[i]);
+ xvmc->sfprivs[i] = NULL;
+ }
+ }
+}
+
+static Bool i915_map_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(ctxpriv->mcStaticIndirectState->offset + pI830->LinearAddr),
+ ctxpriv->mcStaticIndirectState->size, DRM_AGP, 0,
+ (drmAddress)&ctxpriv->sis_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(sis_handle) failed!\n");
+ return FALSE;
+ }
+
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(ctxpriv->mcSamplerState->offset + pI830->LinearAddr),
+ ctxpriv->mcSamplerState->size, DRM_AGP, 0,
+ (drmAddress)&ctxpriv->ssb_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(ssb_handle) failed!\n");
+ return FALSE;
+ }
+
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(ctxpriv->mcMapState->offset + pI830->LinearAddr),
+ ctxpriv->mcMapState->size, DRM_AGP, 0,
+ (drmAddress)&ctxpriv->msb_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(msb_handle) failed!\n");
+ return FALSE;
+ }
+
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(ctxpriv->mcPixelShaderProgram->offset + pI830->LinearAddr),
+ ctxpriv->mcPixelShaderProgram->size, DRM_AGP, 0,
+ (drmAddress)&ctxpriv->psp_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(psp_handle) failed!\n");
+ return FALSE;
+ }
+
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(ctxpriv->mcPixelShaderConstants->offset + pI830->LinearAddr),
+ ctxpriv->mcPixelShaderConstants->size, DRM_AGP, 0,
+ (drmAddress)&ctxpriv->psc_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(psc_handle) failed!\n");
+ return FALSE;
+ }
+
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(ctxpriv->mcCorrdata->offset + pI830->LinearAddr),
+ ctxpriv->mcCorrdata->size, DRM_AGP, 0,
+ (drmAddress)&ctxpriv->corrdata_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(corrdata_handle) failed!\n");
+ return FALSE;
+ }
+
+
+ return TRUE;
+}
+
+static void i915_unmap_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (ctxpriv->sis_handle) {
+ drmRmMap(pI830->drmSubFD, ctxpriv->sis_handle);
+ ctxpriv->sis_handle = 0;
+ }
+
+ if (ctxpriv->ssb_handle) {
+ drmRmMap(pI830->drmSubFD, ctxpriv->ssb_handle);
+ ctxpriv->ssb_handle = 0;
+ }
+
+ if (ctxpriv->msb_handle) {
+ drmRmMap(pI830->drmSubFD, ctxpriv->msb_handle);
+ ctxpriv->msb_handle = 0;
+ }
+
+ if (ctxpriv->psp_handle) {
+ drmRmMap(pI830->drmSubFD, ctxpriv->psp_handle);
+ ctxpriv->psp_handle = 0;
+ }
+
+ if (ctxpriv->psc_handle) {
+ drmRmMap(pI830->drmSubFD, ctxpriv->psc_handle);
+ ctxpriv->psc_handle = 0;
+ }
+
+ if (ctxpriv->corrdata_handle) {
+ drmRmMap(pI830->drmSubFD, ctxpriv->corrdata_handle);
+ ctxpriv->corrdata_handle = 0;
+ }
+
+}
+
+static Bool i915_allocate_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ int flags = ALIGN_BOTH_ENDS;
+
+ if (IS_I915G(pI830) || IS_I915GM(pI830) ||
+ IS_I945G(pI830) || IS_I945GM(pI830))
+ flags |= NEED_PHYSICAL_ADDR;
+
+ if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Static Indirect State",
+ &(ctxpriv->mcStaticIndirectState), 4 * 1024,
+ flags)) {
+ return FALSE;
+ }
+
+ if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Sampler State",
+ &(ctxpriv->mcSamplerState), 4 * 1024,
+ flags)) {
+ return FALSE;
+ }
+
+ if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Map State",
+ &(ctxpriv->mcMapState), 4 * 1024,
+ flags)) {
+ return FALSE;
+ }
+
+ if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Pixel Shader Program",
+ &(ctxpriv->mcPixelShaderProgram), 4 * 1024,
+ flags)) {
+ return FALSE;
+ }
+
+ if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC]Pixel Shader Constants",
+ &(ctxpriv->mcPixelShaderConstants), 4 * 1024,
+ flags)) {
+ return FALSE;
+ }
+
+ 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, "");
+
+ return TRUE;
+}
+
+static void i915_free_xvmc_buffers(ScrnInfoPtr pScrn, I915XvMCContextPriv *ctxpriv)
+{
+ if (ctxpriv->mcStaticIndirectState) {
+ i830_free_memory(pScrn, ctxpriv->mcStaticIndirectState);
+ ctxpriv->mcStaticIndirectState = NULL;
+ }
+
+ if (ctxpriv->mcSamplerState) {
+ i830_free_memory(pScrn, ctxpriv->mcSamplerState);
+ ctxpriv->mcSamplerState = NULL;
+ }
+
+ if (ctxpriv->mcMapState) {
+ i830_free_memory(pScrn, ctxpriv->mcMapState);
+ ctxpriv->mcMapState = NULL;
+ }
+
+ if (ctxpriv->mcPixelShaderProgram) {
+ i830_free_memory(pScrn, ctxpriv->mcPixelShaderProgram);
+ ctxpriv->mcPixelShaderProgram = NULL;
+ }
+
+ if (ctxpriv->mcPixelShaderConstants) {
+ i830_free_memory(pScrn, ctxpriv->mcPixelShaderConstants);
+ ctxpriv->mcPixelShaderConstants = NULL;
+ }
+
+ if (ctxpriv->mcCorrdata) {
+ i830_free_memory(pScrn, ctxpriv->mcCorrdata);
+ ctxpriv->mcCorrdata = NULL;
+ }
+
+}
+
+/*
+ * i915_xvmc_create_context
+ *
+ * Some info about the private data:
+ *
+ * Set *num_priv to the number of 32bit words that make up the size of
+ * of the data that priv will point to.
+ *
+ * *priv = (long *) xcalloc (elements, sizeof(element))
+ * *num_priv = (elements * sizeof(element)) >> 2;
+ *
+ **************************************************************************/
+
+static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext,
+ int *num_priv, long **priv )
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
+ I830DRIPtr pI830DRI = pDRIInfo->devPrivate;
+ I915XvMCCreateContextRec *contextRec = NULL;
+ I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
+ I915XvMCContextPriv *ctxpriv = NULL;
+ int i;
+
+ *priv = NULL;
+ *num_priv = 0;
+
+ if (!pI830->XvMCEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915: XvMC disabled!\n");
+ return BadAlloc;
+ }
+
+ for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
+ if (!pXvMC->contexts[i])
+ break;
+ }
+
+ if (i == I915_XVMC_MAX_CONTEXTS ||
+ pXvMC->ncontexts >= I915_XVMC_MAX_CONTEXTS) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915: Out of contexts.\n");
+ return BadAlloc;
+ }
+
+ *priv = xcalloc(1, sizeof(I915XvMCCreateContextRec));
+ contextRec = (I915XvMCCreateContextRec *)*priv;
+
+ if (!*priv) {
+ *num_priv = 0;
+ return BadAlloc;
+ }
+
+ *num_priv = sizeof(I915XvMCCreateContextRec) >> 2;
+
+ ctxpriv = (I915XvMCContextPriv *)xcalloc(1, sizeof(I915XvMCContextPriv));
+
+ if (!ctxpriv) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915: Unable to allocate memory!\n");
+ xfree(*priv);
+ *priv = NULL;
+ *num_priv = 0;
+ return BadAlloc;
+ }
+
+ if (!i915_allocate_xvmc_buffers(pScrn, ctxpriv)) {
+ i915_free_xvmc_buffers(pScrn, ctxpriv);
+ xfree(ctxpriv);
+ ctxpriv = NULL;
+ xfree(*priv);
+ *priv = NULL;
+ *num_priv = 0;
+ return BadAlloc;
+ }
+
+ if (!i915_map_xvmc_buffers(pScrn, ctxpriv)) {
+ i915_unmap_xvmc_buffers(pScrn, ctxpriv);
+ i915_free_xvmc_buffers(pScrn, ctxpriv);
+ xfree(ctxpriv);
+ ctxpriv = NULL;
+ xfree(*priv);
+ *priv = NULL;
+ *num_priv = 0;
+ return BadAlloc;
+ }
+
+ /* common context items */
+ contextRec->comm.type = xvmc_driver->flag;
+ contextRec->comm.sarea_size = pDRIInfo->SAREASize;
+ contextRec->comm.batchbuffer.offset = xvmc_driver->batch->offset;
+ contextRec->comm.batchbuffer.size = xvmc_driver->batch->size;
+ contextRec->comm.batchbuffer.handle = xvmc_driver->batch_handle;
+
+ /* i915 private context */
+ contextRec->ctxno = i;
+ 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;
+
+ pXvMC->ncontexts++;
+ pXvMC->contexts[i] = pContext->context_id;
+ pXvMC->ctxprivs[i] = ctxpriv;
+
+ return Success;
+}
+
+static int i915_xvmc_create_surface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf,
+ int *num_priv, long **priv )
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
+ I915XvMCSurfacePriv *sfpriv = NULL;
+ I915XvMCCreateSurfaceRec *surfaceRec = NULL;
+ XvMCContextPtr ctx = NULL;
+ unsigned int srfno;
+ unsigned long bufsize;
+
+ if (!pI830->XvMCEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915: XvMC disabled!\n");
+ return BadAlloc;
+ }
+
+ *priv = NULL;
+ *num_priv = 0;
+
+ for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) {
+ if (!pXvMC->surfaces[srfno])
+ break;
+ }
+
+ if (srfno == I915_XVMC_MAX_SURFACES ||
+ pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915: Too many surfaces !\n");
+ return BadAlloc;
+ }
+
+ *priv = xcalloc(1, sizeof(I915XvMCCreateSurfaceRec));
+ surfaceRec = (I915XvMCCreateSurfaceRec *)*priv;
+
+ if (!*priv) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915:Unable to allocate surface priv ret memory!\n");
+ return BadAlloc;
+ }
+
+ *num_priv = sizeof(I915XvMCCreateSurfaceRec) >> 2;
+ sfpriv = (I915XvMCSurfacePriv *)xcalloc(1, sizeof(I915XvMCSurfacePriv));
+
+ if (!sfpriv) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915: Unable to allocate surface priv memory!\n");
+ xfree(*priv);
+ *priv = NULL;
+ *num_priv = 0;
+ return BadAlloc;
+ }
+
+ ctx = pSurf->context;
+ bufsize = SIZE_YUV420(ctx->width, ctx->height);
+
+ if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface",
+ &(sfpriv->surface), bufsize,
+ ALIGN_BOTH_ENDS)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915 : Failed to allocate XvMC surface space!\n");
+ xfree(sfpriv);
+ xfree(*priv);
+ *priv = NULL;
+ *num_priv = 0;
+ return BadAlloc;
+ }
+
+ if (0)
+ i830_describe_allocations(pScrn, 1, "");
+
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(sfpriv->surface->offset + pI830->LinearAddr),
+ sfpriv->surface->size, DRM_AGP, 0,
+ (drmAddress)&sfpriv->surface_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(surface_handle) failed!\n");
+ i830_free_memory(pScrn, sfpriv->surface);
+ xfree(sfpriv);
+ xfree(*priv);
+ *priv = NULL;
+ *num_priv = 0;
+ return BadAlloc;
+ }
+
+ surfaceRec->srfno = srfno;
+ surfaceRec->srf.handle = sfpriv->surface_handle;
+ surfaceRec->srf.offset = sfpriv->surface->offset;
+ surfaceRec->srf.size = sfpriv->surface->size;
+
+ pXvMC->surfaces[srfno] = pSurf->surface_id;
+ pXvMC->sfprivs[srfno]= sfpriv;
+ pXvMC->nsurfaces++;
+
+ return Success;
+}
+
+static int i915_xvmc_create_subpict(ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp,
+ int *num_priv, long **priv )
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
+ I915XvMCSurfacePriv *sfpriv = NULL;
+ I915XvMCCreateSurfaceRec *surfaceRec = NULL;
+ XvMCContextPtr ctx = NULL;
+ unsigned int srfno;
+ unsigned int bufsize;
+
+ *priv = NULL;
+ *num_priv = 0;
+
+ for (srfno = 0; srfno < I915_XVMC_MAX_SURFACES; ++srfno) {
+ if (!pXvMC->surfaces[srfno])
+ break;
+ }
+
+ if (srfno == I915_XVMC_MAX_SURFACES ||
+ pXvMC->nsurfaces >= I915_XVMC_MAX_SURFACES) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915: Too many surfaces !\n");
+ return BadAlloc;
+ }
+
+ *priv = xcalloc(1, sizeof(I915XvMCCreateSurfaceRec));
+ surfaceRec = (I915XvMCCreateSurfaceRec *)*priv;
+
+ if (!*priv) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915: Unable to allocate memory!\n");
+ return BadAlloc;
+ }
+
+ *num_priv = sizeof(I915XvMCCreateSurfaceRec) >> 2;
+ sfpriv = (I915XvMCSurfacePriv *)xcalloc(1, sizeof(I915XvMCSurfacePriv));
+
+ if (!sfpriv) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915: Unable to allocate memory!\n");
+ xfree(*priv);
+ *priv = NULL;
+ *num_priv = 0;
+ return BadAlloc;
+ }
+
+ ctx = pSubp->context;
+ bufsize = SIZE_XX44(ctx->width, ctx->height);
+
+ if (!i830_allocate_xvmc_buffer(pScrn, "XvMC surface",
+ &(sfpriv->surface), bufsize,
+ ALIGN_BOTH_ENDS)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] I915XvMCCreateSurface: Failed to allocate XvMC surface space!\n");
+ xfree(sfpriv);
+ xfree(*priv);
+ *priv = NULL;
+ *num_priv = 0;
+ return BadAlloc;
+ }
+
+ if (drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(sfpriv->surface->offset + pI830->LinearAddr),
+ sfpriv->surface->size, DRM_AGP, 0,
+ (drmAddress)&sfpriv->surface_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] drmAddMap(surface_handle) failed!\n");
+ i830_free_memory(pScrn, sfpriv->surface);
+ xfree(sfpriv);
+ xfree(*priv);
+ *priv = NULL;
+ *num_priv = 0;
+ return BadAlloc;
+ }
+
+ surfaceRec->srfno = srfno;
+ surfaceRec->srf.handle = sfpriv->surface_handle;
+ surfaceRec->srf.offset = sfpriv->surface->offset;
+ surfaceRec->srf.size = sfpriv->surface->size;
+
+ pXvMC->sfprivs[srfno] = sfpriv;
+ pXvMC->surfaces[srfno] = pSubp->subpicture_id;
+ pXvMC->nsurfaces++;
+
+ return Success;
+}
+
+static void i915_xvmc_destroy_context (ScrnInfoPtr pScrn,
+ XvMCContextPtr pContext)
+{
+ I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
+ int i;
+
+ for (i = 0; i < I915_XVMC_MAX_CONTEXTS; i++) {
+ if (pXvMC->contexts[i] == pContext->context_id) {
+ i915_unmap_xvmc_buffers(pScrn, pXvMC->ctxprivs[i]);
+ i915_free_xvmc_buffers(pScrn, pXvMC->ctxprivs[i]);
+ xfree(pXvMC->ctxprivs[i]);
+ pXvMC->ctxprivs[i] = 0;
+ pXvMC->ncontexts--;
+ pXvMC->contexts[i] = 0;
+ return;
+ }
+ }
+
+ return;
+}
+
+static void i915_xvmc_destroy_surface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
+ int i;
+
+ for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
+ if (pXvMC->surfaces[i] == pSurf->surface_id) {
+ drmRmMap(pI830->drmSubFD, pXvMC->sfprivs[i]->surface_handle);
+ i830_free_memory(pScrn, pXvMC->sfprivs[i]->surface);
+ xfree(pXvMC->sfprivs[i]);
+ pXvMC->nsurfaces--;
+ pXvMC->sfprivs[i] = 0;
+ pXvMC->surfaces[i] = 0;
+ return;
+ }
+ }
+
+ return;
+}
+
+static void i915_xvmc_destroy_subpict (ScrnInfoPtr pScrn,
+ XvMCSubpicturePtr pSubp)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
+ int i;
+
+ for (i = 0; i < I915_XVMC_MAX_SURFACES; i++) {
+ if (pXvMC->surfaces[i] == pSubp->subpicture_id) {
+ drmRmMap(pI830->drmSubFD, pXvMC->sfprivs[i]->surface_handle);
+ i830_free_memory(pScrn, pXvMC->sfprivs[i]->surface);
+ xfree(pXvMC->sfprivs[i]);
+ pXvMC->nsurfaces--;
+ pXvMC->sfprivs[i] = 0;
+ pXvMC->surfaces[i] = 0;
+ return;
+ }
+ }
+
+ return;
+}
+
+static int i915_xvmc_put_image(ScrnInfoPtr pScrn,
+ short src_x, short src_y,
+ short drw_x, short drw_y, short src_w,
+ short src_h, short drw_w, short drw_h,
+ int id, unsigned char *buf, short width,
+ 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;
+
+ if (pI830->XvMCEnabled) {
+ if (FOURCC_XVMC == id) {
+ switch (xvmc_cmd->command) {
+ case INTEL_XVMC_COMMAND_DISPLAY:
+ if ((xvmc_cmd->srfNo >= I915_XVMC_MAX_SURFACES) ||
+ !pXvMC->surfaces[xvmc_cmd->srfNo] ||
+ !pXvMC->sfprivs[xvmc_cmd->srfNo]) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[XvMC] i915 put image: Invalid parameters!\n");
+ return 1;
+ }
+
+ buf = pI830->FbBase +
+ pXvMC->sfprivs[xvmc_cmd->srfNo]->surface->offset;
+ id = xvmc_cmd->real_id;
+ pI830->IsXvMCSurface = 1;
+ break;
+ default:
+ return 0;
+ }
+ }
+ }
+
+ 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;
+}
+
+static Bool i915_xvmc_init(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt)
+{
+ I915XvMCPtr pXvMC;
+
+ pXvMC = (I915XvMCPtr)xcalloc(1, sizeof(I915XvMC));
+ if (!pXvMC) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "[XvMC] alloc driver private failed!\n");
+ return FALSE;
+ }
+ xvmc_driver->devPrivate = (void*)pXvMC;
+ if (!intel_xvmc_init_batch(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "[XvMC] fail to init batch buffer\n");
+ xfree(pXvMC);
+ return FALSE;
+ }
+ initI915XvMC(pXvMC);
+
+ /* set up wrappers */
+ pXvMC->savePutImage = XvAdapt->PutImage;
+ XvAdapt->PutImage = i915_xvmc_put_image;
+ return TRUE;
+}
+
+static void i915_xvmc_fini(ScrnInfoPtr pScrn)
+{
+ I915XvMCPtr pXvMC = (I915XvMCPtr)xvmc_driver->devPrivate;
+
+ cleanupI915XvMC(pXvMC);
+ intel_xvmc_fini_batch(pScrn);
+ xfree(xvmc_driver->devPrivate);
+}
+
+/* Fill in the device dependent adaptor record.
+ * This is named "Intel(R) Textured Video" because this code falls under the
+ * XV extenstion, the name must match or it won't be used.
+ *
+ * Surface and Subpicture - see above
+ * Function pointers to functions below
+ */
+static XF86MCAdaptorRec pAdapt =
+{
+ .name = "Intel(R) Textured Video",
+ .num_surfaces = ARRARY_SIZE(ppSI),
+ .surfaces = ppSI,
+#if 0
+ .num_subpictures = ARRARY_SIZE(i915_subpicture_list),
+ .subpictures = i915_subpicture_list,
+#endif
+ .num_subpictures = 0,
+ .subpictures = NULL,
+ .CreateContext = (xf86XvMCCreateContextProcPtr) i915_xvmc_create_context,
+ .DestroyContext = (xf86XvMCDestroyContextProcPtr) i915_xvmc_destroy_context,
+ .CreateSurface = (xf86XvMCCreateSurfaceProcPtr) i915_xvmc_create_surface,
+ .DestroySurface = (xf86XvMCDestroySurfaceProcPtr) i915_xvmc_destroy_surface,
+ .CreateSubpicture = (xf86XvMCCreateSubpictureProcPtr) i915_xvmc_create_subpict,
+ .DestroySubpicture = (xf86XvMCDestroySubpictureProcPtr) i915_xvmc_destroy_subpict,
+};
+
+/* new xvmc driver interface */
+struct intel_xvmc_driver i915_xvmc_driver = {
+ .name = "i915_xvmc",
+ .adaptor = &pAdapt,
+ .flag = XVMC_I915_MPEG2_MC,
+ .init = i915_xvmc_init,
+ .fini = i915_xvmc_fini,
+};
diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h
new file mode 100644
index 00000000..0141fb25
--- /dev/null
+++ b/src/i915_hwmc.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Xiang Haihao <haihao.xiang@intel.com>
+ *
+ */
+#ifndef _I915_HWMC_H
+#define _I915_HWMC_H
+
+#include "i830_hwmc.h"
+
+#define STRIDE(w) (((w) + 0x3ff) & ~0x3ff)
+#define SIZE_Y420(w, h) (h * STRIDE(w))
+#define SIZE_UV420(w, h) ((h >> 1) * STRIDE(w >> 1))
+#define SIZE_YUV420(w, h) (h * (STRIDE(w) + STRIDE(w >> 1)))
+#define SIZE_XX44(w, h) (h * STRIDE(w))
+
+#define I915_NUM_XVMC_ATTRIBUTES 0x02
+#define I915_XVMC_VALID 0x80000000
+
+typedef struct
+{
+ struct _intel_xvmc_common comm;
+ unsigned int ctxno; /* XvMC private context reference number */
+ struct hwmc_buffer sis;
+ struct hwmc_buffer ssb;
+ struct hwmc_buffer msb;
+ struct hwmc_buffer psp;
+ struct hwmc_buffer psc;
+ struct hwmc_buffer corrdata;/* Correction Data Buffer */
+ unsigned int sarea_priv_offset;
+ int deviceID;
+} I915XvMCCreateContextRec;
+
+typedef struct
+{
+ unsigned int srfno;
+ struct hwmc_buffer srf;
+} I915XvMCCreateSurfaceRec;
+
+#endif /* _I915_HWMC_H */
diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am
index b5c9db9a..cde41f98 100644
--- a/src/xvmc/Makefile.am
+++ b/src/xvmc/Makefile.am
@@ -1,5 +1,6 @@
-if DRI
-lib_LTLIBRARIES=libI810XvMC.la
+if XVMC
+lib_LTLIBRARIES=libI810XvMC.la libIntelXvMC.la
+
libI810XvMC_la_SOURCES = I810XvMC.c \
I810XvMC.h
@@ -7,4 +8,19 @@ libI810XvMC_la_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
-I$(top_srcdir)/src -DTRUE=1 -DFALSE=0
libI810XvMC_la_LDFLAGS = -version-number 1:0:0
libI810XvMC_la_LIBADD = @DRI_LIBS@
+
+libIntelXvMC_la_SOURCES = intel_xvmc.c \
+ intel_xvmc.h \
+ i915_xvmc.c \
+ i915_xvmc.h \
+ intel_batchbuffer.c \
+ intel_batchbuffer.h \
+ xf86dri.c \
+ xf86dri.h \
+ xf86dristr.h \
+ driDrawable.c \
+ driDrawable.h
+libIntelXvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0
+libIntelXvMC_la_LDFLAGS = -version-number 1:0:0
+libIntelXvMC_la_LIBADD = @DRI_LIBS@
endif
diff --git a/src/xvmc/driDrawable.c b/src/xvmc/driDrawable.c
new file mode 100644
index 00000000..83863347
--- /dev/null
+++ b/src/xvmc/driDrawable.c
@@ -0,0 +1,174 @@
+/*****************************************************************************
+ * driDrawable.c: Lean Version of DRI utilities.
+ *
+ * Copyright (c) 2005 Thomas Hellstrom. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include "xf86drm.h"
+#include "drm.h"
+#include "xf86dri.h"
+#include "drm_sarea.h"
+#include "driDrawable.h"
+
+static unsigned
+drawStamp(volatile drm_sarea_t * pSarea, int index)
+{
+ return pSarea->drawableTable[index].stamp;
+}
+
+int
+getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen,
+ Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext,
+ drmAddress sarea, Bool updateInfo, drawableInfo ** info,
+ unsigned long infoSize)
+{
+ drawableInfo *drawInfo;
+ void *res;
+ drm_drawable_t drmDraw = 0;
+ volatile drm_sarea_t *pSarea = (drm_sarea_t *) sarea;
+ drm_clip_rect_t *clipFront, *clipBack;
+
+ int ret;
+
+ if (drmHashLookup(drawHash, (unsigned long)draw, &res)) {
+
+ /*
+ * The drawable is unknown to us. Create it and put it in the
+ * hash table.
+ */
+
+ DRM_UNLOCK(drmFD, &pSarea->lock, drmContext);
+ if (!uniDRICreateDrawable(display, screen, draw, &drmDraw)) {
+ DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags);
+ return 1;
+ }
+ DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags);
+
+ drawInfo = (drawableInfo *) malloc(infoSize);
+ if (!drawInfo)
+ return 1;
+
+ drawInfo->drmDraw = drmDraw;
+ drawInfo->stamp = 0;
+ drawInfo->clipFront = 0;
+ drawInfo->clipBack = 0;
+
+ drmHashInsert(drawHash, (unsigned long)draw, drawInfo);
+
+ } else {
+ drawInfo = res;
+ }
+
+ drawInfo->touched = FALSE;
+ while (!drawInfo->clipFront
+ || drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) {
+
+ /*
+ * The drawable has been touched since we last got info about it.
+ * obtain new info from the X server.
+ */
+
+ drawInfo->touched = TRUE;
+
+ if (updateInfo || !drawInfo->clipFront) {
+ DRM_UNLOCK(drmFD, &pSarea->lock, drmContext);
+
+ ret = uniDRIGetDrawableInfo(display, screen, draw,
+ &drawInfo->index, &drawInfo->stamp, &drawInfo->x,
+ &drawInfo->y, &drawInfo->w, &drawInfo->h,
+ &drawInfo->numClipFront, &clipFront,
+ &drawInfo->backX, &drawInfo->backY,
+ &drawInfo->numClipBack, &clipBack);
+
+ DRM_LIGHT_LOCK(drmFD, &pSarea->lock, drmContext);
+
+ /*
+ * Error. Probably the drawable is destroyed. Return error and old values.
+ */
+
+ if (!ret) {
+ free(drawInfo);
+ drawInfo = NULL;
+ drmHashDelete(drawHash, (unsigned long)draw);
+
+ DRM_UNLOCK(drmFD, &pSarea->lock, drmContext);
+ uniDRIDestroyDrawable(display, screen, draw);
+ DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags);
+
+ return 1;
+ }
+
+ if (drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) {
+
+ /*
+ * The info is already outdated. Sigh. Have another go.
+ */
+
+ XFree(clipFront);
+ XFree(clipBack);
+ continue;
+ }
+
+ if (drawInfo->clipFront)
+ XFree(drawInfo->clipFront);
+ drawInfo->clipFront = clipFront;
+ if (drawInfo->clipBack)
+ XFree(drawInfo->clipBack);
+ drawInfo->clipBack = clipBack;
+ } else {
+ if (!drawInfo->clipFront)
+ drawInfo->clipFront = (drm_clip_rect_t *) ~ 0UL;
+ drawInfo->stamp = drawStamp(pSarea, drawInfo->index);
+ }
+ }
+ *info = drawInfo;
+ return 0;
+}
+
+void
+driDestroyHashContents(void *drawHash)
+{
+ unsigned long key;
+ void *content;
+ drawableInfo *drawInfo;
+
+ if (drmHashFirst(drawHash, &key, &content) < 1)
+ return;
+ drawInfo = (drawableInfo *) content;
+ if (drawInfo->clipBack)
+ XFree(drawInfo->clipBack);
+ if (drawInfo->clipFront)
+ XFree(drawInfo->clipFront);
+ free(drawInfo);
+ while (drmHashNext(drawHash, &key, &content) == 1) {
+ drawInfo = (drawableInfo *) content;
+ if (drawInfo->clipBack)
+ XFree(drawInfo->clipBack);
+ if (drawInfo->clipFront)
+ XFree(drawInfo->clipFront);
+ free(drawInfo);
+ }
+
+ return;
+}
diff --git a/src/xvmc/driDrawable.h b/src/xvmc/driDrawable.h
new file mode 100644
index 00000000..a758c7c7
--- /dev/null
+++ b/src/xvmc/driDrawable.h
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * driDrawable.h: Lean Version of DRI utilities.
+ *
+ * Copyright (c) 2005 Thomas Hellstrom. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DRIDRAWABLE_H
+#define _DRIDRAWABLE_H
+
+typedef struct _drawableInfo
+{
+ drm_drawable_t drmDraw;
+ unsigned stamp;
+ unsigned index;
+ drm_clip_rect_t *clipFront;
+ drm_clip_rect_t *clipBack;
+ int x;
+ int y;
+ int w;
+ int h;
+ int backX;
+ int backY;
+ int numClipFront;
+ int numClipBack;
+ Bool touched;
+} drawableInfo;
+
+/*
+ * Get updated info about the drawable "draw". The drawableInfo record returned is malloced
+ * and administrated internally. Never free it unless you know exactly what you are doing.
+ * The drm hash table "drawHash" needs to be initialized externally.
+ */
+
+extern int
+getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen,
+ Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext,
+ drmAddress sarea, Bool updateInfo, drawableInfo ** info,
+ unsigned long infoSize);
+
+/*
+ * Free all resources created by the above function. Typically done on exit.
+ */
+
+extern void driDestroyHashContents(void *drawHash);
+
+#endif
diff --git a/src/xvmc/i915_program.h b/src/xvmc/i915_program.h
new file mode 100644
index 00000000..82c920e0
--- /dev/null
+++ b/src/xvmc/i915_program.h
@@ -0,0 +1,276 @@
+#ifndef _I915_PROGRAM_H
+#define _I915_PROGRAM_H
+
+#define REG_TYPE_R 0 /* temporary regs, no need to
+ * dcl, must be written before
+ * read -- Preserved between
+ * phases.
+ */
+#define REG_TYPE_T 1 /* Interpolated values, must be
+ * dcl'ed before use.
+ *
+ * 0..7: texture coord,
+ * 8: diffuse spec,
+ * 9: specular color,
+ * 10: fog parameter in w.
+ */
+#define REG_TYPE_CONST 2 /* Restriction: only one const
+ * can be referenced per
+ * instruction, though it may be
+ * selected for multiple inputs.
+ * Constants not initialized
+ * default to zero.
+ */
+#define REG_TYPE_S 3 /* sampler */
+#define REG_TYPE_OC 4 /* output color (rgba) */
+#define REG_TYPE_OD 5 /* output depth (w), xyz are
+ * temporaries. If not written,
+ * interpolated depth is used?
+ */
+#define REG_TYPE_U 6 /* unpreserved temporaries */
+#define REG_TYPE_MASK 0x7
+#define REG_NR_MASK 0xf
+
+/* REG_TYPE_T:
+ */
+#define T_TEX0 0
+#define T_TEX1 1
+#define T_TEX2 2
+#define T_TEX3 3
+#define T_TEX4 4
+#define T_TEX5 5
+#define T_TEX6 6
+#define T_TEX7 7
+#define T_DIFFUSE 8
+#define T_SPECULAR 9
+#define T_FOG_W 10 /* interpolated fog is in W coord */
+
+/* Arithmetic instructions */
+
+/* .replicate_swizzle == selection and replication of a particular
+ * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww
+ */
+#define A0_NOP (0x0<<24) /* no operation */
+#define A0_ADD (0x1<<24) /* dst = src0 + src1 */
+#define A0_MOV (0x2<<24) /* dst = src0 */
+#define A0_MUL (0x3<<24) /* dst = src0 * src1 */
+#define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */
+#define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */
+#define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */
+#define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */
+#define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */
+#define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */
+#define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */
+#define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */
+#define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */
+#define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */
+#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */
+#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */
+#define A0_FLR (0x10<<24) /* dst = floor(src0) */
+#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */
+#define A0_TRC (0x12<<24) /* dst = int(src0) */
+#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */
+#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */
+#define A0_DEST_SATURATE (1<<22)
+#define A0_DEST_TYPE_SHIFT 19
+/* Allow: R, OC, OD, U */
+#define A0_DEST_NR_SHIFT 14
+/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
+#define A0_DEST_CHANNEL_X (1<<10)
+#define A0_DEST_CHANNEL_Y (2<<10)
+#define A0_DEST_CHANNEL_Z (4<<10)
+#define A0_DEST_CHANNEL_W (8<<10)
+#define A0_DEST_CHANNEL_ALL (0xf<<10)
+#define A0_DEST_CHANNEL_SHIFT 10
+#define A0_SRC0_TYPE_SHIFT 7
+#define A0_SRC0_NR_SHIFT 2
+
+#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y)
+#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z)
+
+#define SRC_X 0
+#define SRC_Y 1
+#define SRC_Z 2
+#define SRC_W 3
+#define SRC_ZERO 4
+#define SRC_ONE 5
+
+#define A1_SRC0_CHANNEL_X_NEGATE (1<<31)
+#define A1_SRC0_CHANNEL_X_SHIFT 28
+#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27)
+#define A1_SRC0_CHANNEL_Y_SHIFT 24
+#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23)
+#define A1_SRC0_CHANNEL_Z_SHIFT 20
+#define A1_SRC0_CHANNEL_W_NEGATE (1<<19)
+#define A1_SRC0_CHANNEL_W_SHIFT 16
+#define A1_SRC1_TYPE_SHIFT 13
+#define A1_SRC1_NR_SHIFT 8
+#define A1_SRC1_CHANNEL_X_NEGATE (1<<7)
+#define A1_SRC1_CHANNEL_X_SHIFT 4
+#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3)
+#define A1_SRC1_CHANNEL_Y_SHIFT 0
+
+#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31)
+#define A2_SRC1_CHANNEL_Z_SHIFT 28
+#define A2_SRC1_CHANNEL_W_NEGATE (1<<27)
+#define A2_SRC1_CHANNEL_W_SHIFT 24
+#define A2_SRC2_TYPE_SHIFT 21
+#define A2_SRC2_NR_SHIFT 16
+#define A2_SRC2_CHANNEL_X_NEGATE (1<<15)
+#define A2_SRC2_CHANNEL_X_SHIFT 12
+#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11)
+#define A2_SRC2_CHANNEL_Y_SHIFT 8
+#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7)
+#define A2_SRC2_CHANNEL_Z_SHIFT 4
+#define A2_SRC2_CHANNEL_W_NEGATE (1<<3)
+#define A2_SRC2_CHANNEL_W_SHIFT 0
+
+/* Declaration instructions */
+#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib)
+ * register or an s (sampler)
+ * register. */
+#define D0_SAMPLE_TYPE_SHIFT 22
+#define D0_SAMPLE_TYPE_2D (0x0<<22)
+#define D0_SAMPLE_TYPE_CUBE (0x1<<22)
+#define D0_SAMPLE_TYPE_VOLUME (0x2<<22)
+#define D0_SAMPLE_TYPE_MASK (0x3<<22)
+
+#define D0_TYPE_SHIFT 19
+/* Allow: T, S */
+#define D0_NR_SHIFT 14
+/* Allow T: 0..10, S: 0..15 */
+#define D0_CHANNEL_X (1<<10)
+#define D0_CHANNEL_Y (2<<10)
+#define D0_CHANNEL_Z (4<<10)
+#define D0_CHANNEL_W (8<<10)
+#define D0_CHANNEL_ALL (0xf<<10)
+#define D0_CHANNEL_NONE (0<<10)
+
+#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y)
+#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z)
+
+/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse
+ * or specular declarations.
+ *
+ * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw)
+ *
+ * Must be zero for S (sampler) dcls
+ */
+#define D1_MBZ 0
+#define D2_MBZ 0
+
+/* Texture instructions */
+#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared
+ * sampler and address, and output
+ * filtered texel data to destination
+ * register */
+#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a
+ * perspective divide of the texture
+ * coordinate .xyz values by .w before
+ * sampling. */
+#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the
+ * computed LOD by w. Only S4.6 two's
+ * comp is used. This implies that a
+ * float to fixed conversion is
+ * done. */
+#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling
+ * operation. Simply kills the pixel
+ * if any channel of the address
+ * register is < 0.0. */
+#define T0_DEST_TYPE_SHIFT 19
+/* Allow: R, OC, OD, U */
+/* Note: U (unpreserved) regs do not retain their values between
+ * phases (cannot be used for feedback)
+ *
+ * Note: oC and OD registers can only be used as the destination of a
+ * texture instruction once per phase (this is an implementation
+ * restriction).
+ */
+#define T0_DEST_NR_SHIFT 14
+/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */
+#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */
+#define T0_SAMPLER_NR_MASK (0xf<<0)
+
+#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */
+/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */
+#define T1_ADDRESS_REG_NR_SHIFT 17
+#define T2_MBZ 0
+
+
+/* Having zero and one in here makes the definition of swizzle a lot
+ * easier.
+ */
+#define UREG_TYPE_SHIFT 29
+#define UREG_NR_SHIFT 24
+#define UREG_CHANNEL_X_NEGATE_SHIFT 23
+#define UREG_CHANNEL_X_SHIFT 20
+#define UREG_CHANNEL_Y_NEGATE_SHIFT 19
+#define UREG_CHANNEL_Y_SHIFT 16
+#define UREG_CHANNEL_Z_NEGATE_SHIFT 15
+#define UREG_CHANNEL_Z_SHIFT 12
+#define UREG_CHANNEL_W_NEGATE_SHIFT 11
+#define UREG_CHANNEL_W_SHIFT 8
+#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5
+#define UREG_CHANNEL_ZERO_SHIFT 4
+#define UREG_CHANNEL_ONE_NEGATE_MBZ 1
+#define UREG_CHANNEL_ONE_SHIFT 0
+
+#define UREG_BAD 0xffffffff /* not a valid ureg */
+
+#define X SRC_X
+#define Y SRC_Y
+#define Z SRC_Z
+#define W SRC_W
+#define ZERO SRC_ZERO
+#define ONE SRC_ONE
+
+/* Construct a ureg:
+ */
+#define UREG(type, nr) (((type) << UREG_TYPE_SHIFT) | \
+ ((nr) << UREG_NR_SHIFT) | \
+ (X << UREG_CHANNEL_X_SHIFT) | \
+ (Y << UREG_CHANNEL_Y_SHIFT) | \
+ (Z << UREG_CHANNEL_Z_SHIFT) | \
+ (W << UREG_CHANNEL_W_SHIFT) | \
+ (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \
+ (ONE << UREG_CHANNEL_ONE_SHIFT))
+
+#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20))
+#define CHANNEL_SRC( src, channel ) (src>>(channel*4))
+
+#define GET_UREG_TYPE(reg) (((reg) >> UREG_TYPE_SHIFT) & REG_TYPE_MASK)
+#define GET_UREG_NR(reg) (((reg) >> UREG_NR_SHIFT) & REG_NR_MASK)
+
+#define UREG_XYZW_CHANNEL_MASK 0x00ffff00
+
+#define A0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
+#define D0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
+#define T0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT)
+#define A0_SRC0(reg) (((reg) & UREG_MASK) >> UREG_A0_SRC0_SHIFT_LEFT)
+#define A1_SRC0(reg) (((reg) & UREG_MASK) << UREG_A1_SRC0_SHIFT_RIGHT)
+#define A1_SRC1(reg) (((reg) & UREG_MASK) >> UREG_A1_SRC1_SHIFT_LEFT)
+#define A2_SRC1(reg) (((reg) & UREG_MASK) << UREG_A2_SRC1_SHIFT_RIGHT)
+#define A2_SRC2(reg) (((reg) & UREG_MASK) >> UREG_A2_SRC2_SHIFT_LEFT)
+
+/* These are special, and don't have swizzle/negate bits.
+ */
+#define T0_SAMPLER( reg ) (GET_UREG_NR(reg) << T0_SAMPLER_NR_SHIFT)
+#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg) << T1_ADDRESS_REG_NR_SHIFT) | \
+ (GET_UREG_TYPE(reg) << T1_ADDRESS_REG_TYPE_SHIFT))
+
+
+/* Macros for translating UREG's into the various register fields used
+ * by the I915 programmable unit.
+ */
+#define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
+#define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
+#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
+#define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
+#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
+#define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
+
+#define UREG_MASK 0xffffff00
+#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
+ (REG_NR_MASK << UREG_NR_SHIFT))
+
+#endif
diff --git a/src/xvmc/i915_structs.h b/src/xvmc/i915_structs.h
new file mode 100644
index 00000000..a25d7349
--- /dev/null
+++ b/src/xvmc/i915_structs.h
@@ -0,0 +1,973 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Xiang Haihao <haihao.xiang@intel.com>
+ *
+ */
+
+#ifndef _I915_STRUCTS_H
+#define _I915_STRUCTS_H
+
+/* MI_INSTRUCTION */
+#define CMD_MI 0x00
+
+#define OPC_MI_FLUSH (0x04)
+
+struct i915_mi_flush
+{
+ struct {
+ unsigned map_cache_invalidate : 1;
+ unsigned pad0 : 1;
+ unsigned render_cache_flush_inhibit : 1;
+ unsigned scene_count : 1;
+ unsigned end_scene : 1;
+ unsigned pad1 : 18;
+ unsigned opcode : 6;
+ unsigned type : 3;
+ } dw0;
+};
+
+/* BLT */
+#define CMD_2D 0x02
+#define OPC_COLOR_BLT (0x40)
+
+struct i915_color_blt
+{
+ struct {
+ unsigned length : 5;
+ unsigned pad0 : 15;
+ unsigned bpp_mask : 2;
+ unsigned opcode : 7;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned pitch : 16;
+ unsigned rop : 8;
+ unsigned color_depth : 2;
+ unsigned pad0 : 6;
+ } dw1;
+
+ struct {
+ unsigned width : 16;
+ unsigned height : 16;
+ } dw2;
+
+ struct {
+ unsigned address;
+ } dw3;
+
+ struct {
+ unsigned pattern;
+ } dw4;
+};
+
+/* 3D_INSTRUCTION */
+#define CMD_3D 0x03
+
+#define OPC_3DMPEG_MACROBLOCK_IPICTURE (0x01 + (0x1e << 5))
+#define OPC_3DMPEG_SET_ORIGIN (0x10 + (0x1e << 5))
+#define OPC_3DMPEG_MACROBLOCK (0x11 + (0x1e << 5))
+#define OPC_3DMPEG_SLICE (0x12 + (0x1e << 5))
+#define OPC_3DMPEG_QM_PALETTE_LOAD (0x13 + (0x1e << 5))
+
+#define OPC_3DSTATE_SCISSOR_ENABLE (0x10 + (0x1c << 5))
+
+#define OPC_3DSTATE_MAP_STATE (0x00 + (0x1d << 8))
+#define OPC_3DSTATE_SAMPLER_STATE (0x01 + (0x1d << 8))
+#define OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1 (0x04 + (0x1d << 8))
+#define OPC_3DSTATE_PIXEL_SHADER_PROGRAM (0x05 + (0x1d << 8))
+#define OPC_3DSTATE_PIXEL_SHADER_CONSTANTS (0x06 + (0x1d << 8))
+#define OPC_3DSTATE_LOAD_INDIRECT (0x07 + (0x1d << 8))
+
+#define OPC_3DSTATE_MODES_5 (0x0c)
+#define OPC_3DSTATE_COORD_SET_BINDINGS (0x16)
+#define OPC_3DPRIMITIVE (0x1f)
+
+#define OPC_3DSTATE_DRAWING_RECTANGLE (0x80 + (0x1d << 8))
+#define OPC_3DSTATE_SCISSOR_RECTANGLE (0x81 + (0x1d << 8))
+#define OPC_3DSTATE_DEST_BUFFER_VARIABLES (0x85 + (0x1d << 8))
+#define OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG (0x87 + (0x1d << 8))
+#define OPC_3DSTATE_BUFFER_INFO (0x8e + (0x1d << 8))
+
+/*
+ * 3DMPEG instructions
+ */
+struct i915_3dmpeg_macroblock_header
+{
+ struct {
+ unsigned length : 19;
+ unsigned opcode : 10;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned mb_intra : 1;
+ unsigned forward : 1;
+ unsigned backward : 1;
+ unsigned h263_4mv : 1;
+ unsigned pad0 : 1;
+ unsigned dct_type : 1;
+ unsigned pad1 : 2;
+ unsigned motion_type : 2;
+ unsigned pad2 : 2;
+ unsigned vertical_field_select : 4;
+ unsigned coded_block_pattern : 6;
+ unsigned pad3 : 2;
+ unsigned skipped_macroblocks : 7;
+ unsigned pad4 : 1;
+ } dw1;
+};
+
+struct i915_3dmpeg_macroblock_0mv
+{
+ struct i915_3dmpeg_macroblock_header header;
+};
+
+struct i915_3dmpeg_macroblock_1fbmv
+{
+ struct i915_3dmpeg_macroblock_header header;
+ unsigned dw2;
+ unsigned dw3;
+};
+struct i915_3dmpeg_macroblock_2fbmv
+{
+ struct i915_3dmpeg_macroblock_header header;
+ unsigned dw2;
+ unsigned dw3;
+ unsigned dw4;
+ unsigned dw5;
+};
+
+struct i915_3dmpeg_macroblock_5fmv
+{
+ struct i915_3dmpeg_macroblock_header header;
+ unsigned dw2;
+ unsigned dw3;
+ unsigned dw4;
+ unsigned dw5;
+ unsigned dw6;
+};
+
+struct i915_3dmpeg_macroblock_ipicture
+{
+ struct {
+ unsigned pad0 : 5;
+ unsigned dct_type : 1;
+ unsigned pad1 : 13;
+ unsigned opcode : 10;
+ unsigned type : 3;
+ } dw0;
+};
+
+struct i915_3dmpeg_set_origin
+{
+ struct {
+ unsigned length : 19;
+ unsigned opcode : 10;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned v_origin : 7;
+ unsigned pad0 : 1;
+ unsigned h_origin : 7;
+ unsigned pad1 : 17;
+ } dw1;
+};
+
+struct i915_3dmpeg_slice
+{
+ struct {
+ unsigned length : 19;
+ unsigned opcode : 10;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned fst_mb_bit_off : 3;
+ unsigned pad0 : 5;
+ unsigned mb_count : 7;
+ unsigned pad1 : 1;
+ unsigned v_position : 7;
+ unsigned pad2 : 1;
+ unsigned h_position : 7;
+ unsigned pad3 : 1;
+ } dw1;
+
+ struct {
+ unsigned length_minus_one : 17;
+ unsigned pad0 : 7;
+ unsigned qt_scale_code : 5;
+ unsigned pad1 : 3;
+ } dw2;
+};
+
+struct i915_3dmpeg_qm_palette_load
+{
+ struct {
+ unsigned length : 4;
+ unsigned pad0 : 15;
+ unsigned opcode : 10;
+ unsigned type : 3;
+ } dw0;
+
+ unsigned quantmatrix[16];
+};
+
+
+/*
+ * 3DSTATE instruction
+ */
+#define BUFFERID_COLOR_BACK 3
+#define BUFFERID_COLOR_AUX 4
+#define BUFFERID_MC_INTRA_CORR 5
+#define BUFFERID_DEPTH 7
+
+#define TILEWALK_XMAJOR 0
+#define TILEWALK_YMAJOR 1
+
+struct i915_3dstate_buffer_info
+{
+ struct {
+ unsigned length : 16;
+ unsigned opcode : 13;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned pad0 : 2;
+ unsigned pitch : 12;
+ unsigned pad1 : 7;
+ unsigned walk : 1;
+ unsigned tiled_surface : 1;
+ unsigned fence_regs : 1;
+ unsigned buffer_id : 4;
+ unsigned aux_id : 1;
+ unsigned pad2 : 3;
+ } dw1;
+
+ struct {
+ unsigned pad0 : 2;
+ unsigned base_address : 27;
+ unsigned pad1 : 3;
+ } dw2;
+};
+
+#define COLORBUFFER_8BIT 0x00
+#define COLORBUFFER_X1R5G5B5 0x01
+#define COLORBUFFER_R5G6B5 0x02
+#define COLORBUFFER_A8R8G8B8 0x03
+#define COLORBUFFER_YCRCB_SWAP 0x04
+#define COLORBUFFER_YCRCB_NORMAL 0x05
+#define COLORBUFFER_YCRCB_SWAPUV 0x06
+#define COLORBUFFER_YCRCB_SWAPUVY 0x07
+#define COLORBUFFER_A4R4G4B4 0x08
+#define COLORBUFFER_A1R5G5B5 0x09
+#define COLORBUFFER_A2R10G10B10 0x0a
+
+
+struct i915_3dstate_dest_buffer_variables
+{
+ struct {
+ unsigned length : 16;
+ unsigned opcode : 13;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned v_ls_offset : 1;
+ unsigned v_ls : 1;
+ unsigned depth_fmt : 2;
+ unsigned pad0 : 4;
+ unsigned color_fmt : 4;
+ unsigned yuv422_select : 3;
+ unsigned pad1 : 1;
+ unsigned dest_v_bias : 4;
+ unsigned dest_h_bias : 4;
+ unsigned dither_enhancement : 1;
+ unsigned linear_gamma : 1;
+ unsigned dither_pattern : 2;
+ unsigned lod_preclamp : 1;
+ unsigned edt_zone : 1; /* early depth test in zone rendering */
+ unsigned texture_default_color : 1;
+ unsigned edt_classic : 1; /* early depth test in classic mode */
+ } dw1;
+};
+
+#define MPEG_DECODE_MC 0
+#define MPEG_DECODE_VLD_IDCT_MC 1
+
+#define MPEG_I_PICTURE 1
+#define MPEG_P_PICTURE 2
+#define MPEG_B_PICTURE 3
+
+#define MC_SUB_1H 0
+#define MC_SUB_2H 1
+#define MC_SUB_4H 2
+
+#define MC_SUB_1V 0
+#define MC_SUB_2V 1
+
+struct i915_3dstate_dest_buffer_variables_mpeg
+{
+ struct {
+ unsigned length : 16;
+ unsigned opcode : 13;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned picture_width : 7;
+ unsigned pad0 : 1;
+ unsigned v_subsample_factor : 2;
+ unsigned h_subsample_factor : 2;
+ unsigned tff : 1;
+ unsigned mismatch : 1;
+ unsigned pad1 : 1;
+ unsigned intra8 : 1;
+ unsigned abort_on_error : 8;
+ unsigned pad2 : 4;
+ unsigned bidir_avrg_control : 1;
+ unsigned rcontrol : 1;
+ unsigned decode_mode : 2;
+ } dw1;
+
+ struct {
+ unsigned pad0 : 1;
+ unsigned picture_coding_type : 2;
+ unsigned pad1 : 2;
+ unsigned scan_order : 1;
+ unsigned pad2 : 2;
+ unsigned q_scale_type : 1;
+ unsigned concealment : 1;
+ unsigned fpf_dct : 1;
+ unsigned pad3 : 2;
+ unsigned intra_dc : 2;
+ unsigned intra_vlc : 1;
+ unsigned f_code00 : 4;
+ unsigned f_code01 : 4;
+ unsigned f_code10 : 4;
+ unsigned f_code11 : 4;
+ } dw2;
+};
+
+#define MAP_MAP0 0x0001
+#define MAP_MAP1 0x0002
+#define MAP_MAP2 0x0004
+#define MAP_MAP3 0x0008
+#define MAP_MAP4 0x0010
+#define MAP_MAP5 0x0020
+#define MAP_MAP6 0x0040
+#define MAP_MAP7 0x0080
+#define MAP_MAP8 0x0100
+#define MAP_MAP9 0x0200
+#define MAP_MAP10 0x0400
+#define MAP_MAP11 0x0800
+#define MAP_MAP12 0x1000
+#define MAP_MAP13 0x2000
+#define MAP_MAP14 0x4000
+#define MAP_MAP15 0x8000
+
+struct texture_map
+{
+ struct {
+ unsigned v_ls_offset : 1;
+ unsigned v_ls : 1;
+ unsigned base_address : 27;
+ unsigned pad0 : 2;
+ unsigned untrusted : 1;
+ } tm0;
+
+ struct {
+ unsigned tile_walk : 1;
+ unsigned tiled_surface : 1;
+ unsigned utilize_fence_regs : 1;
+ unsigned texel_fmt : 4;
+ unsigned surface_fmt : 3;
+ unsigned width : 11;
+ unsigned height : 11;
+ } tm1;
+
+ struct {
+ unsigned depth : 8;
+ unsigned mipmap_layout : 1;
+ unsigned max_lod : 6;
+ unsigned cube_face : 6;
+ unsigned pitch : 11;
+ } tm2;
+};
+
+struct i915_3dstate_map_state
+{
+ struct {
+ unsigned length : 6;
+ unsigned pad0 : 9;
+ unsigned retain : 1;
+ unsigned opcode : 13;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned map_mask : 16;
+ unsigned pad0 : 16;
+ } dw1;
+// struct texture_map *tms;
+};
+
+#define SAMPLER_SAMPLER0 0x0001
+#define SAMPLER_SAMPLER1 0x0002
+#define SAMPLER_SAMPLER2 0x0004
+#define SAMPLER_SAMPLER3 0x0008
+#define SAMPLER_SAMPLER4 0x0010
+#define SAMPLER_SAMPLER5 0x0020
+#define SAMPLER_SAMPLER6 0x0040
+#define SAMPLER_SAMPLER7 0x0080
+#define SAMPLER_SAMPLER8 0x0100
+#define SAMPLER_SAMPLER9 0x0200
+#define SAMPLER_SAMPLER10 0x0400
+#define SAMPLER_SAMPLER11 0x0800
+#define SAMPLER_SAMPLER12 0x1000
+#define SAMPLER_SAMPLER13 0x2000
+#define SAMPLER_SAMPLER14 0x4000
+#define SAMPLER_SAMPLER15 0x8000
+
+#define MIPFILTER_NONE 0
+#define MIPFILTER_NEAREST 1
+#define MIPFILTER_LINEAR 3
+
+#define MAPFILTER_NEAREST 0
+#define MAPFILTER_LINEAR 1
+#define MAPFILTER_ANISOTROPIC 2
+#define MAPFILTER_4X4_1 3
+#define MAPFILTER_4X4_2 4
+#define MAPFILTER_4X4_FLAT 5
+#define MAPFILTER_MONO 6
+
+#define ANISORATIO_2 0
+#define ANISORATIO_4 1
+
+#define PREFILTEROP_ALWAYS 0
+#define PREFILTEROP_NEVER 1
+#define PREFILTEROP_LESS 2
+#define PREFILTEROP_EQUAL 3
+#define PREFILTEROP_LEQUAL 4
+#define PREFILTEROP_GREATER 5
+#define PREFILTEROP_NOTEQUAL 6
+#define PREFILTEROP_GEQUAL 7
+
+#define TEXCOORDMODE_WRAP 0
+#define TEXCOORDMODE_MIRROR 1
+#define TEXCOORDMODE_CLAMP 2
+#define TEXCOORDMODE_CUBE 3
+#define TEXCOORDMODE_CLAMP_BORDER 4
+#define TEXCOORDMODE_MIRROR_ONCE 5
+
+struct texture_sampler
+{
+ struct {
+ unsigned shadow_function : 3;
+ unsigned max_anisotropy : 1;
+ unsigned shadow_enable : 1;
+ unsigned lod_bias : 9;
+ unsigned min_filter : 3;
+ unsigned mag_filter : 3;
+ unsigned mip_filter : 2;
+ unsigned base_level : 5;
+ unsigned chromakey_index : 2;
+ unsigned color_conversion : 1;
+ unsigned planar2packet : 1;
+ unsigned reverse_gamma : 1;
+ } ts0;
+
+ struct {
+ unsigned east_deinterlacer : 1;
+ unsigned map_index : 4;
+ unsigned normalized_coor : 1;
+ unsigned tcz_control : 3;
+ unsigned tcy_control : 3;
+ unsigned tcx_control : 3;
+ unsigned chromakey_enable : 1;
+ unsigned keyed_texture_filter : 1;
+ unsigned kill_pixel : 1;
+ unsigned pad0 : 6;
+ unsigned min_lod : 8;
+ } ts1;
+
+ struct {
+ unsigned default_color;
+ } ts2;
+};
+
+struct i915_3dstate_sampler_state
+{
+ struct {
+ unsigned length : 6;
+ unsigned pad0 : 10;
+ unsigned opcode : 13;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned sampler_masker : 16;
+ unsigned pad0 : 16;
+ } dw1;
+};
+
+struct arithmetic_inst
+{
+ struct {
+ unsigned pad0 : 2;
+ unsigned src0_reg : 5;
+ unsigned src0_reg_t : 3;
+ unsigned dest_channel_mask : 4;
+ unsigned dest_reg : 4;
+ unsigned pad1 : 1;
+ unsigned dest_reg_t: 3;
+ unsigned dest_saturate : 1;
+ unsigned pad2 : 1;
+ unsigned opcode : 5;
+ unsigned pad3 : 3;
+ } dw0;
+
+ struct {
+ unsigned src1_y_select : 3;
+ unsigned src1_y_negate : 1;
+ unsigned src1_x_select : 3;
+ unsigned src1_x_negate : 1;
+ unsigned src1_reg : 5;
+ unsigned src1_reg_t : 3;
+ unsigned src0_w_select : 3;
+ unsigned src0_w_negate : 1;
+ unsigned src0_z_select : 3;
+ unsigned src0_z_negate : 1;
+ unsigned src0_y_select : 3;
+ unsigned src0_y_negate : 1;
+ unsigned src0_x_select : 3;
+ unsigned src0_x_negate : 1;
+ } dw1;
+
+ struct {
+ unsigned src2_w_select : 3;
+ unsigned src2_w_negate : 1;
+ unsigned src2_z_select : 3;
+ unsigned src2_z_negate : 1;
+ unsigned src2_y_select : 3;
+ unsigned src2_y_negate : 1;
+ unsigned src2_x_select : 3;
+ unsigned src2_x_negate : 1;
+ unsigned src2_reg : 5;
+ unsigned src2_reg_t : 3;
+ unsigned src1_w_select : 3;
+ unsigned src1_w_negate : 1;
+ unsigned src1_z_select : 3;
+ unsigned src1_z_negate : 1;
+ } dw2;
+};
+
+struct texture_inst
+{
+ struct {
+ unsigned sampler_reg : 4;
+ unsigned pad0 : 10;
+ unsigned dest_reg : 4;
+ unsigned pad1 : 1;
+ unsigned dest_reg_t : 3;
+ unsigned pad2 : 2;
+ unsigned opcode : 5;
+ unsigned pad3 : 3;
+ } dw0;
+
+ struct {
+ unsigned pad0 : 16;
+ unsigned address_reg : 5;
+ unsigned pad1 : 3;
+ unsigned address_reg_t : 3;
+ unsigned pad2 : 5;
+ } dw1;
+
+ struct {
+ unsigned pad0;
+ } dw2;
+};
+
+struct declaration_inst
+{
+ struct {
+ unsigned pad0 : 10;
+ unsigned decl_channel_mask : 4;
+ unsigned decl_reg : 4;
+ unsigned pad1 : 1;
+ unsigned decl_reg_t : 2;
+ unsigned pad2 : 1;
+ unsigned sampler_type : 2;
+ unsigned opcode : 5;
+ unsigned pad3 : 3;
+ } dw0;
+
+ struct {
+ unsigned pad0;
+ } dw1;
+
+ struct {
+ unsigned pad0;
+ } dw2;
+};
+
+union shader_inst
+{
+ struct arithmetic_inst a;
+ struct texture_inst t;
+ struct declaration_inst d;
+};
+
+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;
+};
+
+#define REG_CR0 0x00000001
+#define REG_CR1 0x00000002
+#define REG_CR2 0x00000004
+#define REG_CR3 0x00000008
+#define REG_CR4 0x00000010
+#define REG_CR5 0x00000020
+#define REG_CR6 0x00000040
+#define REG_CR7 0x00000080
+#define REG_CR8 0x00000100
+#define REG_CR9 0x00000200
+#define REG_CR10 0x00000400
+#define REG_CR11 0x00000800
+#define REG_CR12 0x00001000
+#define REG_CR13 0x00002000
+#define REG_CR14 0x00004000
+#define REG_CR15 0x00008000
+#define REG_CR16 0x00010000
+#define REG_CR17 0x00020000
+#define REG_CR18 0x00040000
+#define REG_CR19 0x00080000
+#define REG_CR20 0x00100000
+#define REG_CR21 0x00200000
+#define REG_CR22 0x00400000
+#define REG_CR23 0x00800000
+#define REG_CR24 0x01000000
+#define REG_CR25 0x02000000
+#define REG_CR26 0x04000000
+#define REG_CR27 0x08000000
+#define REG_CR28 0x10000000
+#define REG_CR29 0x20000000
+#define REG_CR30 0x40000000
+#define REG_CR31 0x80000000
+
+struct shader_constant
+{
+ float x;
+ float y;
+ float z;
+ float w;
+};
+
+struct i915_3dstate_pixel_shader_constants
+{
+ struct {
+ unsigned length : 8;
+ unsigned pad0 : 8;
+ unsigned opcode : 13;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned reg_mask;
+ } dw1;
+ // struct shader_constant *consts;
+};
+
+#define BLOCK_SIS 0x01
+#define BLOCK_DIS 0x02
+#define BLOCK_SSB 0x04
+#define BLOCK_MSB 0x08
+#define BLOCK_PSP 0x10
+#define BLOCK_PSC 0x20
+
+typedef struct _state_ddword
+{
+ struct {
+ unsigned valid : 1;
+ unsigned force : 1;
+ unsigned buffer_address : 30;
+ } dw0;
+
+ struct {
+ unsigned length : 9;
+ unsigned pad0 : 23;
+ } dw1;
+} sis_state, ssb_state, msb_state, psp_state, psc_state;
+
+typedef struct _state_dword
+{
+ struct {
+ unsigned valid : 1;
+ unsigned reset : 1;
+ unsigned buffer_address : 30;
+ } dw0;
+} dis_state;
+
+struct i915_3dstate_load_indirect
+{
+ struct {
+ unsigned length : 8;
+ unsigned block_mask : 6;
+ unsigned mem_select : 1;
+ unsigned pad0 : 1;
+ unsigned opcode : 13;
+ unsigned type : 3;
+ } dw0;
+};
+
+#define TEXCOORDFMT_2FP 0x00
+#define TEXCOORDFMT_3FP 0x01
+#define TEXCOORDFMT_4FP 0x02
+#define TEXCOORDFMT_1FP 0x03
+#define TEXCOORDFMT_2FP_16 0x04
+#define TEXCOORDFMT_4FP_16 0x05
+#define TEXCOORDFMT_NOT_PRESENT 0x0f
+struct s2_dword
+{
+ unsigned set0_texcoord_fmt : 4;
+ unsigned set1_texcoord_fmt : 4;
+ unsigned set2_texcoord_fmt : 4;
+ unsigned set3_texcoord_fmt : 4;
+ unsigned set4_texcoord_fmt : 4;
+ unsigned set5_texcoord_fmt : 4;
+ unsigned set6_texcoord_fmt : 4;
+ unsigned set7_texcoord_fmt : 4;
+};
+
+struct s3_dword
+{
+ unsigned set0_pcd : 1;
+ unsigned set0_ws_tcz : 1;
+ unsigned set0_ws_tcy : 1;
+ unsigned set0_ws_tcx : 1;
+ unsigned set1_pcd : 1;
+ unsigned set1_ws_tcz : 1;
+ unsigned set1_ws_tcy : 1;
+ unsigned set1_ws_tcx : 1;
+ unsigned set2_pcd : 1;
+ unsigned set2_ws_tcz : 1;
+ unsigned set2_ws_tcy : 1;
+ unsigned set2_ws_tcx : 1;
+ unsigned set3_pcd : 1;
+ unsigned set3_ws_tcz : 1;
+ unsigned set3_ws_tcy : 1;
+ unsigned set3_ws_tcx : 1;
+ unsigned set4_pcd : 1;
+ unsigned set4_ws_tcz : 1;
+ unsigned set4_ws_tcy : 1;
+ unsigned set4_ws_tcx : 1;
+ unsigned set5_pcd : 1;
+ unsigned set5_ws_tcz : 1;
+ unsigned set5_ws_tcy : 1;
+ unsigned set5_ws_tcx : 1;
+ unsigned set6_pcd : 1;
+ unsigned set6_ws_tcz : 1;
+ unsigned set6_ws_tcy : 1;
+ unsigned set6_ws_tcx : 1;
+ unsigned set7_pcd : 1;
+ unsigned set7_ws_tcz : 1;
+ unsigned set7_ws_tcy : 1;
+ unsigned set7_ws_tcx : 1;
+};
+
+#define VERTEXHAS_XYZ 1
+#define VERTEXHAS_XYZW 2
+#define VERTEXHAS_XY 3
+#define VERTEXHAS_XYW 4
+
+#define CULLMODE_BOTH 0
+#define CULLMODE_NONE 1
+#define CULLMODE_CW 2
+#define CULLMODE_CCW 3
+
+#define SHADEMODE_LINEAR 0
+#define SHADEMODE_FLAT 1
+struct s4_dword
+{
+ unsigned anti_aliasing_enable : 1;
+ unsigned sprite_point_enable : 1;
+ unsigned fog_parameter_present : 1;
+ unsigned local_depth_offset_enable : 1;
+ unsigned force_specular_diffuse_color : 1;
+ unsigned force_default_diffuse_color : 1;
+ unsigned position_mask : 3;
+ unsigned local_depth_offset_present : 1;
+ unsigned diffuse_color_presetn : 1;
+ unsigned specular_color_fog_factor_present : 1;
+ unsigned point_width_present : 1;
+ unsigned cull_mode : 2;
+ unsigned color_shade_mode : 1;
+ unsigned specular_shade_mode : 1;
+ unsigned fog_shade_mode : 1;
+ unsigned alpha_shade_mode : 1;
+ unsigned line_width : 4;
+ unsigned point_width : 9;
+};
+
+struct s5_dword
+{
+ unsigned logic_op_enable : 1;
+ unsigned color_dither_enable : 1;
+ unsigned stencil_test_enable : 1;
+ unsigned stencil_buffer_write_enable : 1;
+ unsigned stencil_pass_depth_pass_op : 3;
+ unsigned stencil_pass_depth_fail_op : 3;
+ unsigned stencil_fail_op : 3;
+ unsigned stencil_test_function : 3;
+ unsigned stencil_reference_value : 8;
+ unsigned fog_enable : 1;
+ unsigned global_depth_offset_enable : 1;
+ unsigned last_pixel_enable : 1;
+ unsigned force_default_point_width : 1;
+ unsigned color_buffer_component_write_disable : 4;
+};
+
+struct s6_dword
+{
+ unsigned triangle_pv : 2;
+ unsigned color_buffer_write : 1;
+ unsigned depth_buffer_write : 1;
+ unsigned dest_blend_factor : 4;
+ unsigned src_blend_factor : 4;
+ unsigned color_blend_function : 3;
+ unsigned color_buffer_blend : 1;
+ unsigned depth_test_function : 3;
+ unsigned depth_test_enable : 1;
+ unsigned alpha_reference_value : 8;
+ unsigned alpha_test_function : 3;
+ unsigned alpha_test_enable : 1;
+
+};
+
+struct s7_dword
+{
+ unsigned global_depth_offset_const;
+};
+
+struct i915_3dstate_load_state_immediate_1
+{
+ struct {
+ unsigned length : 4;
+ unsigned load_s0 : 1;
+ unsigned load_s1 : 1;
+ unsigned load_s2 : 1;
+ unsigned load_s3 : 1;
+ unsigned load_s4 : 1;
+ unsigned load_s5 : 1;
+ unsigned load_s6 : 1;
+ unsigned load_s7 : 1;
+ unsigned pad0 : 4;
+ unsigned opcode : 13;
+ unsigned type : 3;
+ } dw0;
+};
+
+struct i915_3dstate_scissor_rectangle
+{
+ struct {
+ unsigned length : 16;
+ unsigned opcode : 13;
+ unsigned type : 3;
+ } dw0;
+
+ struct {
+ unsigned min_x : 16;
+ unsigned min_y : 16;
+ } dw1;
+
+ struct {
+ unsigned max_x : 16;
+ unsigned max_y : 16;
+ } dw2;
+};
+
+#define VERTEX_INLINE 0x00
+#define VERTEX_INDIRECT 0x01
+
+#define PRIM_TRILIST 0x00
+#define PRIM_TRISTRIP 0x01
+#define PRIM_TRISTRIP_REVERSE 0x02
+#define PRIM_TRIFAN 0x03
+#define PRIM_POLYGON 0x04
+#define PRIM_LINELIST 0x05
+#define PRIM_LINESTRIP 0x06
+#define PRIM_RECTLIST 0x07
+#define PRIM_POINTLIST 0x08
+#define PRIM_DIB 0x09
+#define PRIM_CLEAR_RECT 0x0a
+#define PRIM_ZONE_INIT 0x0d
+
+struct texture_coordinate_set
+{
+ unsigned tcx;
+ unsigned tcy;
+};
+
+struct vertex_data
+{
+ unsigned x;
+ unsigned y;
+ struct texture_coordinate_set tc0;
+ struct texture_coordinate_set tc1;
+};
+
+struct i915_3dprimitive
+{
+ union {
+ struct {
+ unsigned length : 18;
+ unsigned prim : 5;
+ unsigned vertex_location : 1;
+ unsigned opcode : 5;
+ unsigned type : 3;
+ } inline_prim;
+
+ struct {
+ unsigned vertex_count : 16;
+ unsigned pad0 : 1;
+ unsigned vertex_access_mode : 1;
+ unsigned prim : 5;
+ unsigned vertex_location : 1;
+ unsigned opcode : 5;
+ unsigned type : 3;
+ } indirect_prim;
+ } dw0;
+};
+#endif /*_I915_STRUCTS_H */
diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c
new file mode 100644
index 00000000..b30facdf
--- /dev/null
+++ b/src/xvmc/i915_xvmc.c
@@ -0,0 +1,2535 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Xiang Haihao <haihao.xiang@intel.com>
+ *
+ */
+
+#include <pthread.h>
+#include <sys/ioctl.h>
+
+#include "i915_xvmc.h"
+#include "i915_structs.h"
+#include "i915_program.h"
+
+#define YOFFSET(surface) (surface->srf.offset)
+#define UOFFSET(surface) (surface->srf.offset + \
+ SIZE_Y420(surface->width, surface->height) + \
+ SIZE_UV420(surface->width, surface->height))
+#define VOFFSET(surface) (surface->srf.offset + \
+ SIZE_Y420(surface->width, surface->height))
+
+/* Lookup tables to speed common calculations */
+static unsigned int mb_bytes[] = {
+ 000, 128, 128, 256, 128, 256, 256, 384, // 0
+ 128, 256, 256, 384, 256, 384, 384, 512, // 1
+ 128, 256, 256, 384, 256, 384, 384, 512, // 10
+ 256, 384, 384, 512, 384, 512, 512, 640, // 11
+ 128, 256, 256, 384, 256, 384, 384, 512, // 100
+ 256, 384, 384, 512, 384, 512, 512, 640, // 101
+ 256, 384, 384, 512, 384, 512, 512, 640, // 110
+ 384, 512, 512, 640, 512, 640, 640, 768 // 111
+};
+
+typedef union {
+ short s[4];
+ uint u[2];
+} su_t;
+
+static int findOverlap(unsigned int width, unsigned int height,
+ short *dstX, short *dstY,
+ short *srcX, short *srcY,
+ unsigned short *areaW, unsigned short *areaH)
+{
+ int w, h;
+ unsigned int mWidth, mHeight;
+
+ w = *areaW;
+ h = *areaH;
+
+ if ((*dstX >= width) || (*dstY >= height))
+ return 1;
+
+ if (*dstX < 0) {
+ w += *dstX;
+ *srcX -= *dstX;
+ *dstX = 0;
+ }
+
+ if (*dstY < 0) {
+ h += *dstY;
+ *srcY -= *dstY;
+ *dstY = 0;
+ }
+
+ if ((w <= 0) || ((h <= 0)))
+ return 1;
+
+ mWidth = width - *dstX;
+ mHeight = height - *dstY;
+ *areaW = (w <= mWidth) ? w : mWidth;
+ *areaH = (h <= mHeight) ? h : mHeight;
+ return 0;
+}
+
+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, h = surface->height;
+
+ /* 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);
+}
+
+
+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);
+}
+
+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;
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+
+ /* 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,
+ unsigned int mask,
+ unsigned int saturate,
+ unsigned int src0, unsigned int src1, unsigned int src2)
+{
+ dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
+ *inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
+ inst++;
+ *inst = (A1_SRC0(src0) | A1_SRC1(src1));
+ inst++;
+ *inst = (A2_SRC1(src1) | A2_SRC2(src2));
+}
+
+static void i915_inst_decl(unsigned int *inst,
+ unsigned int type,
+ unsigned int nr,
+ unsigned int d0_flags)
+{
+ unsigned int reg = UREG(type, nr);
+
+ *inst = (D0_DCL | D0_DEST(reg) | d0_flags);
+ inst++;
+ *inst = D1_MBZ;
+ inst++;
+ *inst = D2_MBZ;
+}
+
+static void i915_inst_texld(unsigned int *inst,
+ unsigned int op,
+ unsigned int dest,
+ unsigned int coord,
+ unsigned int sampler)
+{
+ dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
+ *inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
+ inst++;
+ *inst = T1_ADDRESS_REG(coord);
+ inst++;
+ *inst = T2_MBZ;
+}
+
+static void i915_mc_pixel_shader_program_buffer(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;
+
+ /* Shader 0 */
+ pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
+ 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);
+ 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;
+ /* dcl t0.xy */
+ inst = (unsigned int*)(++pixel_shader_program);
+ i915_inst_decl(inst, 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);
+ /* dcl_2D s0 */
+ inst += 3;
+ i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
+ /* texld r0, t0, s0 */
+ inst += 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);
+ /* mov oC, r0 */
+ inst += 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,
+ 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;
+ /* dcl t2.xy */
+ inst = (unsigned int*)(++pixel_shader_program);
+ i915_inst_decl(inst, 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);
+ /* dcl_2D s1 */
+ inst += 3;
+ i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
+ /* texld r0, t2, s1 */
+ inst += 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);
+ /* mov oC, r0 */
+ inst += 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,
+ 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;
+ /* dcl t0.xy */
+ inst = (unsigned int*)(++pixel_shader_program);
+ i915_inst_decl(inst, 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);
+ /* dcl t2.xy */
+ inst += 3;
+ i915_inst_decl(inst, 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);
+ /* dcl_2D s0 */
+ inst += 3;
+ i915_inst_decl(inst, 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);
+ /* texld r0, t0, s0 */
+ inst += 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);
+ /* texld r1, t2, s1 */
+ inst += 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);
+ /* add r0, r0, r1 */
+ inst += 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,
+ 0 /* A0_DEST_SATURATE */, src0, src1, src2);
+ /* mul oC, r0, c0 */
+ inst += 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,
+ 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;
+}
+
+static void i915_mc_one_time_state_initialization(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;
+
+ /* 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;
+ 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;
+
+ s3 = (struct s3_dword *)(++load_state_immediate_1);
+ s3->set0_pcd = 1;
+ s3->set1_pcd = 1;
+ s3->set2_pcd = 1;
+ s3->set3_pcd = 1;
+ s3->set4_pcd = 1;
+ s3->set5_pcd = 1;
+ s3->set6_pcd = 1;
+ s3->set7_pcd = 1;
+
+ s6 = (struct s6_dword *)(++s3);
+ s6->alpha_test_enable = 0;
+ s6->alpha_test_function = 0;
+ s6->alpha_reference_value = 0;
+ s6->depth_test_enable = 1;
+ s6->depth_test_function = 0;
+ s6->color_buffer_blend = 0;
+ s6->color_blend_function = 0;
+ s6->src_blend_factor = 1;
+ s6->dest_blend_factor = 1;
+ s6->depth_buffer_write = 0;
+ 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;
+ 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;
+
+ 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;
+
+ /* DIS */
+ dis = (dis_state *)(++load_indirect);
+ dis->dw0.valid = 0;
+ dis->dw0.reset = 0;
+ dis->dw0.buffer_address = 0;
+
+ /* SSB */
+ ssb = (ssb_state *)(++dis);
+ ssb->dw0.valid = 1;
+ ssb->dw0.force = 1;
+ ssb->dw1.length = 7; /* 8 - 1 */
+
+ if (mem_select)
+ ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
+ else
+ ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
+
+ /* PSP */
+ 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);
+ else
+ psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
+
+ /* PSC */
+ psc = (psc_state *)(++psp);
+ psc->dw0.valid = 1;
+ psc->dw0.force = 1;
+ psc->dw1.length = 5; /* 6 - 1 */
+
+ if (mem_select)
+ 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_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
+{
+ struct i915_3dstate_load_indirect *load_indirect = NULL;
+ sis_state *sis = NULL;
+ dis_state *dis = NULL;
+ ssb_state *ssb = NULL;
+ msb_state *msb = NULL;
+ psp_state *psp = NULL;
+ psc_state *psc = NULL;
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
+ unsigned int size;
+ void *base = NULL, *ptr = NULL;
+
+ size = sizeof(*load_indirect);
+ if (mask & BLOCK_SIS)
+ size += sizeof(*sis);
+ if (mask & BLOCK_DIS)
+ size += sizeof(*dis);
+ if (mask & BLOCK_SSB)
+ size += sizeof(*ssb);
+ if (mask & BLOCK_MSB)
+ size += sizeof(*msb);
+ if (mask & BLOCK_PSP)
+ size += sizeof(*psp);
+ if (mask & BLOCK_PSC)
+ size += sizeof(*psc);
+
+ if (size == sizeof(*load_indirect)) {
+ XVMC_ERR("There must be at least one bit set\n");
+ return;
+ }
+
+ /* 3DSTATE_LOAD_INDIRECT */
+ 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;
+
+ 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)
+ load_indirect->dw0.mem_select = 0;
+ else
+ load_indirect->dw0.mem_select = 1;
+
+ load_indirect->dw0.block_mask = mask;
+ load_indirect->dw0.length = (size >> 2) - 2;
+ ptr = ++load_indirect;
+
+ /* SIS */
+ if (mask & BLOCK_SIS) {
+ sis = (sis_state *)ptr;
+ sis->dw0.valid = 0;
+ sis->dw0.buffer_address = 0;
+ sis->dw1.length = 0;
+ ptr = ++sis;
+ }
+
+ /* DIS */
+ if (mask & BLOCK_DIS) {
+ dis = (dis_state *)ptr;
+ dis->dw0.valid = 0;
+ dis->dw0.reset = 0;
+ dis->dw0.buffer_address = 0;
+ ptr = ++dis;
+ }
+
+ /* SSB */
+ if (mask & BLOCK_SSB) {
+ ssb = (ssb_state *)ptr;
+ ssb->dw0.valid = 0;
+ ssb->dw0.buffer_address = 0;
+ ssb->dw1.length = 0;
+ ptr = ++ssb;
+ }
+
+ /* MSB */
+ if (mask & BLOCK_MSB) {
+ msb = (msb_state *)ptr;
+ msb->dw0.valid = 0;
+ msb->dw0.buffer_address = 0;
+ msb->dw1.length = 0;
+ ptr = ++msb;
+ }
+
+ /* PSP */
+ if (mask & BLOCK_PSP) {
+ psp = (psp_state *)ptr;
+ psp->dw0.valid = 0;
+ psp->dw0.buffer_address = 0;
+ psp->dw1.length = 0;
+ ptr = ++psp;
+ }
+
+ /* PSC */
+ if (mask & BLOCK_PSC) {
+ psc = (psc_state *)ptr;
+ psc->dw0.valid = 0;
+ psc->dw0.buffer_address = 0;
+ psc->dw1.length = 0;
+ ptr = ++psc;
+ }
+
+ intelBatchbufferData(base, size, 0);
+ free(base);
+}
+
+static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
+{
+ if (drmMap(xvmc_driver->fd,
+ pI915XvMC->sis.handle,
+ pI915XvMC->sis.size,
+ (drmAddress *)&pI915XvMC->sis.map) != 0) {
+ return -1;
+ }
+
+ if (drmMap(xvmc_driver->fd,
+ pI915XvMC->ssb.handle,
+ pI915XvMC->ssb.size,
+ (drmAddress *)&pI915XvMC->ssb.map) != 0) {
+ return -1;
+ }
+
+ if (drmMap(xvmc_driver->fd,
+ pI915XvMC->msb.handle,
+ pI915XvMC->msb.size,
+ (drmAddress *)&pI915XvMC->msb.map) != 0) {
+ return -1;
+ }
+
+ if (drmMap(xvmc_driver->fd,
+ pI915XvMC->psp.handle,
+ pI915XvMC->psp.size,
+ (drmAddress *)&pI915XvMC->psp.map) != 0) {
+ return -1;
+ }
+
+ if (drmMap(xvmc_driver->fd,
+ pI915XvMC->psc.handle,
+ pI915XvMC->psc.size,
+ (drmAddress *)&pI915XvMC->psc.map) != 0) {
+ return -1;
+ }
+
+ if (drmMap(xvmc_driver->fd,
+ pI915XvMC->corrdata.handle,
+ pI915XvMC->corrdata.size,
+ (drmAddress *)&pI915XvMC->corrdata.map) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
+{
+ if (pI915XvMC->sis.map) {
+ drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size);
+ pI915XvMC->sis.map = NULL;
+ }
+
+ if (pI915XvMC->ssb.map) {
+ drmUnmap(pI915XvMC->ssb.map, pI915XvMC->ssb.size);
+ pI915XvMC->ssb.map = NULL;
+ }
+
+ if (pI915XvMC->msb.map) {
+ drmUnmap(pI915XvMC->msb.map, pI915XvMC->msb.size);
+ pI915XvMC->msb.map = NULL;
+ }
+
+ if (pI915XvMC->psp.map) {
+ drmUnmap(pI915XvMC->psp.map, pI915XvMC->psp.size);
+ pI915XvMC->psp.map = NULL;
+ }
+
+ if (pI915XvMC->psc.map) {
+ drmUnmap(pI915XvMC->psc.map, pI915XvMC->psc.size);
+ pI915XvMC->psc.map = NULL;
+ }
+
+ if (pI915XvMC->corrdata.map) {
+ drmUnmap(pI915XvMC->corrdata.map, pI915XvMC->corrdata.size);
+ pI915XvMC->corrdata.map = NULL;
+ }
+}
+
+/*
+ * Video post processing
+ */
+static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
+{
+ struct i915_3dstate_map_state *map_state;
+ struct texture_map *tm;
+ i915XvMCSurface *privTarget = NULL;
+ i915XvMCContext *pI915XvMC = NULL;
+ unsigned int w = target_surface->width, h = target_surface->height;
+
+ privTarget = (i915XvMCSurface *)target_surface->privData;
+ pI915XvMC = (i915XvMCContext *)privTarget->privContext;
+ /* 3DSATE_MAP_STATE */
+ 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 = 0;
+ map_state->dw0.length = 9;
+ map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1 | MAP_MAP2;
+
+ /* texture map 0: V Plane */
+ 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(privTarget);
+ tm->tm1.tile_walk = TILEWALK_XMAJOR;
+ tm->tm1.tiled_surface = 0;
+ tm->tm1.utilize_fence_regs = 1;
+ 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 = (privTarget->uvStride >> 2) - 1; /* in DWords - 1 */
+
+ /* texture map 1: Y Plane */
+ ++tm;
+ memset(tm, 0, sizeof(*tm));
+ tm->tm0.v_ls_offset = 0;
+ tm->tm0.v_ls = 0;
+ tm->tm0.base_address = YOFFSET(privTarget);
+ tm->tm1.tile_walk = TILEWALK_XMAJOR;
+ tm->tm1.tiled_surface = 0;
+ tm->tm1.utilize_fence_regs = 1;
+ tm->tm1.texel_fmt = 0;
+ tm->tm1.surface_fmt = 1;
+ 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 = (privTarget->yStride >> 2) - 1; /* in DWords - 1 */
+
+ /* texture map 2: U Plane */
+ ++tm;
+ memset(tm, 0, sizeof(*tm));
+ tm->tm0.v_ls_offset = 0;
+ tm->tm0.v_ls = 0;
+ tm->tm0.base_address = UOFFSET(privTarget);
+ tm->tm1.tile_walk = TILEWALK_XMAJOR;
+ tm->tm1.tiled_surface = 0;
+ tm->tm1.utilize_fence_regs = 1;
+ 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 = (privTarget->uvStride >> 2) - 1; /* in DWords - 1 */
+}
+
+static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
+{
+ struct i915_3dstate_sampler_state *sampler_state;
+ struct texture_sampler *ts;
+ i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+
+ /* 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 = 9;
+ sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1 | SAMPLER_SAMPLER2;
+
+ /* Sampler 0 */
+ ts = (struct texture_sampler *)(++sampler_state);
+ memset(ts, 0, sizeof(*ts));
+ ts->ts0.reverse_gamma = 0;
+ ts->ts0.planar2packet = 1;
+ ts->ts0.color_conversion = 1;
+ 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;
+ ts->ts0.shadow_enable = 0;
+ ts->ts0.max_anisotropy = ANISORATIO_2;
+ ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+ ts->ts1.min_lod = 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 = 1;
+ ts->ts0.color_conversion = 1;
+ 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;
+ ts->ts0.shadow_enable = 0;
+ ts->ts0.max_anisotropy = ANISORATIO_2;
+ ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+ ts->ts1.min_lod = 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;
+
+ /* Sampler 2 */
+ ++ts;
+ memset(ts, 0, sizeof(*ts));
+ ts->ts0.reverse_gamma = 0;
+ ts->ts0.planar2packet = 1;
+ ts->ts0.color_conversion = 1;
+ 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;
+ ts->ts0.shadow_enable = 0;
+ ts->ts0.max_anisotropy = ANISORATIO_2;
+ ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
+ ts->ts1.min_lod = 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 = 2;
+ ts->ts1.east_deinterlacer = 0;
+ ts->ts2.default_color = 0;
+}
+
+static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
+ unsigned int dstaddr,
+ int dstpitch)
+{
+ struct i915_3dstate_buffer_info *buffer_info;
+ struct i915_3dstate_dest_buffer_variables *dest_buffer_variables;
+ i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+
+ /* 3DSTATE_BUFFER_INFO */
+ 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 = 1;
+ buffer_info->dw1.tiled_surface = 0; /* linear */
+ buffer_info->dw1.walk = TILEWALK_XMAJOR;
+ buffer_info->dw1.pitch = dstpitch;
+ buffer_info->dw2.base_address = dstaddr;
+
+ /* 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; /* FIXME 0x1000 .5 ??? */
+ dest_buffer_variables->dw1.dest_h_bias = 8;
+ dest_buffer_variables->dw1.color_fmt = COLORBUFFER_A8R8G8B8; /* FIXME */
+}
+
+static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
+{
+ struct i915_3dstate_pixel_shader_program *pixel_shader_program;
+ i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+ unsigned int *inst;
+ unsigned int dest, src0, src1;
+
+ /* Shader 0 */
+ pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
+ 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 = 0;
+ pixel_shader_program->dw0.length = 23;
+ /* dcl t0.xy */
+ inst = (unsigned int*)(++pixel_shader_program);
+ i915_inst_decl(inst, 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);
+ /* dcl_2D s0 */
+ inst += 3;
+ i915_inst_decl(inst, 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);
+ /* dcl_2D s2 */
+ inst += 3;
+ i915_inst_decl(inst, REG_TYPE_S, 2, D0_SAMPLE_TYPE_2D);
+ /* texld r0 t1 s0 */
+ inst += 3;
+ dest = UREG(REG_TYPE_R, 0);
+ src0 = UREG(REG_TYPE_T, 1); /* COORD */
+ src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
+ i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+ /* texld r0 t0 s1 */
+ inst += 3;
+ dest = UREG(REG_TYPE_R, 0);
+ src0 = UREG(REG_TYPE_T, 0); /* COORD */
+ src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
+ i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+ /* texld oC t1 s2 */
+ inst += 3;
+ dest = UREG(REG_TYPE_OC, 0);
+ src0 = UREG(REG_TYPE_T, 1); /* COORD */
+ src1 = UREG(REG_TYPE_S, 2); /* SAMPLER */
+ i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
+}
+
+static void i915_yuv2rgb_proc(XvMCSurface *surface)
+{
+ i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
+ i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
+ struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL;
+ struct s2_dword *s2 = NULL;
+ struct s3_dword *s3 = NULL;
+ struct s4_dword *s4 = NULL;
+ struct s5_dword *s5 = NULL;
+ struct s6_dword *s6 = NULL;
+ struct s7_dword *s7 = NULL;
+ struct i915_3dstate_scissor_rectangle scissor_rectangle;
+ struct i915_3dstate_load_indirect *load_indirect = NULL;
+ sis_state *sis = NULL;
+ ssb_state *ssb = NULL;
+ msb_state *msb = NULL;
+ psp_state *psp = NULL;
+ struct i915_3dprimitive *_3dprimitive = NULL;
+ struct vertex_data *vd = NULL;
+ unsigned int size;
+ void *base = NULL;
+
+ /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
+ size = sizeof(*load_state_immediate_1) + sizeof(*s2) + sizeof(*s3) +
+ sizeof(*s4) + sizeof(*s5) + sizeof(*s6) + sizeof(*s7);
+ base = calloc(1, size);
+ load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)base;
+ 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_s2 = 1;
+ load_state_immediate_1->dw0.load_s3 = 1;
+ load_state_immediate_1->dw0.load_s4 = 1;
+ load_state_immediate_1->dw0.load_s5 = 1;
+ load_state_immediate_1->dw0.load_s6 = 1;
+ load_state_immediate_1->dw0.load_s7 = 1;
+ load_state_immediate_1->dw0.length = 5;
+
+ s2 = (struct s2_dword *)(++load_state_immediate_1);
+ s2->set0_texcoord_fmt = TEXCOORDFMT_2FP;
+ s2->set1_texcoord_fmt = TEXCOORDFMT_2FP;
+ s2->set2_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+ s2->set3_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+ s2->set4_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+ s2->set5_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+ s2->set6_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+ s2->set7_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
+
+ s3 = (struct s3_dword *)(++s2);
+ s4 = (struct s4_dword *)(++s3);
+ s4->position_mask = VERTEXHAS_XY;
+ s4->cull_mode = CULLMODE_NONE;
+ s4->color_shade_mode = SHADEMODE_FLAT;
+ s4->specular_shade_mode = SHADEMODE_FLAT;
+ s4->fog_shade_mode = SHADEMODE_FLAT;
+ s4->alpha_shade_mode = SHADEMODE_FLAT;
+ s4->line_width = 0x2; /* FIXME: 1.0??? */
+ s4->point_width = 0x1;
+
+ s5 = (struct s5_dword *)(++s4);
+ s6 = (struct s6_dword *)(++s5);
+ s6->src_blend_factor = 1;
+ s6->dest_blend_factor = 1;
+ s6->color_buffer_write = 1;
+
+ s7 = (struct s7_dword *)(++s6);
+ intelBatchbufferData(base, size, 0);
+ free(base);
+
+ /* 3DSTATE_3DSTATE_SCISSOR_RECTANGLE */
+ scissor_rectangle.dw0.type = CMD_3D;
+ scissor_rectangle.dw0.opcode = OPC_3DSTATE_SCISSOR_RECTANGLE;
+ scissor_rectangle.dw0.length = 1;
+ scissor_rectangle.dw1.min_x = 0;
+ scissor_rectangle.dw1.min_y = 0;
+ scissor_rectangle.dw2.max_x = 2047;
+ scissor_rectangle.dw2.max_y = 2047;
+ intelBatchbufferData(&scissor_rectangle, sizeof(scissor_rectangle), 0);
+
+ /* 3DSTATE_LOAD_INDIRECT */
+ size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*ssb) + sizeof(*msb) + sizeof(*psp);
+ 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.mem_select = 1; /* Bearlake only */
+ load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_SSB | BLOCK_MSB | BLOCK_PSP;
+ load_indirect->dw0.length = 7;
+
+ /* SIS */
+ sis = (sis_state *)(++load_indirect);
+ sis->dw0.valid = 1;
+ sis->dw0.buffer_address = pI915XvMC->sis.offset;
+ sis->dw1.length = ((sizeof(struct i915_3dstate_buffer_info) +
+ sizeof(struct i915_3dstate_dest_buffer_variables)) >> 2) - 1;
+
+ /* SSB */
+ ssb = (ssb_state *)(++sis);
+ ssb->dw0.valid = 1;
+ ssb->dw0.buffer_address = pI915XvMC->ssb.offset;
+ ssb->dw1.length = ((sizeof(struct i915_3dstate_sampler_state) +
+ sizeof(struct texture_sampler) * 3) >> 2) - 1;
+
+ /* MSB */
+ msb = (msb_state *)(++ssb);
+ msb->dw0.valid = 1;
+ msb->dw0.buffer_address = pI915XvMC->msb.offset;
+ msb->dw1.length = ((sizeof(struct i915_3dstate_map_state) +
+ sizeof(struct texture_map) * 3) >> 2) - 1;
+
+ /* PSP */
+ psp = (psp_state *)(++msb);
+ psp->dw0.valid = 1;
+ psp->dw0.buffer_address = pI915XvMC->psp.offset;
+ psp->dw1.length = ((sizeof(struct i915_3dstate_pixel_shader_program) +
+ sizeof(union shader_inst)) >> 2) - 1;
+
+ intelBatchbufferData(base, size, 0);
+ free(base);
+
+ /* 3DPRIMITIVE */
+ size = sizeof(*_3dprimitive) + sizeof(*vd) * 3;
+ base = calloc(1, size);
+ _3dprimitive = (struct i915_3dprimitive *)base;
+ _3dprimitive->dw0.inline_prim.type = CMD_3D;
+ _3dprimitive->dw0.inline_prim.opcode = OPC_3DPRIMITIVE;
+ _3dprimitive->dw0.inline_prim.vertex_location = VERTEX_INLINE;
+ _3dprimitive->dw0.inline_prim.prim = PRIM_RECTLIST;
+ _3dprimitive->dw0.inline_prim.length = size - 2;
+
+ vd = (struct vertex_data *)(++_3dprimitive);
+ vd->x = 0; /* FIXME!!! */
+ vd->x = 0; /* FIXME */
+ vd->tc0.tcx = 0;
+ vd->tc0.tcy = 0;
+ vd->tc1.tcx = 0;
+ vd->tc1.tcy = 0;
+
+ ++vd;
+ vd->x = 0; /* FIXME!!! */
+ vd->x = 0; /* FIXME */
+ vd->tc0.tcx = 0;
+ vd->tc0.tcy = 0;
+ vd->tc1.tcx = 0;
+ vd->tc1.tcy = 0;
+
+ ++vd;
+ vd->x = 0; /* FIXME!!! */
+ vd->x = 0; /* FIXME */
+ vd->tc0.tcx = 0;
+ vd->tc0.tcy = 0;
+ vd->tc1.tcx = 0;
+ vd->tc1.tcy = 0;
+
+ intelBatchbufferData(base, size, 0);
+ free(base);
+}
+
+/*
+ * Function: i915_release_resource
+ */
+static void i915_release_resource(Display *display, XvMCContext *context)
+{
+ i915XvMCContext *pI915XvMC;
+ int screen = DefaultScreen(display);
+
+ if (!(pI915XvMC = context->privData))
+ return;
+
+ pI915XvMC->ref--;
+ i915_xvmc_unmap_buffers(pI915XvMC);
+
+ driDestroyHashContents(pI915XvMC->drawHash);
+ drmHashDestroy(pI915XvMC->drawHash);
+
+ free(pI915XvMC);
+ context->privData = NULL;
+}
+
+static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context,
+ int priv_count, CARD32 *priv_data)
+{
+ i915XvMCContext *pI915XvMC = NULL;
+ I915XvMCCreateContextRec *tmpComm = NULL;
+ Status ret;
+ drm_sarea_t *pSAREA;
+ char *curBusID;
+ uint magic;
+ int major, minor;
+ int isCapable;
+ int screen = DefaultScreen(display);
+
+ XVMC_DBG("%s\n", __FUNCTION__);
+
+ if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
+ XVMC_ERR("_xvmc_create_context() returned incorrect data size!");
+ XVMC_INFO("\tExpected %d, got %d",
+ (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count);
+ _xvmc_destroy_context(display, context);
+ XFree(priv_data);
+ context->privData = NULL;
+ return BadValue;
+ }
+
+ context->privData = (void *)calloc(1, sizeof(i915XvMCContext));
+ if (!context->privData) {
+ XVMC_ERR("Unable to allocate resources for XvMC context.");
+ return BadAlloc;
+ }
+ pI915XvMC = (i915XvMCContext *)context->privData;
+
+ tmpComm = (I915XvMCCreateContextRec *)priv_data;
+ pI915XvMC->ctxno = tmpComm->ctxno;
+ pI915XvMC->deviceID = tmpComm->deviceID;
+ pI915XvMC->sis.handle = tmpComm->sis.handle;
+ pI915XvMC->sis.offset = tmpComm->sis.offset;
+ pI915XvMC->sis.size = tmpComm->sis.size;
+ pI915XvMC->ssb.handle = tmpComm->ssb.handle;
+ pI915XvMC->ssb.offset = tmpComm->ssb.offset;
+ pI915XvMC->ssb.size = tmpComm->ssb.size;
+ pI915XvMC->msb.handle = tmpComm->msb.handle;
+ pI915XvMC->msb.offset = tmpComm->msb.offset;
+ pI915XvMC->msb.size = tmpComm->msb.size;
+ pI915XvMC->psp.handle = tmpComm->psp.handle;
+ pI915XvMC->psp.offset = tmpComm->psp.offset;
+ pI915XvMC->psp.size = tmpComm->psp.size;
+ pI915XvMC->psc.handle = tmpComm->psc.handle;
+ pI915XvMC->psc.offset = tmpComm->psc.offset;
+ 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->sis.bus_addr = tmpComm->sis.bus_addr;
+ pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr;
+ pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr;
+ pI915XvMC->psp.bus_addr = tmpComm->psp.bus_addr;
+ pI915XvMC->psc.bus_addr = tmpComm->psc.bus_addr;
+ }
+
+ pI915XvMC->corrdata.handle = tmpComm->corrdata.handle;
+ pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
+ pI915XvMC->corrdata.size = tmpComm->corrdata.size;
+ pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset;
+
+ /* Must free the private data we were passed from X */
+ XFree(priv_data);
+ priv_data = NULL;
+
+ pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
+ pI915XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pI915XvMC->sarea_priv_offset);
+
+ if (NULL == (pI915XvMC->drawHash = drmHashCreate())) {
+ XVMC_ERR("Could not allocate drawable hash table.");
+ free(pI915XvMC);
+ context->privData = NULL;
+ return BadAlloc;
+ }
+
+ if (i915_xvmc_map_buffers(pI915XvMC)) {
+ i915_xvmc_unmap_buffers(pI915XvMC);
+ free(pI915XvMC);
+ context->privData = NULL;
+ return BadAlloc;
+ }
+
+ /* Initialize private context values */
+ pI915XvMC->yStride = STRIDE(context->width);
+ pI915XvMC->uvStride = STRIDE(context->width >> 1);
+ pI915XvMC->haveXv = 0;
+ pI915XvMC->dual_prime = 0;
+ pI915XvMC->last_flip = 0;
+ pI915XvMC->port = context->port;
+ pI915XvMC->ref = 1;
+ return Success;
+}
+
+static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
+{
+ i915XvMCContext *pI915XvMC;
+
+ if (!(pI915XvMC = context->privData))
+ return XvMCBadContext;
+
+ /* Pass Control to the X server to destroy the drm_context_t */
+ i915_release_resource(display,context);
+ return Success;
+}
+
+static Status i915_xvmc_mc_create_surface(Display *display,
+ XvMCContext *context, XvMCSurface *surface, int priv_count,
+ CARD32 *priv_data)
+{
+ Status ret;
+ i915XvMCContext *pI915XvMC;
+ i915XvMCSurface *pI915Surface;
+ I915XvMCCreateSurfaceRec *tmpComm = NULL;
+
+ if (!(pI915XvMC = context->privData))
+ return XvMCBadContext;
+
+ XVMC_DBG("%s\n", __FUNCTION__);
+
+ if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
+ XVMC_ERR("_xvmc_create_surface() returned incorrect data size!");
+ XVMC_INFO("\tExpected %d, got %d",
+ (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
+ _xvmc_destroy_surface(display, surface);
+ XFree(priv_data);
+ return BadAlloc;
+ }
+
+ PPTHREAD_MUTEX_LOCK();
+ surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
+
+ if (!(pI915Surface = surface->privData)) {
+ PPTHREAD_MUTEX_UNLOCK();
+ return BadAlloc;
+ }
+
+ /* Initialize private values */
+ pI915Surface->last_render = 0;
+ pI915Surface->last_flip = 0;
+ pI915Surface->yStride = pI915XvMC->yStride;
+ pI915Surface->uvStride = pI915XvMC->uvStride;
+ pI915Surface->width = context->width;
+ pI915Surface->height = context->height;
+ pI915Surface->privContext = pI915XvMC;
+ pI915Surface->privSubPic = NULL;
+ pI915Surface->srf.map = NULL;
+
+ tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
+
+ pI915Surface->srfNo = tmpComm->srfno;
+ pI915Surface->srf.handle = tmpComm->srf.handle;
+ pI915Surface->srf.offset = tmpComm->srf.offset;
+ pI915Surface->srf.size = tmpComm->srf.size;
+
+ XFree(priv_data);
+
+ if (drmMap(xvmc_driver->fd,
+ pI915Surface->srf.handle,
+ pI915Surface->srf.size,
+ (drmAddress *)&pI915Surface->srf.map) != 0) {
+ XVMC_ERR("mapping surface memory failed!\n");
+ _xvmc_destroy_surface(display, surface);
+ free(pI915Surface);
+ surface->privData = NULL;
+ PPTHREAD_MUTEX_UNLOCK();
+ return BadAlloc;
+ }
+
+ pI915XvMC->ref++;
+ PPTHREAD_MUTEX_UNLOCK();
+ return 0;
+}
+
+
+static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface)
+{
+ i915XvMCSurface *pI915Surface;
+ i915XvMCContext *pI915XvMC;
+
+ if (!display || !surface)
+ return BadValue;
+
+ if (!(pI915Surface = surface->privData))
+ return XvMCBadSurface;
+
+ if (!(pI915XvMC = pI915Surface->privContext))
+ return XvMCBadSurface;
+
+ if (pI915Surface->last_flip)
+ XvMCSyncSurface(display,surface);
+
+ if (pI915Surface->srf.map)
+ drmUnmap(pI915Surface->srf.map, pI915Surface->srf.size);
+
+ free(pI915Surface);
+ surface->privData = NULL;
+ pI915XvMC->ref--;
+
+ return Success;
+}
+
+
+static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
+ unsigned int picture_structure,
+ XvMCSurface *target_surface,
+ XvMCSurface *past_surface,
+ XvMCSurface *future_surface,
+ unsigned int flags,
+ unsigned int num_macroblocks,
+ unsigned int first_macroblock,
+ XvMCMacroBlockArray *macroblock_array,
+ XvMCBlockArray *blocks)
+{
+ int i;
+ int picture_coding_type = MPEG_I_PICTURE;
+ /* correction data buffer */
+ char *corrdata_ptr;
+ int corrdata_size = 0;
+
+ /* Block Pointer */
+ short *block_ptr;
+ /* Current Macroblock Pointer */
+ XvMCMacroBlock *mb;
+
+ intel_xvmc_context_ptr intel_ctx;
+
+ i915XvMCSurface *privTarget = NULL;
+ i915XvMCSurface *privFuture = NULL;
+ i915XvMCSurface *privPast = NULL;
+ i915XvMCContext *pI915XvMC = NULL;
+
+ XVMC_DBG("%s\n", __FUNCTION__);
+
+ /* Check Parameters for validity */
+ if (!display || !context || !target_surface) {
+ XVMC_ERR("Invalid Display, Context or Target!");
+ return BadValue;
+ }
+
+ if (!num_macroblocks)
+ return Success;
+
+ if (!macroblock_array || !blocks) {
+ XVMC_ERR("Invalid block data!");
+ return BadValue;
+ }
+
+ if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) {
+ XVMC_ERR("Too many macroblocks requested for MB array size.");
+ return BadValue;
+ }
+
+ if (!(pI915XvMC = context->privData))
+ return XvMCBadContext;
+
+ 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.");
+ return BadValue;
+ }
+
+ intel_ctx = intel_xvmc_find_context(context->context_id);
+ if (!intel_ctx) {
+ XVMC_ERR("Can't find intel xvmc context\n");
+ return BadValue;
+ }
+
+ /* P Frame Test */
+ if (!past_surface) {
+ /* Just to avoid some ifs later. */
+ privPast = privTarget;
+ } else {
+ if (!(privPast = past_surface->privData)) {
+ XVMC_ERR("Invalid Past Surface!");
+ return XvMCBadSurface;
+ }
+ picture_coding_type = MPEG_P_PICTURE;
+ }
+
+ /* B Frame Test */
+ if (!future_surface) {
+ privFuture = privPast; // privTarget;
+ } else {
+ if (!past_surface) {
+ XVMC_ERR("No Past Surface!");
+ return BadValue;
+ }
+
+ if (!(privFuture = future_surface->privData)) {
+ XVMC_ERR("Invalid Future Surface!");
+ return XvMCBadSurface;
+ }
+
+ picture_coding_type = MPEG_B_PICTURE;
+ }
+
+ LOCK_HARDWARE(intel_ctx->hw_context);
+ corrdata_ptr = pI915XvMC->corrdata.map;
+ corrdata_size = 0;
+
+ for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
+ int bspm = 0;
+ mb = &macroblock_array->macro_blocks[i];
+ block_ptr = &(blocks->blocks[mb->index << 6]);
+
+ /* Lockup can happen if the coordinates are too far out of range */
+ if (mb->x > (target_surface->width >> 4)) {
+ mb->x = 0;
+ XVMC_INFO("reset x");
+ }
+
+ if (mb->y > (target_surface->height >> 4)) {
+ mb->y = 0;
+ XVMC_INFO("reset y");
+ }
+
+ /* Catch no pattern case */
+ if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) &&
+ !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) &&
+ mb->coded_block_pattern) {
+ mb->coded_block_pattern = 0;
+ XVMC_INFO("no coded blocks present!");
+ }
+
+ bspm = mb_bytes[mb->coded_block_pattern];
+
+ if (!bspm)
+ continue;
+
+ corrdata_size += bspm;
+
+ if (corrdata_size > pI915XvMC->corrdata.size) {
+ XVMC_ERR("correction data buffer overflow.");
+ break;
+ }
+ memcpy(corrdata_ptr, block_ptr, bspm);
+ corrdata_ptr += bspm;
+ }
+
+ i915_flush(1, 0);
+ // 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_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++) {
+ mb = &macroblock_array->macro_blocks[i];
+
+ /* Intra Blocks */
+ if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
+ i915_mc_mpeg_macroblock_ipicture(context, mb);
+ } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
+ /* Frame Picture */
+ switch (mb->motion_type & 3) {
+ case XVMC_PREDICTION_FIELD: /* Field Based */
+ i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
+ break;
+
+ case XVMC_PREDICTION_FRAME: /* Frame Based */
+ i915_mc_mpeg_macroblock_1fbmv(context, mb);
+ break;
+
+ case XVMC_PREDICTION_DUAL_PRIME: /* Dual Prime */
+ i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
+ break;
+
+ default: /* No Motion Type */
+ XVMC_ERR("Invalid Macroblock Parameters found.");
+ break;
+ }
+ } else { /* Frame Picture */
+ switch (mb->motion_type & 3) {
+ case XVMC_PREDICTION_FIELD: /* Field Based */
+ i915_mc_mpeg_macroblock_1fbmv(context, mb);
+ break;
+
+ case XVMC_PREDICTION_16x8: /* 16x8 MC */
+ i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
+ break;
+
+ case XVMC_PREDICTION_DUAL_PRIME: /* Dual Prime */
+ i915_mc_mpeg_macroblock_1fbmv(context, mb);
+ break;
+
+ default: /* No Motion Type */
+ XVMC_ERR("Invalid Macroblock Parameters found.");
+ break;
+ }
+ } /* Field Picture */
+ }
+
+ intelFlushBatch(TRUE);
+ xvmc_driver->last_render = xvmc_driver->alloc.irq_emitted;
+ privTarget->last_render = xvmc_driver->last_render;
+
+ UNLOCK_HARDWARE(intel_ctx->hw_context);
+ return 0;
+}
+
+static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
+ Drawable draw, short srcx, short srcy,
+ unsigned short srcw, unsigned short srch,
+ short destx, short desty,
+ unsigned short destw, unsigned short desth,
+ int flags, struct intel_xvmc_command *data)
+{
+ i915XvMCContext *pI915XvMC;
+ i915XvMCSurface *pI915Surface;
+ i915XvMCSubpicture *pI915SubPic;
+
+ if (!(pI915Surface = surface->privData))
+ return XvMCBadSurface;
+
+ if (!(pI915XvMC = pI915Surface->privContext))
+ return XvMCBadSurface;
+
+ PPTHREAD_MUTEX_LOCK();
+
+ data->command = INTEL_XVMC_COMMAND_DISPLAY;
+ data->ctxNo = pI915XvMC->ctxno;
+ data->srfNo = pI915Surface->srfNo;
+ pI915SubPic = pI915Surface->privSubPic;
+ data->subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo);
+ data->real_id = FOURCC_YV12;
+ data->flags = flags;
+
+ PPTHREAD_MUTEX_UNLOCK();
+
+ return 0;
+}
+
+static int i915_xvmc_mc_get_surface_status(Display *display,
+ XvMCSurface *surface, int *stat)
+{
+ i915XvMCSurface *pI915Surface;
+ i915XvMCContext *pI915XvMC;
+
+ if (!display || !surface || !stat)
+ return BadValue;
+
+ *stat = 0;
+
+ if (!(pI915Surface = surface->privData))
+ return XvMCBadSurface;
+
+ if (!(pI915XvMC = pI915Surface->privContext))
+ return XvMCBadSurface;
+
+ PPTHREAD_MUTEX_LOCK();
+ if (pI915Surface->last_flip) {
+ /* This can not happen */
+ if (pI915XvMC->last_flip < pI915Surface->last_flip) {
+ XVMC_ERR("Context last flip is less than surface last flip.");
+ PPTHREAD_MUTEX_UNLOCK();
+ return BadValue;
+ }
+
+ /*
+ If the context has 2 or more flips after this surface it
+ cannot be displaying. Don't bother to check.
+ */
+ if (!(pI915XvMC->last_flip > (pI915Surface->last_flip + 1))) {
+ /*
+ If this surface was the last flipped it is either displaying
+ or about to be so don't bother checking.
+ */
+ if (pI915XvMC->last_flip == pI915Surface->last_flip) {
+ *stat |= XVMC_DISPLAYING;
+ }
+ }
+ }
+
+ if (pI915Surface->last_render &&
+ (pI915Surface->last_render > pI915XvMC->sarea->last_dispatch)) {
+ *stat |= XVMC_RENDERING;
+ }
+
+ PPTHREAD_MUTEX_UNLOCK();
+ return 0;
+}
+
+/* XXX WIP code */
+#if 0
+Status XvMCHideSurface(Display *display, XvMCSurface *surface)
+{
+ i915XvMCSurface *pI915Surface;
+ i915XvMCContext *pI915XvMC;
+ int stat = 0, ret;
+
+ if (!display || !surface)
+ return BadValue;
+
+ if (!(pI915Surface = surface->privData))
+ return XvMCBadSurface;
+
+ /* Get the associated context pointer */
+ if (!(pI915XvMC = pI915Surface->privContext))
+ return XvMCBadSurface;
+
+ XvMCSyncSurface(display, surface);
+
+ /*
+ Get the status of the surface, if it is not currently displayed
+ we don't need to worry about it.
+ */
+ if ((ret = XvMCGetSurfaceStatus(display, surface, &stat)) != Success)
+ return ret;
+
+ if (!(stat & XVMC_DISPLAYING))
+ return Success;
+
+ /* FIXME: */
+ return Success;
+}
+
+Status i915_xvmc_create_subpict(Display *display, XvMCContext *context,
+ XvMCSubpicture *subpicture,
+ unsigned short width, unsigned short height,
+ int xvimage_id)
+{
+ Status ret;
+ i915XvMCContext *pI915XvMC;
+ i915XvMCSubpicture *pI915Subpicture;
+ I915XvMCCreateSurfaceRec *tmpComm = NULL;
+ int priv_count;
+ uint *priv_data;
+
+ if (!subpicture || !context || !display)
+ return BadValue;
+
+ pI915XvMC = (i915XvMCContext *)context->privData;
+
+ if (!pI915XvMC)
+ return XvMCBadContext;
+
+ subpicture->privData =
+ (i915XvMCSubpicture *)malloc(sizeof(i915XvMCSubpicture));
+
+ if (!subpicture->privData)
+ return BadAlloc;
+
+ PPTHREAD_MUTEX_LOCK();
+ subpicture->context_id = context->context_id;
+ subpicture->xvimage_id = xvimage_id;
+ subpicture->width = width;
+ subpicture->height = height;
+ pI915Subpicture = (i915XvMCSubpicture *)subpicture->privData;
+
+ XLockDisplay(display);
+ if ((ret = _xvmc_create_subpicture(display, context, subpicture,
+ &priv_count, &priv_data))) {
+ XUnlockDisplay(display);
+ XVMC_ERR("Unable to create XvMCSubpicture.");
+ free(pI915Subpicture);
+ subpicture->privData = NULL;
+ PPTHREAD_MUTEX_UNLOCK();
+ return ret;
+ }
+ XUnlockDisplay(display);
+
+ if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
+ XVMC_ERR("_xvmc_create_subpicture() returned incorrect data size!");
+ XVMC_INFO("\tExpected %d, got %d",
+ (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
+ XLockDisplay(display);
+ _xvmc_destroy_subpicture(display, subpicture);
+ XUnlockDisplay(display);
+ XFree(priv_data);
+ free(pI915Subpicture);
+ subpicture->privData = NULL;
+ PPTHREAD_MUTEX_UNLOCK();
+ return BadAlloc;
+ }
+
+ tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
+ pI915Subpicture->srfNo = tmpComm->srfno;
+ pI915Subpicture->srf.handle = tmpComm->srf.handle;
+ pI915Subpicture->srf.offset = tmpComm->srf.offset;
+ pI915Subpicture->srf.size = tmpComm->srf.size;
+ XFree(priv_data);
+
+ if (drmMap(pI915XvMC->fd,
+ pI915Subpicture->srf.handle,
+ pI915Subpicture->srf.size,
+ (drmAddress *)&pI915Subpicture->srf.map) != 0) {
+ XLockDisplay(display);
+ _xvmc_destroy_subpicture(display, subpicture);
+ XUnlockDisplay(display);
+ free(pI915Subpicture);
+ subpicture->privData = NULL;
+ PPTHREAD_MUTEX_UNLOCK();
+ return BadAlloc;
+ }
+
+ /* subpicture */
+ subpicture->num_palette_entries = I915_SUBPIC_PALETTE_SIZE;
+ subpicture->entry_bytes = 3;
+ strncpy(subpicture->component_order, "YUV", 4);
+
+ /* Initialize private values */
+ pI915Subpicture->privContext = pI915XvMC;
+ pI915Subpicture->last_render= 0;
+ pI915Subpicture->last_flip = 0;
+ pI915Subpicture->pitch = ((subpicture->width + 3) & ~3);
+
+ switch(subpicture->xvimage_id) {
+ case FOURCC_IA44:
+ case FOURCC_AI44:
+ break;
+
+ default:
+ drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
+ XLockDisplay(display);
+ _xvmc_destroy_subpicture(display, subpicture);
+ XUnlockDisplay(display);
+ free(pI915Subpicture);
+ subpicture->privData = NULL;
+ PPTHREAD_MUTEX_UNLOCK();
+ return BadMatch;
+ }
+
+ pI915XvMC->ref++;
+ PPTHREAD_MUTEX_UNLOCK();
+ return Success;
+}
+
+Status i915_xvmc_clear_subpict(Display *display, XvMCSubpicture *subpicture,
+ short x, short y,
+ unsigned short width, unsigned short height,
+ unsigned int color)
+{
+ i915XvMCContext *pI915XvMC;
+ i915XvMCSubpicture *pI915Subpicture;
+
+ if (!display || !subpicture)
+ return BadValue;
+
+ if (!(pI915Subpicture = subpicture->privData))
+ return XvMCBadSubpicture;
+
+ if (!(pI915XvMC = pI915Subpicture->privContext))
+ return XvMCBadSubpicture;
+
+ if ((x < 0) || (x + width) > subpicture->width)
+ return BadValue;
+
+ if ((y < 0) || (y + height) > subpicture->height)
+ return BadValue;
+
+ /* FIXME: clear the area */
+
+ return Success;
+}
+
+Status i915_xvmc_composite_subpict(Display *display, XvMCSubpicture *subpicture,
+ XvImage *image,
+ short srcx, short srcy,
+ unsigned short width, unsigned short height,
+ short dstx, short dsty)
+{
+ i915XvMCContext *pI915XvMC;
+ i915XvMCSubpicture *pI915Subpicture;
+
+ if (!display || !subpicture)
+ return BadValue;
+
+ if (!(pI915Subpicture = subpicture->privData))
+ return XvMCBadSubpicture;
+
+ if (!(pI915XvMC = pI915Subpicture->privContext))
+ return XvMCBadSubpicture;
+
+ if ((srcx < 0) || (srcx + width) > subpicture->width)
+ return BadValue;
+
+ if ((srcy < 0) || (srcy + height) > subpicture->height)
+ return BadValue;
+
+ if ((dstx < 0) || (dstx + width) > subpicture->width)
+ return BadValue;
+
+ if ((dsty < 0) || (dsty + width) > subpicture->height)
+ return BadValue;
+
+ if (image->id != subpicture->xvimage_id)
+ return BadMatch;
+
+ /* FIXME */
+ return Success;
+}
+
+
+Status i915_xvmc_destroy_subpict(Display *display, XvMCSubpicture *subpicture)
+{
+ i915XvMCSubpicture *pI915Subpicture;
+ i915XvMCContext *pI915XvMC;
+
+ if (!display || !subpicture)
+ return BadValue;
+
+ if (!(pI915Subpicture = subpicture->privData))
+ return XvMCBadSubpicture;
+
+ if (!(pI915XvMC = pI915Subpicture->privContext))
+ return XvMCBadSubpicture;
+
+ if (pI915Subpicture->last_render)
+ XvMCSyncSubpicture(display, subpicture);
+
+ if (pI915Subpicture->srf.map)
+ drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
+
+ PPTHREAD_MUTEX_LOCK();
+ XLockDisplay(display);
+ _xvmc_destroy_subpicture(display,subpicture);
+ XUnlockDisplay(display);
+
+ free(pI915Subpicture);
+ subpicture->privData = NULL;
+ pI915XvMC->ref--;
+ PPTHREAD_MUTEX_UNLOCK();
+
+ return Success;
+}
+
+
+Status i915_xvmc_set_subpict_palette(Display *display,
+ XvMCSubpicture *subpicture,
+ unsigned char *palette)
+{
+ i915XvMCSubpicture *pI915Subpicture;
+ int i, j;
+
+ if (!display || !subpicture)
+ return BadValue;
+
+ if (!(pI915Subpicture = subpicture->privData))
+ return XvMCBadSubpicture;
+
+ j = 0;
+ for (i = 0; i < 16; i++) {
+ pI915Subpicture->palette[0][i] = palette[j++];
+ pI915Subpicture->palette[1][i] = palette[j++];
+ pI915Subpicture->palette[2][i] = palette[j++];
+ }
+
+ /* FIXME: Update the subpicture with the new palette */
+ return Success;
+}
+
+Status i915_xvmc_blend_subpict(Display *display, XvMCSurface *target_surface,
+ XvMCSubpicture *subpicture,
+ short subx, short suby,
+ unsigned short subw, unsigned short subh,
+ short surfx, short surfy,
+ unsigned short surfw, unsigned short surfh)
+{
+ i915XvMCSubpicture *pI915Subpicture;
+ i915XvMCSurface *privTargetSurface;
+
+ if (!display || !target_surface)
+ return BadValue;
+
+ if (!(privTargetSurface = target_surface->privData))
+ return XvMCBadSurface;
+
+ if (subpicture) {
+ if (!(pI915Subpicture = subpicture->privData))
+ return XvMCBadSubpicture;
+
+ if ((FOURCC_AI44 != subpicture->xvimage_id) &&
+ (FOURCC_IA44 != subpicture->xvimage_id))
+ return XvMCBadSubpicture;
+
+ privTargetSurface->privSubPic = pI915Subpicture;
+ } else {
+ privTargetSurface->privSubPic = NULL;
+ }
+
+ return Success;
+}
+
+Status i915_xvmc_blend_subpict2(Display *display,
+ XvMCSurface *source_surface,
+ XvMCSurface *target_surface,
+ XvMCSubpicture *subpicture,
+ short subx, short suby,
+ unsigned short subw, unsigned short subh,
+ short surfx, short surfy,
+ unsigned short surfw, unsigned short surfh)
+{
+ i915XvMCContext *pI915XvMC;
+ i915XvMCSubpicture *pI915Subpicture;
+ i915XvMCSurface *privSourceSurface;
+ i915XvMCSurface *privTargetSurface;
+
+ if (!display || !source_surface || !target_surface)
+ return BadValue;
+
+ if (!(privSourceSurface = source_surface->privData))
+ return XvMCBadSurface;
+
+ if (!(privTargetSurface = target_surface->privData))
+ return XvMCBadSurface;
+
+ if (!(pI915XvMC = privTargetSurface->privContext))
+ return XvMCBadSurface;
+
+ if (((surfx + surfw) > privTargetSurface->width) ||
+ ((surfy + surfh) > privTargetSurface->height))
+ return BadValue;
+
+ if ((privSourceSurface->width != privTargetSurface->width) ||
+ (privTargetSurface->height != privTargetSurface->height))
+ return BadValue;
+
+ if (XvMCSyncSurface(display, source_surface))
+ return BadValue;
+
+ /* FIXME: update Target Surface */
+
+ if (subpicture) {
+ if (((subx + subw) > subpicture->width) ||
+ ((suby + subh) > subpicture->height))
+ return BadValue;
+
+ if (!(pI915Subpicture = subpicture->privData))
+ return XvMCBadSubpicture;
+
+ if ((FOURCC_AI44 != subpicture->xvimage_id) &&
+ (FOURCC_IA44 != subpicture->xvimage_id))
+ return XvMCBadSubpicture;
+
+ privTargetSurface->privSubPic = pI915Subpicture;
+ } else {
+ privTargetSurface->privSubPic = NULL;
+ }
+
+ return Success;
+}
+
+Status i915_xvmc_sync_subpict(Display *display, XvMCSubpicture *subpicture)
+{
+ Status ret;
+ int stat = 0;
+
+ if (!display || !subpicture)
+ return BadValue;
+
+ do {
+ ret = XvMCGetSubpictureStatus(display, subpicture, &stat);
+ } while(!ret && (stat & XVMC_RENDERING));
+
+ return ret;
+}
+
+Status i915_xvmc_flush_subpict(Display *display, XvMCSubpicture *subpicture)
+{
+ i915XvMCSubpicture *pI915Subpicture;
+
+ if (!display || !subpicture)
+ return BadValue;
+
+ if (!(pI915Subpicture = subpicture->privData))
+ return XvMCBadSubpicture;
+
+ return Success;
+}
+
+Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture,
+ int *stat)
+{
+ i915XvMCSubpicture *pI915Subpicture;
+ i915XvMCContext *pI915XvMC;
+
+ if (!display || !subpicture || stat)
+ return BadValue;
+
+ *stat = 0;
+
+ if (!(pI915Subpicture = subpicture->privData))
+ return XvMCBadSubpicture;
+
+ if (!(pI915XvMC = pI915Subpicture->privContext))
+ return XvMCBadSubpicture;
+
+ PPTHREAD_MUTEX_LOCK();
+ /* FIXME: */
+ if (pI915Subpicture->last_render &&
+ (pI915Subpicture->last_render > pI915XvMC->sarea->last_dispatch)) {
+ *stat |= XVMC_RENDERING;
+ }
+
+ PPTHREAD_MUTEX_UNLOCK();
+ return Success;
+}
+
+#endif
+
+struct _intel_xvmc_driver i915_xvmc_mc_driver = {
+ .type = XVMC_I915_MPEG2_MC,
+ .num_ctx = 0,
+ .ctx_list = NULL,
+ .create_context = i915_xvmc_mc_create_context,
+ .destroy_context = i915_xvmc_mc_destroy_context,
+ .create_surface = i915_xvmc_mc_create_surface,
+ .destroy_surface = i915_xvmc_mc_destroy_surface,
+ .render_surface = i915_xvmc_mc_render_surface,
+ .put_surface = i915_xvmc_mc_put_surface,
+ .get_surface_status = i915_xvmc_mc_get_surface_status,
+};
diff --git a/src/xvmc/i915_xvmc.h b/src/xvmc/i915_xvmc.h
new file mode 100644
index 00000000..af0a77da
--- /dev/null
+++ b/src/xvmc/i915_xvmc.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Xiang Haihao <haihao.xiang@intel.com>
+ *
+ */
+
+#ifndef _I915XVMC_H
+#define _I915XVMC_H
+
+#include "intel_xvmc.h"
+#include "i915_hwmc.h"
+
+#define I915_SUBPIC_PALETTE_SIZE 16
+#define MAX_SUBCONTEXT_LEN 1024
+
+#define PCI_CHIP_I915_G 0x2582
+#define PCI_CHIP_I915_GM 0x2592
+#define PCI_CHIP_I945_G 0x2772
+#define PCI_CHIP_I945_GM 0x27A2
+#define PCI_CHIP_I945_GME 0x27AE
+#define PCI_CHIP_G33_G 0x29C2
+#define PCI_CHIP_Q35_G 0x29B2
+#define PCI_CHIP_Q33_G 0x29D2
+
+/*
+ * i915XvMCContext:
+ * Private Context data referenced via the privData
+ * pointer in the XvMCContext structure.
+ */
+typedef struct _i915XvMCContext {
+ unsigned int ctxno;
+ unsigned int last_flip;
+ unsigned int dual_prime; /* Flag to identify when dual prime is in use. */
+ unsigned int yStride;
+ unsigned int uvStride;
+ unsigned short ref;
+ volatile drmI830Sarea *sarea;
+ unsigned int sarea_priv_offset; /* Offset in sarea to private part */
+ unsigned int depth;
+ XvPortID port; /* Xv Port ID when displaying */
+ int haveXv; /* Have I initialized the Xv
+ * connection for this surface? */
+ XvImage *xvImage; /* Fake Xv Image used for command
+ * buffer transport to the X server */
+ GC gc; /* X GC needed for displaying */
+ Drawable draw; /* Drawable to undisplay from */
+ void *drawHash;
+ int deviceID;
+
+ intel_xvmc_drm_map_t sis;
+ intel_xvmc_drm_map_t msb;
+ intel_xvmc_drm_map_t ssb;
+ intel_xvmc_drm_map_t psp;
+ intel_xvmc_drm_map_t psc;
+ intel_xvmc_drm_map_t corrdata;
+} i915XvMCContext;
+
+/*
+ * i915XvMCSubpicture:
+ * Private data structure for each XvMCSubpicture. This
+ * structure is referenced by the privData pointer in the XvMCSubpicture
+ * structure.
+ */
+typedef struct _i915XvMCSubpicture {
+ unsigned int srfNo;
+ unsigned int last_render;
+ unsigned int last_flip;
+ unsigned int pitch;
+ unsigned char palette[3][16];
+ intel_xvmc_drm_map_t srf;
+ i915XvMCContext *privContext;
+} i915XvMCSubpicture;
+
+/* Number of YUV buffers per surface */
+#define I830_MAX_BUFS 2
+
+/*
+ * i915XvMCSurface: Private data structure for each XvMCSurface. This
+ * structure is referenced by the privData pointer in the XvMCSurface
+ * structure.
+ */
+typedef struct _i915XvMCSurface {
+ unsigned int srfNo; /* XvMC private surface numbers */
+ unsigned int last_render;
+ unsigned int last_flip;
+ unsigned int yStride; /* Stride of YUV420 Y component. */
+ unsigned int uvStride;
+ unsigned int width; /* Dimensions */
+ unsigned int height;
+ intel_xvmc_drm_map_t srf;
+ i915XvMCContext *privContext;
+ i915XvMCSubpicture *privSubPic; /* Subpicture to be blended when
+ * displaying. NULL if none. */
+} i915XvMCSurface;
+
+#endif /* _I915XVMC_H */
diff --git a/src/xvmc/intel_batchbuffer.c b/src/xvmc/intel_batchbuffer.c
new file mode 100644
index 00000000..a3f82ff1
--- /dev/null
+++ b/src/xvmc/intel_batchbuffer.c
@@ -0,0 +1,271 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+#include <assert.h>
+
+#include <sys/ioctl.h>
+#include <X11/Xlibint.h>
+#include <fourcc.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XvMC.h>
+#include <X11/extensions/XvMClib.h>
+
+#include "intel_xvmc.h"
+#include "intel_batchbuffer.h"
+
+#define MI_BATCH_BUFFER_END (0xA << 23)
+
+int intelEmitIrqLocked(void)
+{
+ drmI830IrqEmit ie;
+ int ret, seq;
+
+ ie.irq_seq = &seq;
+ ret = drmCommandWriteRead(xvmc_driver->fd, DRM_I830_IRQ_EMIT,
+ &ie, sizeof(ie));
+
+ if ( ret ) {
+ fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret);
+ exit(1);
+ }
+
+ return seq;
+}
+
+void intelWaitIrq(int seq)
+{
+ int ret;
+ drmI830IrqWait iw;
+
+ iw.irq_seq = seq;
+
+ do {
+ ret = drmCommandWrite(xvmc_driver->fd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
+ } while (ret == -EAGAIN || ret == -EINTR);
+
+ if (ret) {
+ fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret);
+ exit(1);
+ }
+}
+
+static void intelDestroyBatchBuffer(void)
+{
+ if (xvmc_driver->alloc.offset) {
+ xvmc_driver->alloc.ptr = NULL;
+ xvmc_driver->alloc.offset = 0;
+ } else if (xvmc_driver->alloc.ptr) {
+ free(xvmc_driver->alloc.ptr);
+ xvmc_driver->alloc.ptr = NULL;
+ }
+
+ memset(&xvmc_driver->batch, 0, sizeof(xvmc_driver->batch));
+}
+
+
+Bool intelInitBatchBuffer(void)
+{
+ if (drmMap(xvmc_driver->fd,
+ xvmc_driver->batchbuffer.handle,
+ xvmc_driver->batchbuffer.size,
+ (drmAddress *)&xvmc_driver->batchbuffer.map) != 0) {
+ XVMC_ERR("fail to map batch buffer\n");
+ return False;
+ }
+
+ if (xvmc_driver->batchbuffer.map) {
+ xvmc_driver->alloc.size = xvmc_driver->batchbuffer.size;
+ xvmc_driver->alloc.offset = xvmc_driver->batchbuffer.offset;
+ xvmc_driver->alloc.ptr = xvmc_driver->batchbuffer.map;
+ } else {
+ xvmc_driver->alloc.size = 8 * 1024;
+ xvmc_driver->alloc.offset = 0;
+ xvmc_driver->alloc.ptr = malloc(xvmc_driver->alloc.size);
+ }
+
+ xvmc_driver->alloc.active_buf = 0;
+ assert(xvmc_driver->alloc.ptr);
+}
+
+void intelFiniBatchBuffer(void)
+{
+ if (xvmc_driver->batchbuffer.map) {
+ drmUnmap(xvmc_driver->batchbuffer.map, xvmc_driver->batchbuffer.size);
+ xvmc_driver->batchbuffer.map = NULL;
+ }
+ intelDestroyBatchBuffer();
+}
+
+void intelBatchbufferRequireSpace(unsigned int sz)
+{
+ if (xvmc_driver->batch.space < sz)
+ intelFlushBatch(TRUE);
+}
+
+void intelBatchbufferData(const void *data, unsigned bytes, unsigned flags)
+{
+ assert((bytes & 0x3) == 0);
+
+ intelBatchbufferRequireSpace(bytes);
+ memcpy(xvmc_driver->batch.ptr, data, bytes);
+ xvmc_driver->batch.ptr += bytes;
+ xvmc_driver->batch.space -= bytes;
+
+ assert(xvmc_driver->batch.space >= 0);
+}
+
+#define MI_FLUSH ((0 << 29) | (4 << 23))
+#define FLUSH_MAP_CACHE (1 << 0)
+#define FLUSH_RENDER_CACHE (0 << 2)
+#define FLUSH_WRITE_DIRTY_STATE (1 << 4)
+
+void intelRefillBatchLocked(Bool allow_unlock )
+{
+ unsigned half = xvmc_driver->alloc.size >> 1;
+ unsigned buf = (xvmc_driver->alloc.active_buf ^= 1);
+ unsigned dword[2];
+
+ dword[0] = MI_FLUSH | FLUSH_WRITE_DIRTY_STATE | FLUSH_RENDER_CACHE | FLUSH_MAP_CACHE;
+ dword[1] = 0;
+ intelCmdIoctl((char *)&dword[0], sizeof(dword));
+ xvmc_driver->alloc.irq_emitted = intelEmitIrqLocked();
+
+ if (xvmc_driver->alloc.irq_emitted) {
+ intelWaitIrq(xvmc_driver->alloc.irq_emitted);
+ }
+
+ xvmc_driver->batch.start_offset = xvmc_driver->alloc.offset + buf * half;
+ xvmc_driver->batch.ptr = (unsigned char *)xvmc_driver->alloc.ptr + buf * half;
+ xvmc_driver->batch.size = half - 8;
+ xvmc_driver->batch.space = half - 8;
+ assert(xvmc_driver->batch.space >= 0);
+}
+
+
+void intelFlushBatchLocked(Bool ignore_cliprects,
+ Bool refill,
+ Bool allow_unlock)
+{
+ drmI830BatchBuffer batch;
+
+ if (xvmc_driver->batch.space != xvmc_driver->batch.size) {
+
+ batch.start = xvmc_driver->batch.start_offset;
+ batch.used = xvmc_driver->batch.size - xvmc_driver->batch.space;
+ batch.cliprects = 0;
+ batch.num_cliprects = 0;
+ batch.DR1 = 0;
+ batch.DR4 = 0;
+
+ if (xvmc_driver->alloc.offset) {
+ if ((batch.used & 0x4) == 0) {
+ ((int *)xvmc_driver->batch.ptr)[0] = 0;
+ ((int *)xvmc_driver->batch.ptr)[1] = MI_BATCH_BUFFER_END;
+ batch.used += 0x8;
+ xvmc_driver->batch.ptr += 0x8;
+ } else {
+ ((int *)xvmc_driver->batch.ptr)[0] = MI_BATCH_BUFFER_END;
+ batch.used += 0x4;
+ xvmc_driver->batch.ptr += 0x4;
+ }
+ }
+
+ xvmc_driver->batch.start_offset += batch.used;
+ xvmc_driver->batch.size -= batch.used;
+
+ if (xvmc_driver->batch.size < 8) {
+ refill = TRUE;
+ xvmc_driver->batch.space = xvmc_driver->batch.size = 0;
+ }
+ else {
+ xvmc_driver->batch.size -= 8;
+ xvmc_driver->batch.space = xvmc_driver->batch.size;
+ }
+
+ assert(xvmc_driver->batch.space >= 0);
+ assert(batch.start >= xvmc_driver->alloc.offset);
+ assert(batch.start < xvmc_driver->alloc.offset + xvmc_driver->alloc.size);
+ assert(batch.start + batch.used > xvmc_driver->alloc.offset);
+ assert(batch.start + batch.used <= xvmc_driver->alloc.offset + xvmc_driver->alloc.size);
+
+ if (xvmc_driver->alloc.offset) {
+ if (drmCommandWrite(xvmc_driver->fd, DRM_I830_BATCHBUFFER, &batch, sizeof(batch))) {
+ fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno);
+ exit(1);
+ }
+ } else {
+ drmI830CmdBuffer cmd;
+ cmd.buf = (char *)xvmc_driver->alloc.ptr + batch.start;
+ cmd.sz = batch.used;
+ cmd.DR1 = batch.DR1;
+ cmd.DR4 = batch.DR4;
+ cmd.num_cliprects = batch.num_cliprects;
+ cmd.cliprects = batch.cliprects;
+
+ if (drmCommandWrite(xvmc_driver->fd, DRM_I830_CMDBUFFER,
+ &cmd, sizeof(cmd))) {
+ fprintf(stderr, "DRM_I915_CMDBUFFER: %d\n", -errno);
+ exit(1);
+ }
+ }
+ }
+
+ if (refill)
+ intelRefillBatchLocked(allow_unlock);
+}
+
+void intelFlushBatch(Bool refill )
+{
+ intelFlushBatchLocked(FALSE, refill, TRUE);
+}
+
+void intelCmdIoctl(char *buf, unsigned used)
+{
+ drmI830CmdBuffer cmd;
+
+ cmd.buf = buf;
+ cmd.sz = used;
+ cmd.cliprects = 0;
+ cmd.num_cliprects = 0;
+ cmd.DR1 = 0;
+ cmd.DR4 = 0;
+
+ if (drmCommandWrite(xvmc_driver->fd, DRM_I830_CMDBUFFER,
+ &cmd, sizeof(cmd))) {
+ fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n", -errno);
+ exit(1);
+ }
+}
diff --git a/src/xvmc/intel_batchbuffer.h b/src/xvmc/intel_batchbuffer.h
new file mode 100644
index 00000000..aec71e4a
--- /dev/null
+++ b/src/xvmc/intel_batchbuffer.h
@@ -0,0 +1,42 @@
+#ifndef _INTEL_BATCHBUFFER_H
+#define _INTEL_BATCHBUFFER_H
+
+/* #define VERBOSE 0 */
+#ifndef VERBOSE
+extern int VERBOSE;
+#endif
+
+#define BATCH_LOCALS char *batch_ptr;
+
+#define BEGIN_BATCH(n) \
+ do { \
+ if (VERBOSE) fprintf(stderr, \
+ "BEGIN_BATCH(%ld) in %s, %d dwords free\n", \
+ ((unsigned long)n), __FUNCTION__, \
+ xvmc_driver->batch.space/4); \
+ if (xvmc_driver->batch.space < (n)*4) \
+ intelFlushBatch(TRUE); \
+ batch_ptr = xvmc_driver->batch.ptr; \
+ } while (0)
+
+#define OUT_BATCH(n) \
+ do { \
+ *(GLuint *)batch_ptr = (n); \
+ if (VERBOSE) fprintf(stderr, " -- %08x at %s/%d\n", (n), __FILE__, __LINE__); \
+ batch_ptr += 4; \
+ } while (0)
+
+#define ADVANCE_BATCH() \
+ do { \
+ if (VERBOSE) fprintf(stderr, "ADVANCE_BATCH()\n"); \
+ xvmc_driver->batch.space -= (batch_ptr - xvmc_driver->batch.ptr); \
+ xvmc_driver->batch.ptr = batch_ptr; \
+ assert(xvmc_driver->batch.space >= 0); \
+ } while(0)
+
+extern void intelFlushBatch(Bool);
+extern void intelBatchbufferData(const void *, unsigned, unsigned);
+extern Bool intelInitBatchBuffer(void);
+extern void intelFiniBatchBuffer(void);
+extern void intelCmdIoctl(char *, unsigned);
+#endif /* _INTEL_BATCHBUFFER_H */
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
new file mode 100644
index 00000000..489a2c2c
--- /dev/null
+++ b/src/xvmc/intel_xvmc.c
@@ -0,0 +1,1069 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Zhenyu Wang <zhenyu.z.wang@intel.com>
+ *
+ */
+#include "intel_xvmc.h"
+
+struct _intel_xvmc_driver *xvmc_driver = NULL;
+static int error_base;
+static int event_base;
+
+/* locking */
+static void intel_xvmc_try_heavy_lock(drm_context_t ctx)
+{
+ drmGetLock(xvmc_driver->fd, ctx, 0);
+}
+
+void LOCK_HARDWARE(drm_context_t ctx)
+{
+ char __ret = 0;
+
+ PPTHREAD_MUTEX_LOCK();
+ assert(!xvmc_driver->locked);
+
+ DRM_CAS(xvmc_driver->driHwLock, ctx,
+ (DRM_LOCK_HELD | ctx), __ret);
+
+ if (__ret)
+ intel_xvmc_try_heavy_lock(ctx);
+
+ xvmc_driver->locked = 1;
+}
+
+void UNLOCK_HARDWARE(drm_context_t ctx)
+{
+ xvmc_driver->locked = 0;
+ DRM_UNLOCK(xvmc_driver->fd, xvmc_driver->driHwLock, ctx);
+ PPTHREAD_MUTEX_UNLOCK();
+}
+
+static intel_xvmc_context_ptr intel_xvmc_new_context(Display *dpy)
+{
+ intel_xvmc_context_ptr ret;
+
+ ret = (intel_xvmc_context_ptr)calloc(1, sizeof(intel_xvmc_context_t));
+ if (!ret)
+ return NULL;
+
+ if (!xvmc_driver->ctx_list)
+ ret->next = NULL;
+ else
+ ret->next = xvmc_driver->ctx_list;
+ xvmc_driver->ctx_list = ret;
+ xvmc_driver->num_ctx++;
+
+ return ret;
+
+}
+
+static void intel_xvmc_free_context(XID id)
+{
+ intel_xvmc_context_ptr p = xvmc_driver->ctx_list;
+ intel_xvmc_context_ptr pre = p;
+
+ while(p) {
+ if (p->context && p->context->context_id == id) {
+ if (p == xvmc_driver->ctx_list)
+ xvmc_driver->ctx_list = p->next;
+ else
+ pre->next = p->next;
+ break;
+ }
+ pre = p;
+ p = p->next;
+ }
+
+ if (p) {
+ free(p);
+ xvmc_driver->num_ctx--;
+ }
+}
+
+intel_xvmc_context_ptr intel_xvmc_find_context(XID id)
+{
+ intel_xvmc_context_ptr p = xvmc_driver->ctx_list;
+
+ while(p) {
+ if (p->context && p->context->context_id == id)
+ return p;
+ p = p->next;
+ }
+ return NULL;
+}
+
+static intel_xvmc_surface_ptr intel_xvmc_new_surface(Display *dpy)
+{
+ intel_xvmc_surface_ptr ret;
+
+ ret = (intel_xvmc_surface_ptr)calloc(1, sizeof(intel_xvmc_surface_t));
+ if (!ret)
+ return NULL;
+
+ if (!xvmc_driver->surf_list)
+ ret->next = NULL;
+ else
+ ret->next = xvmc_driver->surf_list;
+ xvmc_driver->surf_list = ret;
+ xvmc_driver->num_surf++;
+
+ ret->image = NULL;
+ ret->gc_init = FALSE;
+
+ return ret;
+
+}
+
+static void intel_xvmc_free_surface(XID id)
+{
+ intel_xvmc_surface_ptr p = xvmc_driver->surf_list;
+ intel_xvmc_surface_ptr pre = p;
+
+ while(p) {
+ if (p->surface && p->surface->surface_id == id) {
+ if (p == xvmc_driver->surf_list)
+ xvmc_driver->surf_list = p->next;
+ else
+ pre->next = p->next;
+ break;
+ }
+ pre = p;
+ p = p->next;
+ }
+
+ if (p) {
+ free(p);
+ xvmc_driver->num_surf--;
+ }
+}
+
+intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id)
+{
+ intel_xvmc_surface_ptr p = xvmc_driver->surf_list;
+
+ while(p) {
+ if (p->surface && p->surface->surface_id == id)
+ return p;
+ p = p->next;
+ }
+ return NULL;
+}
+/*
+* Function: XvMCCreateContext
+* Description: Create a XvMC context for the given surface parameters.
+* Arguments:
+* display - Connection to the X server.
+* port - XvPortID to use as avertised by the X connection.
+* surface_type_id - Unique identifier for the Surface type.
+* width - Width of the surfaces.
+* height - Height of the surfaces.
+* flags - one or more of the following
+* XVMC_DIRECT - A direct rendered context is requested.
+*
+* Notes: surface_type_id and width/height parameters must match those
+* returned by XvMCListSurfaceTypes.
+* Returns: Status
+*/
+Status XvMCCreateContext(Display *display, XvPortID port,
+ int surface_type_id, int width, int height,
+ int flags, XvMCContext *context)
+{
+ Status ret;
+ drm_sarea_t *pSAREA;
+ char *curBusID;
+ CARD32 *priv_data = NULL;
+ struct _intel_xvmc_common *comm;
+ drm_magic_t magic;
+ int major, minor;
+ int priv_count;
+ int isCapable;
+ int screen = DefaultScreen(display);
+ intel_xvmc_context_ptr intel_ctx;
+ int fd;
+
+ /* Verify Obvious things first */
+ if (!display || !context)
+ return BadValue;
+
+ if (!(flags & XVMC_DIRECT)) {
+ XVMC_ERR("Indirect Rendering not supported! Using Direct.");
+ return BadValue;
+ }
+
+ /* Open DRI Device */
+ if((fd = drmOpen("i915", NULL)) < 0) {
+ XVMC_ERR("DRM Device could not be opened.");
+ return BadValue;
+ }
+
+ /*
+ Width, Height, and flags are checked against surface_type_id
+ and port for validity inside the X server, no need to check
+ here.
+ */
+ context->surface_type_id = surface_type_id;
+ context->width = (unsigned short)((width + 15) & ~15);
+ context->height = (unsigned short)((height + 15) & ~15);
+ context->flags = flags;
+ context->port = port;
+
+ if (!XvMCQueryExtension(display, &event_base, &error_base)) {
+ XVMC_ERR("XvMCExtension is not available!");
+ return BadValue;
+ }
+ ret = XvMCQueryVersion(display, &major, &minor);
+ if (ret) {
+ XVMC_ERR("XvMCQueryVersion Failed, unable to determine protocol version.");
+ return ret;
+ }
+
+ /* XXX: major and minor could be checked in future for XvMC
+ * protocol capability (i.e H.264/AVC decode available)
+ */
+
+ /*
+ Pass control to the X server to create a drm_context_t for us and
+ validate the with/height and flags.
+ */
+ if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) {
+ XVMC_ERR("Unable to create XvMC Context.");
+ return ret;
+ }
+ XVMC_DBG("new context %d created\n", context->context_id);
+
+ comm = (struct _intel_xvmc_common *)priv_data;
+
+ if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
+ switch (comm->type) {
+ case XVMC_I915_MPEG2_MC:
+ xvmc_driver = &i915_xvmc_mc_driver;
+ break;
+ case XVMC_I965_MPEG2_MC:
+ case XVMC_I945_MPEG2_VLD:
+ case XVMC_I965_MPEG2_VLD:
+ default:
+ XVMC_ERR("unimplemented xvmc type %d", comm->type);
+ XFree(priv_data);
+ priv_data = NULL;
+ return BadValue;
+ }
+ }
+
+ if (xvmc_driver == NULL || xvmc_driver->type != comm->type) {
+ XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type);
+ return BadValue;
+ }
+
+ xvmc_driver->fd = fd;
+
+ XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type));
+
+ xvmc_driver->sarea_size = comm->sarea_size;
+ xvmc_driver->batchbuffer.handle = comm->batchbuffer.handle;
+ xvmc_driver->batchbuffer.offset = comm->batchbuffer.offset;
+ xvmc_driver->batchbuffer.size = comm->batchbuffer.size;
+
+ /* assign local ctx info */
+ intel_ctx = intel_xvmc_new_context(display);
+ if (!intel_ctx) {
+ XVMC_ERR("Intel XvMC context create fail\n");
+ return BadAlloc;
+ }
+ intel_ctx->context = context;
+
+ ret = uniDRIQueryDirectRenderingCapable(display, screen,
+ &isCapable);
+ if (!ret || !isCapable) {
+ XVMC_ERR("Direct Rendering is not available on this system!");
+ XFree(priv_data);
+ return BadValue;
+ }
+
+ if (!uniDRIOpenConnection(display, screen,
+ &xvmc_driver->hsarea, &curBusID)) {
+ XVMC_ERR("Could not open DRI connection to X server!");
+ XFree(priv_data);
+ return BadValue;
+ }
+
+ strncpy(xvmc_driver->busID, curBusID, 20);
+ xvmc_driver->busID[20] = '\0';
+ XFree(curBusID);
+
+ /* Get magic number */
+ drmGetMagic(xvmc_driver->fd, &magic);
+ // context->flags = (unsigned long)magic;
+
+ if (!uniDRIAuthConnection(display, screen, magic)) {
+ XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions.");
+ xvmc_driver = NULL;
+ XFree(priv_data);
+ return BadAlloc;
+ }
+
+ /*
+ * Map DRI Sarea. we always want it right?
+ */
+ if (drmMap(xvmc_driver->fd, xvmc_driver->hsarea,
+ xvmc_driver->sarea_size, &xvmc_driver->sarea_address) < 0) {
+ XVMC_ERR("Unable to map DRI SAREA.\n");
+ xvmc_driver = NULL;
+ XFree(priv_data);
+ return BadAlloc;
+ }
+ pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address;
+ xvmc_driver->driHwLock = (drmLock *)&pSAREA->lock;
+ pthread_mutex_init(&xvmc_driver->ctxmutex, NULL);
+
+ /* context_id is alloc in _xvmc_create_context */
+ if (!uniDRICreateContext(display, screen, DefaultVisual(display, screen),
+ context->context_id,
+ &intel_ctx->hw_context)) {
+ XVMC_ERR("Could not create DRI context for xvmc ctx %d.",
+ context->context_id);
+ XFree(priv_data);
+ context->privData = NULL;
+ drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+ return BadAlloc;
+ }
+
+ /* call driver hook.
+ * driver hook should free priv_data after return if success.*/
+ ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data);
+ if (ret) {
+ XVMC_ERR("driver create context failed\n");
+ XFree(priv_data);
+ drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+ return ret;
+ }
+
+ intelInitBatchBuffer();
+
+ return Success;
+}
+
+/*
+ * Function: XvMCDestroyContext
+ * Description: Destorys the specified context.
+ *
+ * Arguments:
+ * display - Specifies the connection to the server.
+ * context - The context to be destroyed.
+ *
+ */
+Status XvMCDestroyContext(Display *display, XvMCContext *context)
+{
+ Status ret;
+ int screen = DefaultScreen(display);
+
+ if (!display || !context)
+ return XvMCBadContext;
+
+ ret = (xvmc_driver->destroy_context)(display, context);
+ if (ret) {
+ XVMC_ERR("destroy context fail\n");
+ return ret;
+ }
+
+ uniDRIDestroyContext(display, screen, context->context_id);
+ intel_xvmc_free_context(context->context_id);
+
+ ret = _xvmc_destroy_context(display, context);
+ if (ret != Success) {
+ XVMC_ERR("_xvmc_destroy_context fail\n");
+ return ret;
+ }
+
+ if (xvmc_driver->num_ctx == 0) {
+ uniDRICloseConnection(display, screen);
+
+ pthread_mutex_destroy(&xvmc_driver->ctxmutex);
+
+ drmUnmap(xvmc_driver->sarea_address, xvmc_driver->sarea_size);
+
+ if (xvmc_driver->fd >= 0)
+ drmClose(xvmc_driver->fd);
+ xvmc_driver->fd = -1;
+
+ intelFiniBatchBuffer();
+ }
+ return Success;
+}
+
+/*
+ * Function: XvMCCreateSurface
+ */
+Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface)
+{
+ Status ret;
+ int priv_count;
+ CARD32 *priv_data;
+ intel_xvmc_surface_ptr intel_surf = NULL;
+
+ if (!display || !context)
+ return XvMCBadContext;
+
+ if (!surface)
+ return XvMCBadSurface;
+
+ intel_surf = intel_xvmc_new_surface(display);
+ if (!intel_surf)
+ return BadAlloc;
+ intel_surf->surface = surface;
+
+ if ((ret = _xvmc_create_surface(display, context, surface,
+ &priv_count, &priv_data))) {
+ XVMC_ERR("Unable to create XvMCSurface.");
+ return ret;
+ }
+
+ intel_surf->image = XvCreateImage(display, context->port,
+ FOURCC_XVMC, (char *)&intel_surf->data, surface->width,
+ surface->height);
+ if (!intel_surf->image) {
+ XVMC_ERR("Can't create XvImage for surface\n");
+ _xvmc_destroy_surface(display, surface);
+ intel_xvmc_free_surface(surface->surface_id);
+ return BadAlloc;
+ }
+ intel_surf->image->data = (char *)&intel_surf->data;
+
+ ret = (xvmc_driver->create_surface)(display, context, surface, priv_count,
+ priv_data);
+ if (ret) {
+ XVMC_ERR("create surface failed\n");
+ return ret;
+ }
+
+ return Success;
+}
+
+
+/*
+ * Function: XvMCDestroySurface
+ */
+Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
+{
+ intel_xvmc_surface_ptr intel_surf;
+
+ if (!display || !surface)
+ return XvMCBadSurface;
+
+ intel_surf = intel_xvmc_find_surface(surface->surface_id);
+ if (!intel_surf)
+ return XvMCBadSurface;
+
+ XFree(intel_surf->image);
+ if (intel_surf->gc_init)
+ XFreeGC(display, intel_surf->gc);
+ intel_xvmc_free_surface(surface->surface_id);
+
+ (xvmc_driver->destroy_surface)(display, surface);
+
+ _xvmc_destroy_surface(display, surface);
+
+ return Success;
+}
+
+/*
+ * Function: XvMCCreateBlocks
+ */
+Status XvMCCreateBlocks(Display *display, XvMCContext *context,
+ unsigned int num_blocks,
+ XvMCBlockArray *block)
+{
+ if (!display || !context || !num_blocks || !block)
+ return BadValue;
+
+ memset(block, 0, sizeof(XvMCBlockArray));
+
+ if (!(block->blocks = (short *)malloc(num_blocks << 6 * sizeof(short))))
+ return BadAlloc;
+
+ block->num_blocks = num_blocks;
+ block->context_id = context->context_id;
+ block->privData = NULL;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCDestroyBlocks
+ */
+Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block)
+{
+ if (!display || block)
+ return BadValue;
+
+ if (block->blocks)
+ free(block->blocks);
+
+ block->context_id = 0;
+ block->num_blocks = 0;
+ block->blocks = NULL;
+ block->privData = NULL;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCCreateMacroBlocks
+ */
+Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context,
+ unsigned int num_blocks,
+ XvMCMacroBlockArray *blocks)
+{
+ if (!display || !context || !blocks || !num_blocks)
+ return BadValue;
+
+ memset(blocks, 0, sizeof(XvMCMacroBlockArray));
+ blocks->macro_blocks = (XvMCMacroBlock *)malloc(num_blocks * sizeof(XvMCMacroBlock));
+
+ if (!blocks->macro_blocks)
+ return BadAlloc;
+
+ blocks->num_blocks = num_blocks;
+ blocks->context_id = context->context_id;
+ blocks->privData = NULL;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCDestroyMacroBlocks
+ */
+Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block)
+{
+ if (!display || !block)
+ return BadValue;
+ if (block->macro_blocks)
+ free(block->macro_blocks);
+
+ block->context_id = 0;
+ block->num_blocks = 0;
+ block->macro_blocks = NULL;
+ block->privData = NULL;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCRenderSurface
+ *
+ * Description: This function does the actual HWMC. Given a list of
+ * macroblock structures it dispatched the hardware commands to execute
+ * them.
+ */
+Status XvMCRenderSurface(Display *display, XvMCContext *context,
+ unsigned int picture_structure,
+ XvMCSurface *target_surface,
+ XvMCSurface *past_surface,
+ XvMCSurface *future_surface,
+ unsigned int flags,
+ unsigned int num_macroblocks,
+ unsigned int first_macroblock,
+ XvMCMacroBlockArray *macroblock_array,
+ XvMCBlockArray *blocks)
+{
+ Status ret;
+
+ if (!display || !context) {
+ XVMC_ERR("Invalid Display, Context or Target!");
+ return XvMCBadContext;
+ }
+ if (!target_surface)
+ return XvMCBadSurface;
+
+ ret = (xvmc_driver->render_surface)(display, context, picture_structure,
+ target_surface, past_surface, future_surface, flags,
+ num_macroblocks, first_macroblock, macroblock_array,
+ blocks);
+
+ if (ret) {
+ XVMC_ERR("render surface fail\n");
+ return ret;
+ }
+ return Success;
+}
+
+/*
+ * Function: XvMCPutSurface
+ *
+ * Description:
+ * Arguments:
+ * display: Connection to X server
+ * surface: Surface to be displayed
+ * draw: X Drawable on which to display the surface
+ * srcx: X coordinate of the top left corner of the region to be
+ * displayed within the surface.
+ * srcy: Y coordinate of the top left corner of the region to be
+ * displayed within the surface.
+ * srcw: Width of the region to be displayed.
+ * srch: Height of the region to be displayed.
+ * destx: X cordinate of the top left corner of the destination region
+ * in the drawable coordinates.
+ * desty: Y cordinate of the top left corner of the destination region
+ * in the drawable coordinates.
+ * destw: Width of the destination region.
+ * desth: Height of the destination region.
+ * flags: One or more of the following.
+ * XVMC_TOP_FIELD - Display only the Top field of the surface.
+ * XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
+ * XVMC_FRAME_PICTURE - Display both fields or frame.
+ */
+Status XvMCPutSurface(Display *display,XvMCSurface *surface,
+ Drawable draw, short srcx, short srcy,
+ unsigned short srcw, unsigned short srch,
+ short destx, short desty,
+ unsigned short destw, unsigned short desth,
+ int flags)
+{
+ Status ret = Success;
+ XvMCContext *context;
+ intel_xvmc_context_ptr intel_ctx;
+ intel_xvmc_surface_ptr intel_surf;
+
+ if (!display || !surface)
+ return XvMCBadSurface;
+
+ intel_ctx = intel_xvmc_find_context(surface->context_id);
+ intel_surf = intel_xvmc_find_surface(surface->surface_id);
+ if (!intel_ctx || !intel_surf)
+ return XvMCBadSurface;
+ context = intel_ctx->context;
+
+ if (intel_surf->gc_init == FALSE) {
+ intel_surf->gc = XCreateGC(display, draw, 0, NULL);
+ intel_surf->gc_init = TRUE;
+ } else if (draw != intel_surf->last_draw) {
+ XFreeGC(display, intel_surf->gc);
+ intel_surf->gc = XCreateGC(display, draw, 0, NULL);
+ }
+ intel_surf->last_draw = draw;
+
+ /* fill intel_surf->data */
+ ret = (xvmc_driver->put_surface)(display, surface, draw, srcx, srcy,
+ srcw, srch, destx, desty, destw, desth, flags, &intel_surf->data);
+ if (ret) {
+ XVMC_ERR("put surface fail\n");
+ return ret;
+ }
+
+ ret = XvPutImage(display, context->port, draw, intel_surf->gc,
+ intel_surf->image, srcx, srcy, srcw, srch, destx, desty,
+ destw, desth);
+
+ return ret;
+}
+
+/*
+ * Function: XvMCSyncSurface
+ * Arguments:
+ * display - Connection to the X server
+ * surface - The surface to synchronize
+ */
+Status XvMCSyncSurface(Display *display, XvMCSurface *surface)
+{
+ Status ret;
+ int stat = 0;
+
+ if (!display || !surface)
+ return XvMCBadSurface;
+
+ do {
+ ret = XvMCGetSurfaceStatus(display, surface, &stat);
+ } while (!ret && (stat & XVMC_RENDERING));
+
+ return ret;
+}
+
+/*
+ * Function: XvMCFlushSurface
+ * Description:
+ * This function commits pending rendering requests to ensure that they
+ * wll be completed in a finite amount of time.
+ * Arguments:
+ * display - Connection to X server
+ * surface - Surface to flush
+ * Returns: Status
+ */
+Status XvMCFlushSurface(Display * display, XvMCSurface *surface)
+{
+ if (!display || !surface)
+ return XvMCBadSurface;
+ return Success;
+}
+
+/*
+ * Function: XvMCGetSurfaceStatus
+ * Description:
+ * Arguments:
+ * display: connection to X server
+ * surface: The surface to query
+ * stat: One of the Following
+ * XVMC_RENDERING - The last XvMCRenderSurface command has not
+ * completed.
+ * XVMC_DISPLAYING - The surface is currently being displayed or a
+ * display is pending.
+ */
+Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat)
+{
+ Status ret;
+
+ if (!display || !surface || !stat)
+ return XvMCBadSurface;
+
+ ret = (xvmc_driver->get_surface_status)(display, surface, stat);
+ if (ret) {
+ XVMC_ERR("get surface status fail\n");
+ return ret;
+ }
+
+ return Success;
+}
+
+/*
+ * Function: XvMCHideSurface
+ * Description: Stops the display of a surface.
+ * Arguments:
+ * display - Connection to the X server.
+ * surface - surface to be hidden.
+ *
+ * Returns: Status
+ */
+Status XvMCHideSurface(Display *display, XvMCSurface *surface)
+{
+ int stat = 0;
+ Status ret;
+
+ if (!display || !surface)
+ return XvMCBadSurface;
+
+ XvMCSyncSurface(display, surface);
+
+ /*
+ Get the status of the surface, if it is not currently displayed
+ we don't need to worry about it.
+ */
+ if ((ret = XvMCGetSurfaceStatus(display, surface, &stat)) != Success)
+ return ret;
+
+ if (!(stat & XVMC_DISPLAYING))
+ return Success;
+
+ /* FIXME: */
+ XVMC_ERR("XvMCHideSurface not implemented!\n");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCCreateSubpicture
+ * Description: This creates a subpicture by filling out the XvMCSubpicture
+ * structure passed to it and returning Success.
+ * Arguments:
+ * display - Connection to the X server.
+ * context - The context to create the subpicture for.
+ * subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
+ * width - of subpicture
+ * height - of subpicture
+ * xvimage_id - The id describing the XvImage format.
+ *
+ * Returns: Status
+ */
+Status XvMCCreateSubpicture(Display *display, XvMCContext *context,
+ XvMCSubpicture *subpicture,
+ unsigned short width, unsigned short height,
+ int xvimage_id)
+{
+ XVMC_ERR("XvMCCreateSubpicture not implemented!\n");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCClearSubpicture
+ * Description: Clear the area of the given subpicture to "color".
+ * structure passed to it and returning Success.
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - Subpicture to clear.
+ * x, y, width, height - rectangle in the subpicture to clear.
+ * color - The data to file the rectangle with.
+ *
+ * Returns: Status
+ */
+Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture,
+ short x, short y,
+ unsigned short width, unsigned short height,
+ unsigned int color)
+{
+ XVMC_ERR("XvMCClearSubpicture not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCCompositeSubpicture
+ * Description: Composite the XvImae on the subpicture. This composit uses
+ * non-premultiplied alpha. Destination alpha is utilized
+ * except for with indexed subpictures. Indexed subpictures
+ * use a simple "replace".
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - Subpicture to clear.
+ * image - the XvImage to be used as the source of the composite.
+ * srcx, srcy, width, height - The rectangle from the image to be used.
+ * dstx, dsty - location in the subpicture to composite the source.
+ *
+ * Returns: Status
+ */
+Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture,
+ XvImage *image,
+ short srcx, short srcy,
+ unsigned short width, unsigned short height,
+ short dstx, short dsty)
+{
+ XVMC_ERR("XvMCCompositeSubpicture not implemented!");
+ return BadValue;
+}
+
+
+/*
+ * Function: XvMCDestroySubpicture
+ * Description: Destroys the specified subpicture.
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - Subpicture to be destroyed.
+ *
+ * Returns: Status
+ */
+Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
+{
+ XVMC_ERR("XvMCDestroySubpicture not implemented!");
+ return BadValue;
+}
+
+
+/*
+ * Function: XvMCSetSubpicturePalette
+ * Description: Set the subpictures palette
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - Subpiture to set palette for.
+ * palette - A pointer to an array holding the palette data. The array
+ * is num_palette_entries * entry_bytes in size.
+ * Returns: Status
+ */
+Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture,
+ unsigned char *palette)
+{
+ XVMC_ERR("XvMCSetSubpicturePalette not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCBlendSubpicture
+ * Description:
+ * The behavior of this function is different depending on whether
+ * or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+ * i915 only support frontend behavior.
+ *
+ * XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+ *
+ * XvMCBlendSubpicture is a no-op in this case.
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - The subpicture to be blended into the video.
+ * target_surface - The surface to be displayed with the blended subpic.
+ * source_surface - Source surface prior to blending.
+ * subx, suby, subw, subh - The rectangle from the subpicture to use.
+ * surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+ * blend the subpicture rectangle into. Scaling can ocure if
+ * XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+ *
+ * Returns: Status
+ */
+Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface,
+ XvMCSubpicture *subpicture,
+ short subx, short suby,
+ unsigned short subw, unsigned short subh,
+ short surfx, short surfy,
+ unsigned short surfw, unsigned short surfh)
+{
+ XVMC_ERR("XvMCBlendSubpicture not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCBlendSubpicture2
+ * Description:
+ * The behavior of this function is different depending on whether
+ * or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+ * i915 only supports frontend blending.
+ *
+ * XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+ *
+ * XvMCBlendSubpicture2 blends the source_surface and subpicture and
+ * puts it in the target_surface. This does not effect the status of
+ * the source surface but will cause the target_surface to query
+ * XVMC_RENDERING until the blend is completed.
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - The subpicture to be blended into the video.
+ * target_surface - The surface to be displayed with the blended subpic.
+ * source_surface - Source surface prior to blending.
+ * subx, suby, subw, subh - The rectangle from the subpicture to use.
+ * surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+ * blend the subpicture rectangle into. Scaling can ocure if
+ * XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+ *
+ * Returns: Status
+ */
+Status XvMCBlendSubpicture2(Display *display,
+ XvMCSurface *source_surface,
+ XvMCSurface *target_surface,
+ XvMCSubpicture *subpicture,
+ short subx, short suby,
+ unsigned short subw, unsigned short subh,
+ short surfx, short surfy,
+ unsigned short surfw, unsigned short surfh)
+{
+ XVMC_ERR("XvMCBlendSubpicture2 not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCSyncSubpicture
+ * Description: This function blocks until all composite/clear requests on
+ * the subpicture have been complete.
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - The subpicture to synchronize
+ *
+ * Returns: Status
+ */
+Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture)
+{
+ XVMC_ERR("XvMCSyncSubpicture not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCFlushSubpicture
+ * Description: This function commits pending composite/clear requests to
+ * ensure that they will be completed in a finite amount of
+ * time.
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - The subpicture whos compsiting should be flushed
+ *
+ * Returns: Status
+ */
+Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture)
+{
+ XVMC_ERR("XvMCFlushSubpicture not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCGetSubpictureStatus
+ * Description: This function gets the current status of a subpicture
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - The subpicture whos status is being queried
+ * stat - The status of the subpicture. It can be any of the following
+ * OR'd together:
+ * XVMC_RENDERING - Last composite or clear request not completed
+ * XVMC_DISPLAYING - Suppicture currently being displayed.
+ *
+ * Returns: Status
+ */
+Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture,
+ int *stat)
+{
+ XVMC_ERR("XvMCGetSubpictureStatus not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCQueryAttributes
+ * Description: An array of XvAttributes of size "number" is returned by
+ * this function. If there are no attributes, NULL is returned and number
+ * is set to 0. The array may be freed with xfree().
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * context - The context whos attributes we are querying.
+ * number - The returned number of recognized atoms
+ *
+ * Returns:
+ * An array of XvAttributes.
+ */
+XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context,
+ int *number)
+{
+ /* now XvMC has no extra attribs than Xv */
+ *number = 0;
+ return NULL;
+}
+
+/*
+ * Function: XvMCSetAttribute
+ * Description: This function sets a context-specific attribute.
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * context - The context whos attributes we are querying.
+ * attribute - The X atom of the attribute to be changed.
+ * value - The new value for the attribute.
+ *
+ * Returns:
+ * Status
+ */
+Status XvMCSetAttribute(Display *display, XvMCContext *context,
+ Atom attribute, int value)
+{
+ return Success;
+}
+
+/*
+ * Function: XvMCGetAttribute
+ * Description: This function queries a context-specific attribute and
+ * returns the value.
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * context - The context whos attributes we are querying.
+ * attribute - The X atom of the attribute to be queried
+ * value - The returned attribute value
+ *
+ * Returns:
+ * Status
+ */
+Status XvMCGetAttribute(Display *display, XvMCContext *context,
+ Atom attribute, int *value)
+{
+ return Success;
+}
diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h
new file mode 100644
index 00000000..3375ffc4
--- /dev/null
+++ b/src/xvmc/intel_xvmc.h
@@ -0,0 +1,252 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Zhenyu Wang <zhenyu.z.wang@intel.com>
+ *
+ */
+#ifndef INTEL_XVMC_H
+#define INTEL_XVMC_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+#include <assert.h>
+#include <signal.h>
+
+#include <xf86drm.h>
+#include "i830_common.h"
+#include "i830_hwmc.h"
+#include <X11/X.h>
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include <fourcc.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XvMC.h>
+#include <X11/extensions/XvMClib.h>
+#include <drm_sarea.h>
+
+#include "xf86dri.h"
+#include "driDrawable.h"
+
+#include "intel_batchbuffer.h"
+
+#define DEBUG 0
+
+#define XVMC_ERR(s, arg...) \
+ do { \
+ fprintf(stderr, "[intel_xvmc] err: " s "\n", ##arg); \
+ } while (0)
+
+#define XVMC_INFO(s, arg...) \
+ do { \
+ fprintf(stderr, "[intel_xvmc] info: " s "\n", ##arg); \
+ } while (0)
+
+#define XVMC_DBG(s, arg...) \
+ do { \
+ if (DEBUG) \
+ fprintf(stderr, "[intel_xvmc] debug: " s "\n", ##arg); \
+ } while (0)
+
+/* Subpicture fourcc */
+#define FOURCC_IA44 0x34344149
+
+/*
+ Definitions for temporary wire protocol hooks to be replaced
+ when a HW independent libXvMC is created.
+*/
+extern Status _xvmc_create_context(Display *dpy, XvMCContext *context,
+ int *priv_count, CARD32 **priv_data);
+
+extern Status _xvmc_destroy_context(Display *dpy, XvMCContext *context);
+
+extern Status _xvmc_create_surface(Display *dpy, XvMCContext *context,
+ XvMCSurface *surface, int *priv_count,
+ CARD32 **priv_data);
+
+extern Status _xvmc_destroy_surface(Display *dpy, XvMCSurface *surface);
+
+extern Status _xvmc_create_subpicture(Display *dpy, XvMCContext *context,
+ XvMCSubpicture *subpicture,
+ int *priv_count, uint **priv_data);
+
+extern Status _xvmc_destroy_subpicture(Display *dpy,
+ XvMCSubpicture *subpicture);
+
+typedef struct _intel_xvmc_context {
+ XvMCContext *context;
+ drm_context_t hw_context; /* context id to kernel drm */
+ struct _intel_xvmc_context *next;
+} intel_xvmc_context_t, *intel_xvmc_context_ptr;
+
+typedef struct _intel_xvmc_surface {
+ XvMCSurface *surface;
+ XvImage *image;
+ GC gc;
+ Bool gc_init;
+ Drawable last_draw;
+ struct intel_xvmc_command data;
+ struct _intel_xvmc_surface *next;
+} intel_xvmc_surface_t, *intel_xvmc_surface_ptr;
+
+typedef struct _intel_xvmc_drm_map {
+ drm_handle_t handle;
+ unsigned long offset;
+ unsigned long size;
+ unsigned long bus_addr;
+ drmAddress map;
+} intel_xvmc_drm_map_t, *intel_xvmc_drm_map_ptr;
+
+typedef struct _intel_xvmc_driver {
+ int type; /* hw xvmc type - i830_hwmc.h */
+ int screen; /* current screen num*/
+
+ int fd; /* drm file handler */
+ drm_handle_t hsarea; /* DRI open connect */
+ char busID[32];
+
+ unsigned int sarea_size;
+ drmAddress sarea_address;
+
+ struct {
+ unsigned int start_offset;
+ unsigned int size;
+ unsigned int space;
+ unsigned char *ptr;
+ } batch;
+
+ struct
+ {
+ void *ptr;
+ unsigned int size;
+ unsigned int offset;
+ unsigned int active_buf;
+ unsigned int irq_emitted;
+ } alloc;
+ intel_xvmc_drm_map_t batchbuffer;
+ unsigned int last_render;
+
+ sigset_t sa_mask;
+ pthread_mutex_t ctxmutex;
+ int lock; /* Lightweight lock to avoid locking twice */
+ int locked;
+ drmLock *driHwLock;
+
+ int num_ctx;
+ intel_xvmc_context_ptr ctx_list;
+ int num_surf;
+ intel_xvmc_surface_ptr surf_list;
+
+ void *private;
+
+ /* driver specific xvmc callbacks */
+ Status (*create_context)(Display* display, XvMCContext *context,
+ int priv_count, CARD32 *priv_data);
+
+ Status (*destroy_context)(Display* display, XvMCContext *context);
+
+ Status (*create_surface)(Display* display, XvMCContext *context,
+ XvMCSurface *surface, int priv_count, CARD32 *priv_data);
+
+ Status (*destroy_surface)(Display* display, XvMCSurface *surface);
+
+ Status (*render_surface)(Display *display, XvMCContext *context,
+ unsigned int picture_structure,
+ XvMCSurface *target_surface,
+ XvMCSurface *past_surface,
+ XvMCSurface *future_surface,
+ unsigned int flags,
+ unsigned int num_macroblocks,
+ unsigned int first_macroblock,
+ XvMCMacroBlockArray *macroblock_array,
+ XvMCBlockArray *blocks);
+
+ Status (*put_surface)(Display *display, XvMCSurface *surface,
+ Drawable draw, short srcx, short srcy,
+ unsigned short srcw, unsigned short srch,
+ short destx, short desty,
+ unsigned short destw, unsigned short desth,
+ int flags, struct intel_xvmc_command *data);
+
+ Status (*get_surface_status)(Display *display, XvMCSurface *surface, int *stat);
+
+ /* XXX more for vld */
+} intel_xvmc_driver_t, *intel_xvmc_driver_ptr;
+
+extern struct _intel_xvmc_driver i915_xvmc_mc_driver;
+extern struct _intel_xvmc_driver *xvmc_driver;
+
+#define SET_BLOCKED_SIGSET() do { \
+ sigset_t bl_mask; \
+ sigfillset(&bl_mask); \
+ sigdelset(&bl_mask, SIGFPE); \
+ sigdelset(&bl_mask, SIGILL); \
+ sigdelset(&bl_mask, SIGSEGV); \
+ sigdelset(&bl_mask, SIGBUS); \
+ sigdelset(&bl_mask, SIGKILL); \
+ pthread_sigmask(SIG_SETMASK, &bl_mask, &xvmc_driver->sa_mask); \
+ } while (0)
+
+#define RESTORE_BLOCKED_SIGSET() do { \
+ pthread_sigmask(SIG_SETMASK, &xvmc_driver->sa_mask, NULL); \
+ } while (0)
+
+#define PPTHREAD_MUTEX_LOCK() do { \
+ SET_BLOCKED_SIGSET(); \
+ pthread_mutex_lock(&xvmc_driver->ctxmutex); \
+ } while (0)
+
+#define PPTHREAD_MUTEX_UNLOCK() do { \
+ pthread_mutex_unlock(&xvmc_driver->ctxmutex); \
+ RESTORE_BLOCKED_SIGSET(); \
+ } while (0)
+
+extern void LOCK_HARDWARE(drm_context_t);
+extern void UNLOCK_HARDWARE(drm_context_t);
+
+static inline const char* intel_xvmc_decoder_string(int flag)
+{
+ switch (flag) {
+ case XVMC_I915_MPEG2_MC:
+ return "i915/945 MPEG2 MC decoder";
+ case XVMC_I965_MPEG2_MC:
+ return "i965 MPEG2 MC decoder";
+ case XVMC_I945_MPEG2_VLD:
+ return "i945 MPEG2 VLD decoder";
+ case XVMC_I965_MPEG2_VLD:
+ return "i965 MPEG2 VLD decoder";
+ default:
+ return "Unknown decoder";
+ }
+}
+
+extern intel_xvmc_context_ptr intel_xvmc_find_context(XID id);
+extern intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id);
+
+#endif
diff --git a/src/xvmc/xf86dri.c b/src/xvmc/xf86dri.c
new file mode 100644
index 00000000..798c1a84
--- /dev/null
+++ b/src/xvmc/xf86dri.c
@@ -0,0 +1,601 @@
+/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Jens Owen <jens@tungstengraphics.com>
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD */
+
+#define NEED_REPLIES
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include "xf86dristr.h"
+
+static XExtensionInfo _xf86dri_info_data;
+static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
+static char xf86dri_extension_name[] = XF86DRINAME;
+
+#define uniDRICheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, xf86dri_extension_name, val)
+
+/*****************************************************************************
+ * *
+ * private utility routines *
+ * *
+ *****************************************************************************/
+
+static int close_display(Display * dpy, XExtCodes * extCodes);
+static /* const */ XExtensionHooks xf86dri_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ close_display, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
+};
+
+static
+XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
+ xf86dri_extension_name, &xf86dri_extension_hooks, 0, NULL)
+
+ static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)
+
+/*****************************************************************************
+ * *
+ * public XFree86-DRI Extension routines *
+ * *
+ *****************************************************************************/
+#if 0
+#include <stdio.h>
+#define TRACE(msg, arg...) fprintf(stderr,"uniDRI" msg "\n", ##arg);
+#else
+#define TRACE(msg, arg...)
+#endif
+ Bool uniDRIQueryExtension(dpy, event_basep, error_basep)
+ Display *dpy;
+ int *event_basep, *error_basep;
+{
+ XExtDisplayInfo *info = find_display(dpy);
+
+ TRACE("QueryExtension...");
+ if (XextHasExtension(info)) {
+ *event_basep = info->codes->first_event;
+ *error_basep = info->codes->first_error;
+ TRACE("QueryExtension... return True");
+ return True;
+ } else {
+ TRACE("QueryExtension... return False");
+ return False;
+ }
+}
+
+Bool
+uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
+ Display *dpy;
+ int *majorVersion;
+ int *minorVersion;
+ int *patchVersion;
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRIQueryVersionReply rep;
+ xXF86DRIQueryVersionReq *req;
+
+ TRACE("QueryVersion...");
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIQueryVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIQueryVersion;
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryVersion... return False");
+ return False;
+ }
+ *majorVersion = rep.majorVersion;
+ *minorVersion = rep.minorVersion;
+ *patchVersion = rep.patchVersion;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryVersion... %d.%d.%d return True", rep.majorVersion,
+ rep.minorVersion, rep.patchVersion);
+ return True;
+}
+
+Bool
+uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
+ Display *dpy;
+ int screen;
+ Bool *isCapable;
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRIQueryDirectRenderingCapableReply rep;
+ xXF86DRIQueryDirectRenderingCapableReq *req;
+
+ TRACE("QueryDirectRenderingCapable...");
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIQueryDirectRenderingCapable, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryDirectRenderingCapable... return False");
+ return False;
+ }
+ *isCapable = rep.isCapable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("QueryDirectRenderingCapable... %s return True",
+ rep.isCapable ? "true" : "false");
+ return True;
+}
+
+Bool
+uniDRIOpenConnection(dpy, screen, hSAREA, busIdString)
+ Display *dpy;
+ int screen;
+ drm_handle_t *hSAREA;
+ char **busIdString;
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRIOpenConnectionReply rep;
+ xXF86DRIOpenConnectionReq *req;
+
+ TRACE("OpenConnection...");
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIOpenConnection, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIOpenConnection;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("OpenConnection... return False");
+ return False;
+ }
+
+ *hSAREA = rep.hSAREALow;
+#ifdef LONG64
+ if (sizeof(drm_handle_t) == 8) {
+ *hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32;
+ }
+#endif
+ if (rep.length) {
+ if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
+ _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("OpenConnection... return False");
+ return False;
+ }
+ _XReadPad(dpy, *busIdString, rep.busIdStringLength);
+ } else {
+ *busIdString = NULL;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("OpenConnection... busid %s return True",
+ *busIdString ? *busIdString : "null");
+ return True;
+}
+
+Bool
+uniDRIAuthConnection(dpy, screen, magic)
+ Display *dpy;
+ int screen;
+ drm_magic_t magic;
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRIAuthConnectionReq *req;
+ xXF86DRIAuthConnectionReply rep;
+
+ TRACE("AuthConnection...");
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIAuthConnection, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIAuthConnection;
+ req->screen = screen;
+ req->magic = magic;
+ rep.authenticated = 0;
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("AuthConnection... return False");
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("AuthConnection... return True");
+ return True;
+}
+
+Bool
+uniDRICloseConnection(dpy, screen)
+ Display *dpy;
+ int screen;
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRICloseConnectionReq *req;
+
+ TRACE("CloseConnection...");
+
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRICloseConnection, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRICloseConnection;
+ req->screen = screen;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CloseConnection... return True");
+ return True;
+}
+
+Bool
+uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
+ ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
+ Display *dpy;
+ int screen;
+ int *ddxDriverMajorVersion;
+ int *ddxDriverMinorVersion;
+ int *ddxDriverPatchVersion;
+ char **clientDriverName;
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRIGetClientDriverNameReply rep;
+ xXF86DRIGetClientDriverNameReq *req;
+
+ TRACE("GetClientDriverName...");
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIGetClientDriverName, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIGetClientDriverName;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetClientDriverName... return False");
+ return False;
+ }
+
+ *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
+ *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
+ *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
+
+ if (rep.length) {
+ if (!(*clientDriverName =
+ (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
+ _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetClientDriverName... return False");
+ return False;
+ }
+ _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
+ } else {
+ *clientDriverName = NULL;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetClientDriverName... return True");
+ return True;
+}
+
+Bool
+uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
+ Display *dpy;
+ int screen;
+ int configID;
+ XID context;
+ drm_context_t *hHWContext;
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRICreateContextReply rep;
+ xXF86DRICreateContextReq *req;
+
+ TRACE("CreateContext... id %d", context);
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRICreateContext, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRICreateContext;
+ req->visual = configID;
+ req->screen = screen;
+ req->context = context;
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateContext... return False");
+ return False;
+ }
+ *hHWContext = rep.hHWContext;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateContext... return True");
+ return True;
+}
+
+Bool
+uniDRICreateContext(dpy, screen, visual, context, hHWContext)
+ Display *dpy;
+ int screen;
+ Visual *visual;
+ XID context;
+ drm_context_t *hHWContext;
+{
+ return uniDRICreateContextWithConfig(dpy, screen,
+ visual->visualid, context, hHWContext);
+}
+
+Bool
+uniDRIDestroyContext(Display * ndpy, int screen, XID context)
+{
+ Display *const dpy = (Display *) ndpy;
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRIDestroyContextReq *req;
+
+ TRACE("DestroyContext... id %d", context);
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIDestroyContext, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIDestroyContext;
+ req->screen = screen;
+ req->context = context;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("DestroyContext... return True");
+ return True;
+}
+
+Bool
+uniDRICreateDrawable(Display * ndpy, int screen,
+ Drawable drawable, drm_drawable_t * hHWDrawable)
+{
+ Display *const dpy = (Display *) ndpy;
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRICreateDrawableReply rep;
+ xXF86DRICreateDrawableReq *req;
+
+ TRACE("CreateDrawable...");
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRICreateDrawable, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRICreateDrawable;
+ req->screen = screen;
+ req->drawable = drawable;
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateDrawable... return False");
+ return False;
+ }
+ *hHWDrawable = rep.hHWDrawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("CreateDrawable... return True");
+ return True;
+}
+
+Bool
+uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable)
+{
+ Display *const dpy = (Display *) ndpy;
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRIDestroyDrawableReq *req;
+
+ TRACE("DestroyDrawable...");
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIDestroyDrawable, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIDestroyDrawable;
+ req->screen = screen;
+ req->drawable = drawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("DestroyDrawable... return True");
+ return True;
+}
+
+Bool
+uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
+ unsigned int *index, unsigned int *stamp,
+ int *X, int *Y, int *W, int *H,
+ int *numClipRects, drm_clip_rect_t ** pClipRects,
+ int *backX, int *backY,
+ int *numBackClipRects, drm_clip_rect_t ** pBackClipRects)
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRIGetDrawableInfoReply rep;
+ xXF86DRIGetDrawableInfoReq *req;
+ int total_rects;
+
+ TRACE("GetDrawableInfo...");
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIGetDrawableInfo, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIGetDrawableInfo;
+ req->screen = screen;
+ req->drawable = drawable;
+
+ if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDrawableInfo... return False");
+ return False;
+ }
+ *index = rep.drawableTableIndex;
+ *stamp = rep.drawableTableStamp;
+ *X = (int)rep.drawableX;
+ *Y = (int)rep.drawableY;
+ *W = (int)rep.drawableWidth;
+ *H = (int)rep.drawableHeight;
+ *numClipRects = rep.numClipRects;
+ total_rects = *numClipRects;
+
+ *backX = rep.backX;
+ *backY = rep.backY;
+ *numBackClipRects = rep.numBackClipRects;
+ total_rects += *numBackClipRects;
+
+#if 0
+ /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
+ * backwards compatibility (Because of the >> 2 shift) but the fix
+ * enables multi-threaded apps to work.
+ */
+ if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply) +
+ total_rects * sizeof(drm_clip_rect_t)) +
+ 3) & ~3) >> 2)) {
+ _XEatData(dpy, rep.length);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDrawableInfo... return False");
+ return False;
+ }
+#endif
+
+ if (*numClipRects) {
+ int len = sizeof(drm_clip_rect_t) * (*numClipRects);
+
+ *pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
+ if (*pClipRects)
+ _XRead(dpy, (char *)*pClipRects, len);
+ } else {
+ *pClipRects = NULL;
+ }
+
+ if (*numBackClipRects) {
+ int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
+
+ *pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
+ if (*pBackClipRects)
+ _XRead(dpy, (char *)*pBackClipRects, len);
+ } else {
+ *pBackClipRects = NULL;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDrawableInfo... return True");
+ return True;
+}
+
+Bool
+uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer,
+ fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
+ Display *dpy;
+ int screen;
+ drm_handle_t *hFrameBuffer;
+ int *fbOrigin;
+ int *fbSize;
+ int *fbStride;
+ int *devPrivateSize;
+ void **pDevPrivate;
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86DRIGetDeviceInfoReply rep;
+ xXF86DRIGetDeviceInfoReq *req;
+
+ TRACE("GetDeviceInfo...");
+ uniDRICheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DRIGetDeviceInfo, req);
+ req->reqType = info->codes->major_opcode;
+ req->driReqType = X_XF86DRIGetDeviceInfo;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDeviceInfo... return False");
+ return False;
+ }
+
+ *hFrameBuffer = rep.hFrameBufferLow;
+#ifdef LONG64
+ if (sizeof(drm_handle_t) == 8) {
+ *hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32;
+ }
+#endif
+
+ *fbOrigin = rep.framebufferOrigin;
+ *fbSize = rep.framebufferSize;
+ *fbStride = rep.framebufferStride;
+ *devPrivateSize = rep.devPrivateSize;
+
+ if (rep.length) {
+ if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
+ _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDeviceInfo... return False");
+ return False;
+ }
+ _XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize);
+ } else {
+ *pDevPrivate = NULL;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ TRACE("GetDeviceInfo... return True");
+ return True;
+}
diff --git a/src/xvmc/xf86dri.h b/src/xvmc/xf86dri.h
new file mode 100644
index 00000000..7598bc81
--- /dev/null
+++ b/src/xvmc/xf86dri.h
@@ -0,0 +1,111 @@
+/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.8 2002/10/30 12:51:25 alanh Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/**
+ * \file xf86dri.h
+ * Protocol numbers and function prototypes for DRI X protocol.
+ *
+ * \author Kevin E. Martin <martin@valinux.com>
+ * \author Jens Owen <jens@tungstengraphics.com>
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ */
+
+#ifndef _XF86DRI_H_
+#define _XF86DRI_H_
+
+#include <X11/Xfuncproto.h>
+#include <xf86drm.h>
+
+#define X_XF86DRIQueryVersion 0
+#define X_XF86DRIQueryDirectRenderingCapable 1
+#define X_XF86DRIOpenConnection 2
+#define X_XF86DRICloseConnection 3
+#define X_XF86DRIGetClientDriverName 4
+#define X_XF86DRICreateContext 5
+#define X_XF86DRIDestroyContext 6
+#define X_XF86DRICreateDrawable 7
+#define X_XF86DRIDestroyDrawable 8
+#define X_XF86DRIGetDrawableInfo 9
+#define X_XF86DRIGetDeviceInfo 10
+#define X_XF86DRIAuthConnection 11
+#define X_XF86DRIOpenFullScreen 12 /* Deprecated */
+#define X_XF86DRICloseFullScreen 13 /* Deprecated */
+
+#define XF86DRINumberEvents 0
+
+#define XF86DRIClientNotLocal 0
+#define XF86DRIOperationNotSupported 1
+#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1)
+
+#ifndef _XF86DRI_SERVER_
+
+_XFUNCPROTOBEGIN
+ Bool uniDRIQueryExtension(Display * dpy, int *event_base,
+ int *error_base);
+
+Bool uniDRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
+ int *patchVersion);
+
+Bool uniDRIQueryDirectRenderingCapable(Display * dpy, int screen,
+ Bool * isCapable);
+
+Bool uniDRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA,
+ char **busIDString);
+
+Bool uniDRIAuthConnection(Display * dpy, int screen, drm_magic_t magic);
+
+Bool uniDRICloseConnection(Display * dpy, int screen);
+
+Bool uniDRIGetClientDriverName(Display * dpy, int screen,
+ int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
+ int *ddxDriverPatchVersion, char **clientDriverName);
+
+/* XvMC context XID is alloced in _xvmc_create_context, so
+ * don't recreate here */
+Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual,
+ XID context_id, drm_context_t * hHWContext);
+
+Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID,
+ XID context_id, drm_context_t * hHWContext);
+
+extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id);
+
+extern Bool uniDRICreateDrawable(Display * dpy, int screen,
+ Drawable drawable, drm_drawable_t * hHWDrawable);
+
+extern Bool uniDRIDestroyDrawable(Display * dpy, int screen,
+ Drawable drawable);
+
+Bool uniDRIGetDeviceInfo(Display * dpy, int screen,
+ drm_handle_t * hFrameBuffer, int *fbOrigin, int *fbSize,
+ int *fbStride, int *devPrivateSize, void **pDevPrivate);
+
+_XFUNCPROTOEND
+#endif /* _XF86DRI_SERVER_ */
+#endif /* _XF86DRI_H_ */
diff --git a/src/xvmc/xf86dristr.h b/src/xvmc/xf86dristr.h
new file mode 100644
index 00000000..3b43438e
--- /dev/null
+++ b/src/xvmc/xf86dristr.h
@@ -0,0 +1,390 @@
+/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.10 2002/10/30 12:51:25 alanh Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Jens Owen <jens@tungstengraphics.com>
+ * Rickard E. (Rik) Fiath <faith@valinux.com>
+ *
+ */
+
+#ifndef _XF86DRISTR_H_
+#define _XF86DRISTR_H_
+
+#include "xf86dri.h"
+
+#define XF86DRINAME "XFree86-DRI"
+
+/* The DRI version number. This was originally set to be the same of the
+ * XFree86 version number. However, this version is really indepedent of
+ * the XFree86 version.
+ *
+ * Version History:
+ * 4.0.0: Original
+ * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
+ * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
+ */
+#define XF86DRI_MAJOR_VERSION 4
+#define XF86DRI_MINOR_VERSION 1
+#define XF86DRI_PATCH_VERSION 0
+
+typedef struct _XF86DRIQueryVersion
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRIQueryVersion */
+ CARD16 length B16;
+} xXF86DRIQueryVersionReq;
+
+#define sz_xXF86DRIQueryVersionReq 4
+
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 majorVersion B16; /* major version of DRI protocol */
+ CARD16 minorVersion B16; /* minor version of DRI protocol */
+ CARD32 patchVersion B32; /* patch version of DRI protocol */
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86DRIQueryVersionReply;
+
+#define sz_xXF86DRIQueryVersionReply 32
+
+typedef struct _XF86DRIQueryDirectRenderingCapable
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */
+ CARD16 length B16;
+ CARD32 screen B32;
+} xXF86DRIQueryDirectRenderingCapableReq;
+
+#define sz_xXF86DRIQueryDirectRenderingCapableReq 8
+
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ BOOL isCapable;
+ BOOL pad2;
+ BOOL pad3;
+ BOOL pad4;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+ CARD32 pad7 B32;
+ CARD32 pad8 B32;
+ CARD32 pad9 B32;
+} xXF86DRIQueryDirectRenderingCapableReply;
+
+#define sz_xXF86DRIQueryDirectRenderingCapableReply 32
+
+typedef struct _XF86DRIOpenConnection
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRIOpenConnection */
+ CARD16 length B16;
+ CARD32 screen B32;
+} xXF86DRIOpenConnectionReq;
+
+#define sz_xXF86DRIOpenConnectionReq 8
+
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 hSAREALow B32;
+ CARD32 hSAREAHigh B32;
+ CARD32 busIdStringLength B32;
+ CARD32 pad6 B32;
+ CARD32 pad7 B32;
+ CARD32 pad8 B32;
+} xXF86DRIOpenConnectionReply;
+
+#define sz_xXF86DRIOpenConnectionReply 32
+
+typedef struct _XF86DRIAuthConnection
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRICloseConnection */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 magic B32;
+} xXF86DRIAuthConnectionReq;
+
+#define sz_xXF86DRIAuthConnectionReq 12
+
+typedef struct
+{
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 authenticated B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86DRIAuthConnectionReply;
+
+#define zx_xXF86DRIAuthConnectionReply 32
+
+typedef struct _XF86DRICloseConnection
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRICloseConnection */
+ CARD16 length B16;
+ CARD32 screen B32;
+} xXF86DRICloseConnectionReq;
+
+#define sz_xXF86DRICloseConnectionReq 8
+
+typedef struct _XF86DRIGetClientDriverName
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRIGetClientDriverName */
+ CARD16 length B16;
+ CARD32 screen B32;
+} xXF86DRIGetClientDriverNameReq;
+
+#define sz_xXF86DRIGetClientDriverNameReq 8
+
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 ddxDriverMajorVersion B32;
+ CARD32 ddxDriverMinorVersion B32;
+ CARD32 ddxDriverPatchVersion B32;
+ CARD32 clientDriverNameLength B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86DRIGetClientDriverNameReply;
+
+#define sz_xXF86DRIGetClientDriverNameReply 32
+
+typedef struct _XF86DRICreateContext
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRICreateContext */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 visual B32;
+ CARD32 context B32;
+} xXF86DRICreateContextReq;
+
+#define sz_xXF86DRICreateContextReq 16
+
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 hHWContext B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86DRICreateContextReply;
+
+#define sz_xXF86DRICreateContextReply 32
+
+typedef struct _XF86DRIDestroyContext
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRIDestroyContext */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 context B32;
+} xXF86DRIDestroyContextReq;
+
+#define sz_xXF86DRIDestroyContextReq 12
+
+typedef struct _XF86DRICreateDrawable
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRICreateDrawable */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 drawable B32;
+} xXF86DRICreateDrawableReq;
+
+#define sz_xXF86DRICreateDrawableReq 12
+
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 hHWDrawable B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86DRICreateDrawableReply;
+
+#define sz_xXF86DRICreateDrawableReply 32
+
+typedef struct _XF86DRIDestroyDrawable
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRIDestroyDrawable */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 drawable B32;
+} xXF86DRIDestroyDrawableReq;
+
+#define sz_xXF86DRIDestroyDrawableReq 12
+
+typedef struct _XF86DRIGetDrawableInfo
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRIGetDrawableInfo */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 drawable B32;
+} xXF86DRIGetDrawableInfoReq;
+
+#define sz_xXF86DRIGetDrawableInfoReq 12
+
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 drawableTableIndex B32;
+ CARD32 drawableTableStamp B32;
+ INT16 drawableX B16;
+ INT16 drawableY B16;
+ INT16 drawableWidth B16;
+ INT16 drawableHeight B16;
+ CARD32 numClipRects B32;
+ INT16 backX B16;
+ INT16 backY B16;
+ CARD32 numBackClipRects B32;
+} xXF86DRIGetDrawableInfoReply;
+
+#define sz_xXF86DRIGetDrawableInfoReply 36
+
+typedef struct _XF86DRIGetDeviceInfo
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRIGetDeviceInfo */
+ CARD16 length B16;
+ CARD32 screen B32;
+} xXF86DRIGetDeviceInfoReq;
+
+#define sz_xXF86DRIGetDeviceInfoReq 8
+
+typedef struct
+{
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 hFrameBufferLow B32;
+ CARD32 hFrameBufferHigh B32;
+ CARD32 framebufferOrigin B32;
+ CARD32 framebufferSize B32;
+ CARD32 framebufferStride B32;
+ CARD32 devPrivateSize B32;
+} xXF86DRIGetDeviceInfoReply;
+
+#define sz_xXF86DRIGetDeviceInfoReply 32
+
+typedef struct _XF86DRIOpenFullScreen
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRIOpenFullScreen */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 drawable B32;
+} xXF86DRIOpenFullScreenReq;
+
+#define sz_xXF86DRIOpenFullScreenReq 12
+
+typedef struct
+{
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 isFullScreen B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86DRIOpenFullScreenReply;
+
+#define sz_xXF86DRIOpenFullScreenReply 32
+
+typedef struct _XF86DRICloseFullScreen
+{
+ CARD8 reqType; /* always DRIReqCode */
+ CARD8 driReqType; /* always X_DRICloseFullScreen */
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 drawable B32;
+} xXF86DRICloseFullScreenReq;
+
+#define sz_xXF86DRICloseFullScreenReq 12
+
+typedef struct
+{
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+ CARD32 pad7 B32;
+} xXF86DRICloseFullScreenReply;
+
+#define sz_xXF86DRICloseFullScreenReply 32
+
+#endif /* _XF86DRISTR_H_ */