diff options
-rw-r--r-- | src/i830_hwmc.h | 16 | ||||
-rw-r--r-- | src/i915_hwmc.c | 4 | ||||
-rw-r--r-- | src/i915_hwmc.h | 3 | ||||
-rw-r--r-- | src/xvmc/I915XvMC.c | 456 | ||||
-rw-r--r-- | src/xvmc/Makefile.am | 13 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc.c | 1333 | ||||
-rw-r--r-- | src/xvmc/intel_xvmc.h | 65 |
7 files changed, 1535 insertions, 355 deletions
diff --git a/src/i830_hwmc.h b/src/i830_hwmc.h index 60a49783..70ec00d6 100644 --- a/src/i830_hwmc.h +++ b/src/i830_hwmc.h @@ -36,14 +36,20 @@ #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 _intel_xvmc_common { + unsigned int type; +}; + #ifdef _INTEL_XVMC_SERVER_ #include <xf86xvmc.h> -#define XVMC_DRIVER_MPEG2_MC 0x0001 -#define XVMC_DRIVER_MPEG2_VLD 0x0002 -#define XVMC_DRIVER_H264_MC 0x0004 -#define XVMC_DRIVER_H264_VLD 0x0008 - struct intel_xvmc_driver { char *name; XF86MCAdaptorPtr adaptor; diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c index ed5e7bc0..e2c91304 100644 --- a/src/i915_hwmc.c +++ b/src/i915_hwmc.c @@ -56,7 +56,6 @@ #endif #define _INTEL_XVMC_SERVER_ -#include "i830_hwmc.h" #include "i915_hwmc.h" #define I915_XVMC_MAX_BUFFERS 2 @@ -531,6 +530,7 @@ static int I915XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, return BadAlloc; } + contextRec->comm.type = xvmc_driver->flag; contextRec->ctxno = i; contextRec->sis.handle = ctxpriv->sis_handle; contextRec->sis.offset = ctxpriv->mcStaticIndirectState->offset; @@ -892,7 +892,7 @@ static void i915_xvmc_fini(ScrnInfoPtr pScrn) struct intel_xvmc_driver i915_xvmc_driver = { .name = "i915_xvmc", .adaptor = &pAdapt, - .flag = XVMC_DRIVER_MPEG2_MC, + .flag = XVMC_I915_MPEG2_MC, .init = i915_xvmc_init, .fini = i915_xvmc_fini, .putimage_size = i915_xvmc_putimage_size, diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h index 21964cb4..cf74d331 100644 --- a/src/i915_hwmc.h +++ b/src/i915_hwmc.h @@ -27,6 +27,8 @@ #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)) @@ -55,6 +57,7 @@ struct hwmc_buffer typedef struct { + struct _intel_xvmc_common comm; unsigned int ctxno; /* XvMC private context reference number */ struct hwmc_buffer sis; struct hwmc_buffer ssb; diff --git a/src/xvmc/I915XvMC.c b/src/xvmc/I915XvMC.c index 59d5730a..2c3dec64 100644 --- a/src/xvmc/I915XvMC.c +++ b/src/xvmc/I915XvMC.c @@ -24,35 +24,14 @@ * Xiang Haihao <haihao.xiang@intel.com> * */ -#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 <pthread.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 <xf86drm.h> -#include <drm_sarea.h> #include "I915XvMC.h" #include "i915_structs.h" #include "i915_program.h" #include "intel_batchbuffer.h" -#include "xf86dri.h" -#include "driDrawable.h" - -#define _STATIC_ static #define SAREAPTR(ctx) ((drmI830Sarea *) \ (((CARD8 *)(ctx)->sarea_address) + \ @@ -66,7 +45,7 @@ SIZE_Y420(surface->width, surface->height)) /* Lookup tables to speed common calculations */ -_STATIC_ unsigned int mb_bytes[] = { +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 @@ -82,11 +61,51 @@ typedef union { uint u[2]; } su_t; -_STATIC_ char I915KernelDriverName[] = "i915"; -_STATIC_ int error_base; -_STATIC_ int event_base; +static char I915KernelDriverName[] = "i915"; +static int error_base; +static int event_base; + +static int i915_xvmc_mc_create_context(Display* display, XvMCContext *context, int priv_count, CARD32* priv_data); +static int i915_xvmc_mc_destroy_context(Display* display, XvMCContext *context); +static int i915_xvmc_mc_create_surface(Display* display, XvMCContext *context, XvMCSurface *surface); +static int i915_xvmc_mc_destroy_surface(Display* display, XvMCSurface *surface); +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); +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); +static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat); +//XXX +static int i915_xvmc_mc_init() +{return 0;} +static void i915_xvmc_mc_fini() +{} + +struct _intel_xvmc_driver i915_xvmc_mc_driver = { + .type = XVMC_I915_MPEG2_MC, + .init = i915_xvmc_mc_init, + .fini = i915_xvmc_mc_fini, + .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, +}; -_STATIC_ int findOverlap(unsigned int width, unsigned int height, +static int findOverlap(unsigned int width, unsigned int height, short *dstX, short *dstY, short *srcX, short *srcY, unsigned short *areaW, unsigned short *areaH) @@ -122,12 +141,12 @@ _STATIC_ int findOverlap(unsigned int width, unsigned int height, return 0; } -_STATIC_ __inline__ void renderError(void) +static __inline__ void renderError(void) { XVMC_ERR("Invalid Macroblock Parameters found."); } -_STATIC_ void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, drmLockFlags flags) +static void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, drmLockFlags flags) { drmGetLock(pI915XvMC->fd, pI915XvMC->hHWContext, flags); } @@ -159,7 +178,7 @@ _STATIC_ void I915XvMCContendedLock(i915XvMCContext *pI915XvMC, drmLockFlags fla /* Lock the hardware and validate our state. */ -_STATIC_ void LOCK_HARDWARE(i915XvMCContext *pI915XvMC) +static void LOCK_HARDWARE(i915XvMCContext *pI915XvMC) { char __ret = 0; @@ -177,7 +196,7 @@ _STATIC_ void LOCK_HARDWARE(i915XvMCContext *pI915XvMC) /* Unlock the hardware using the global current context */ -_STATIC_ void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC) +static void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC) { pI915XvMC->locked = 0; DRM_UNLOCK(pI915XvMC->fd, pI915XvMC->driHwLock, @@ -185,7 +204,7 @@ _STATIC_ void UNLOCK_HARDWARE(i915XvMCContext *pI915XvMC) PPTHREAD_MUTEX_UNLOCK(pI915XvMC); } -_STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render) +static void i915_flush(i915XvMCContext *pI915XvMC, int map, int render) { struct i915_mi_flush mi_flush; @@ -199,7 +218,7 @@ _STATIC_ void i915_flush(i915XvMCContext *pI915XvMC, int map, int render) } /* for MC picture rendering */ -_STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, +static void i915_mc_static_indirect_state_buffer(XvMCContext *context, XvMCSurface *surface, unsigned int picture_structure, unsigned int flags, @@ -325,7 +344,7 @@ _STATIC_ void i915_mc_static_indirect_state_buffer(XvMCContext *context, buffer_info->dw2.base_address = (pI915XvMC->corrdata.offset >> 2); /* starting DWORD address */ } -_STATIC_ void i915_mc_map_state_buffer(XvMCContext *context, +static void i915_mc_map_state_buffer(XvMCContext *context, i915XvMCSurface *privTarget, i915XvMCSurface *privPast, i915XvMCSurface *privFuture) @@ -471,7 +490,7 @@ _STATIC_ void i915_mc_map_state_buffer(XvMCContext *context, tm->tm2.pitch = (privFuture->uvStride >> 2) - 1; } -_STATIC_ void i915_mc_load_sis_msb_buffers(XvMCContext *context) +static void i915_mc_load_sis_msb_buffers(XvMCContext *context) { struct i915_3dstate_load_indirect *load_indirect; sis_state *sis = NULL; @@ -524,7 +543,7 @@ _STATIC_ void i915_mc_load_sis_msb_buffers(XvMCContext *context) free(base); } -_STATIC_ void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb) +static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb) { struct i915_3dmpeg_set_origin set_origin; i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; @@ -540,7 +559,7 @@ _STATIC_ void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb) intelBatchbufferData(pI915XvMC, &set_origin, sizeof(set_origin), 0); } -_STATIC_ void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb) +static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb) { struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture; i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; @@ -555,7 +574,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBl } -_STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb) +static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb) { struct i915_3dmpeg_macroblock_0mv macroblock_0mv; i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; @@ -584,7 +603,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock * intelBatchbufferData(pI915XvMC, ¯oblock_0mv, sizeof(macroblock_0mv), 0); } -_STATIC_ void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb) +static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb) { struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv; i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; @@ -623,7 +642,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock intelBatchbufferData(pI915XvMC, ¯oblock_1fbmv, sizeof(macroblock_1fbmv), 0); } -_STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps) +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; @@ -691,7 +710,7 @@ _STATIC_ void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock } /* for MC context initialization */ -_STATIC_ void i915_mc_sampler_state_buffer(XvMCContext *context) +static void i915_mc_sampler_state_buffer(XvMCContext *context) { struct i915_3dstate_sampler_state *sampler_state; struct texture_sampler *ts; @@ -760,7 +779,7 @@ _STATIC_ void i915_mc_sampler_state_buffer(XvMCContext *context) ts->ts2.default_color = 0; } -_STATIC_ void i915_inst_arith(unsigned int *inst, +static void i915_inst_arith(unsigned int *inst, unsigned int op, unsigned int dest, unsigned int mask, @@ -775,7 +794,7 @@ _STATIC_ void i915_inst_arith(unsigned int *inst, *inst = (A2_SRC1(src1) | A2_SRC2(src2)); } -_STATIC_ void i915_inst_decl(unsigned int *inst, +static void i915_inst_decl(unsigned int *inst, unsigned int type, unsigned int nr, unsigned int d0_flags) @@ -789,7 +808,7 @@ _STATIC_ void i915_inst_decl(unsigned int *inst, *inst = D2_MBZ; } -_STATIC_ void i915_inst_texld(unsigned int *inst, +static void i915_inst_texld(unsigned int *inst, unsigned int op, unsigned int dest, unsigned int coord, @@ -803,7 +822,7 @@ _STATIC_ void i915_inst_texld(unsigned int *inst, *inst = T2_MBZ; } -_STATIC_ void i915_mc_pixel_shader_program_buffer(XvMCContext *context) +static void i915_mc_pixel_shader_program_buffer(XvMCContext *context) { struct i915_3dstate_pixel_shader_program *pixel_shader_program; i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; @@ -945,7 +964,7 @@ _STATIC_ void i915_mc_pixel_shader_program_buffer(XvMCContext *context) inst += 3; } -_STATIC_ void i915_mc_pixel_shader_constants_buffer(XvMCContext *context) +static void i915_mc_pixel_shader_constants_buffer(XvMCContext *context) { struct i915_3dstate_pixel_shader_constants *pixel_shader_constants; i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData; @@ -964,7 +983,7 @@ _STATIC_ void i915_mc_pixel_shader_constants_buffer(XvMCContext *context) *(value++) = 0.5; } -_STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context) +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; @@ -1076,7 +1095,7 @@ _STATIC_ void i915_mc_one_time_state_initialization(XvMCContext *context) free(base); } -_STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask) +static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask) { struct i915_3dstate_load_indirect *load_indirect = NULL; sis_state *sis = NULL; @@ -1184,7 +1203,7 @@ _STATIC_ void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsign free(base); } -_STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC) +static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC) { if (drmMap(pI915XvMC->fd, pI915XvMC->sis.handle, @@ -1238,7 +1257,7 @@ _STATIC_ int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC) return 0; } -_STATIC_ void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC) +static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC) { if (pI915XvMC->sis.map) { drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size); @@ -1279,7 +1298,7 @@ _STATIC_ void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC) /* * Video post processing */ -_STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface) +static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface) { struct i915_3dstate_map_state *map_state; struct texture_map *tm; @@ -1353,7 +1372,7 @@ _STATIC_ void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface) tm->tm2.pitch = (privTarget->uvStride >> 2) - 1; /* in DWords - 1 */ } -_STATIC_ void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface) +static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface) { struct i915_3dstate_sampler_state *sampler_state; struct texture_sampler *ts; @@ -1450,7 +1469,7 @@ _STATIC_ void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface) ts->ts2.default_color = 0; } -_STATIC_ void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface, +static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface, unsigned int dstaddr, int dstpitch) { @@ -1484,7 +1503,7 @@ _STATIC_ void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface, dest_buffer_variables->dw1.color_fmt = COLORBUFFER_A8R8G8B8; /* FIXME */ } -_STATIC_ void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface) +static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface) { struct i915_3dstate_pixel_shader_program *pixel_shader_program; i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData; @@ -1534,7 +1553,7 @@ _STATIC_ void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface) i915_inst_texld(inst, T0_TEXLD, dest, src0, src1); } -_STATIC_ void i915_yuv2rgb_proc(XvMCSurface *surface) +static void i915_yuv2rgb_proc(XvMCSurface *surface) { i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData; i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext; @@ -1695,13 +1714,11 @@ _STATIC_ void i915_yuv2rgb_proc(XvMCSurface *surface) // Function: i915_release_resource // Description: ***************************************************************************/ -_STATIC_ void i915_release_resource(Display *display, XvMCContext *context) +//XXX +static void i915_release_resource(Display *display, XvMCContext *context) { i915XvMCContext *pI915XvMC; - if (!display || !context) - return; - if (!(pI915XvMC = context->privData)) return; @@ -1733,115 +1750,18 @@ _STATIC_ void i915_release_resource(Display *display, XvMCContext *context) context->privData = 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) -{ +static int 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 *priv_data = NULL; uint magic; int major, minor; - int priv_count; int isCapable; - /* Verify Obvious things first */ - if (!display || !context) - return BadValue; - - if (!(flags & XVMC_DIRECT)) { - /* Indirect */ - XVMC_ERR("Indirect Rendering not supported! Using Direct."); - return BadAccess; - } - - /* Limit use to root for now */ - /* FIXME: remove it ??? */ -/* - if (geteuid()) { - printf("Use of XvMC on i915 is currently limited to root\n"); - return BadAccess; - } -*/ - /* - *FIXME: Check $DISPLAY for legal values 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; - - /* - Width, Height, and flags are checked against surface_type_id - and port for validity inside the X server, no need to check - here. - */ - - /* Verify the XvMC extension exists */ - XLockDisplay(display); - if (!XvMCQueryExtension(display, &event_base, &error_base)) { - XUnlockDisplay(display); - XVMC_ERR("XvMCExtension is not available!"); - return BadAlloc; - } - /* Verify XvMC version */ - ret = XvMCQueryVersion(display, &major, &minor); - if (ret) { - XVMC_ERR("XvMCQueryVersion Failed, unable to determine protocol version."); - } - XUnlockDisplay(display); - /* FIXME: Check Major and Minor here */ - - /* Allocate private Context data */ - 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; - - /* Check for drm */ - if (!drmAvailable()) { - XVMC_ERR("Direct Rendering is not avilable on this system!"); - free(pI915XvMC); - context->privData = NULL; - return BadAccess; - } - - /* - Pass control to the X server to create a drm_context_t for us and - validate the with/height and flags. - */ - XLockDisplay(display); - if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) { - XUnlockDisplay(display); - XVMC_ERR("Unable to create XvMC Context."); - free(pI915XvMC); - context->privData = NULL; - return ret; - } - XUnlockDisplay(display); - if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) { XVMC_ERR("_xvmc_create_context() returned incorrect data size!"); XVMC_INFO("\tExpected %d, got %d", @@ -1850,8 +1770,15 @@ Status XvMCCreateContext(Display *display, XvPortID port, free(priv_data); free(pI915XvMC); context->privData = NULL; + return BadAccess; + } + + 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; @@ -1891,6 +1818,8 @@ Status XvMCCreateContext(Display *display, XvPortID port, pI915XvMC->batchbuffer.size = tmpComm->batchbuffer.size; pI915XvMC->sarea_size = tmpComm->sarea_size; pI915XvMC->sarea_priv_offset = tmpComm->sarea_priv_offset; + //XXX +// xvmc_driver->screen = pI915XvMC->screen = tmpComm->screen; pI915XvMC->depth = tmpComm->depth; @@ -1898,64 +1827,54 @@ Status XvMCCreateContext(Display *display, XvPortID port, free(priv_data); priv_data = NULL; - XLockDisplay(display); + /* XXX just keep current i915 setup code for now */ + ret = uniDRIQueryDirectRenderingCapable(display, pI915XvMC->screen, &isCapable); if (!ret || !isCapable) { - XUnlockDisplay(display); XVMC_ERR("Direct Rendering is not available on this system!"); - free(pI915XvMC); - context->privData = NULL; return BadAlloc; } if (!uniDRIOpenConnection(display, pI915XvMC->screen, &pI915XvMC->hsarea, &curBusID)) { - XUnlockDisplay(display); XVMC_ERR("Could not open DRI connection to X server!"); - free(pI915XvMC); - context->privData = NULL; return BadAlloc; } - XUnlockDisplay(display); strncpy(pI915XvMC->busIdString, curBusID, 20); pI915XvMC->busIdString[20] = '\0'; free(curBusID); /* Open DRI Device */ - if((pI915XvMC->fd = drmOpen(I915KernelDriverName, NULL)) < 0) { - XVMC_ERR("DRM Device for %s could not be opened.", I915KernelDriverName); - free(pI915XvMC); - context->privData = NULL; + if((pI915XvMC->fd = drmOpen("i915", NULL)) < 0) { + XVMC_ERR("DRM Device could not be opened."); + //(xvmc_driver->fini)(); + //xvmc_driver = NULL; return BadAccess; - } /* !pI915XvMC->fd */ + } /* Get magic number */ drmGetMagic(pI915XvMC->fd, &magic); // context->flags = (unsigned long)magic; - XLockDisplay(display); if (!uniDRIAuthConnection(display, pI915XvMC->screen, magic)) { - XUnlockDisplay(display); XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions."); - free(pI915XvMC); - context->privData = NULL; + //(xvmc_driver->fini)(); + //xvmc_driver = NULL; return BadAlloc; } - XUnlockDisplay(display); /* - * Map DRI Sarea. + * Map DRI Sarea. we always want it right? */ if (drmMap(pI915XvMC->fd, pI915XvMC->hsarea, pI915XvMC->sarea_size, &pI915XvMC->sarea_address) < 0) { XVMC_ERR("Unable to map DRI SAREA.\n"); - free(pI915XvMC); - context->privData = NULL; + //(xvmc_driver->fini)(); + //xvmc_driver = NULL; return BadAlloc; } - pSAREA = (drm_sarea_t *)pI915XvMC->sarea_address; pI915XvMC->driHwLock = (drmLock *)&pSAREA->lock; pI915XvMC->sarea = SAREAPTR(pI915XvMC); @@ -2000,8 +1919,8 @@ Status XvMCCreateContext(Display *display, XvPortID port, } /* Initialize private context values */ - pI915XvMC->yStride = STRIDE(width); - pI915XvMC->uvStride = STRIDE(width >> 1); + pI915XvMC->yStride = STRIDE(context->width); + pI915XvMC->uvStride = STRIDE(context->width >> 1); pI915XvMC->haveXv = 0; pI915XvMC->dual_prime = 0; pI915XvMC->last_flip = 0; @@ -2010,7 +1929,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, pthread_mutex_init(&pI915XvMC->ctxmutex, NULL); intelInitBatchBuffer(pI915XvMC); pI915XvMC->ref = 1; - return Success; + return 0; } /*************************************************************************** @@ -2023,13 +1942,10 @@ Status XvMCCreateContext(Display *display, XvPortID port, // // Returns: Status ***************************************************************************/ -Status XvMCDestroyContext(Display *display, XvMCContext *context) +static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context) { i915XvMCContext *pI915XvMC; - if (!display || !context) - return BadValue; - if (!(pI915XvMC = context->privData)) return (error_base + XvMCBadContext); @@ -2041,7 +1957,7 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context) /*************************************************************************** // Function: XvMCCreateSurface ***************************************************************************/ -Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) +static int i915_xvmc_mc_create_surface(Display *display, XvMCContext *context, XvMCSurface *surface) { Status ret; i915XvMCContext *pI915XvMC; @@ -2121,14 +2037,14 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su pI915XvMC->ref++; PPTHREAD_MUTEX_UNLOCK(pI915XvMC); - return Success; + return 0; } /*************************************************************************** // Function: XvMCDestroySurface ***************************************************************************/ -Status XvMCDestroySurface(Display *display, XvMCSurface *surface) +static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface) { i915XvMCSurface *pI915Surface; i915XvMCContext *pI915XvMC; @@ -2159,87 +2075,6 @@ Status XvMCDestroySurface(Display *display, XvMCSurface *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 @@ -2247,7 +2082,7 @@ Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) // macroblock structures it dispatched the hardware commands to execute // them. ***************************************************************************/ -Status XvMCRenderSurface(Display *display, XvMCContext *context, +static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, unsigned int picture_structure, XvMCSurface *target_surface, XvMCSurface *past_surface, @@ -2256,7 +2091,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context, unsigned int num_macroblocks, unsigned int first_macroblock, XvMCMacroBlockArray *macroblock_array, - XvMCBlockArray *blocks) + XvMCBlockArray *blocks) { int i; int picture_coding_type = MPEG_I_PICTURE; @@ -2444,7 +2279,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context, privTarget->last_render = pI915XvMC->last_render; UNLOCK_HARDWARE(pI915XvMC); - return Success; + return 0; } /*************************************************************************** @@ -2479,7 +2314,7 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context, // possible to catch up before we have to check on its progress. This // makes it unlikely that we have to wait on the last flip. ***************************************************************************/ -Status XvMCPutSurface(Display *display,XvMCSurface *surface, +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, @@ -2545,7 +2380,7 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface, XUnlockDisplay(display); PPTHREAD_MUTEX_UNLOCK(pI915XvMC); - return Success; + return 0; } /*************************************************************************** @@ -2556,6 +2391,7 @@ Status XvMCPutSurface(Display *display,XvMCSurface *surface, // Info: // Returns: Status ***************************************************************************/ +#if 0 Status XvMCSyncSurface(Display *display, XvMCSurface *surface) { Status ret; @@ -2582,6 +2418,7 @@ Status XvMCFlushSurface(Display * display, XvMCSurface *surface) { return Success; } +#endif /*************************************************************************** // Function: XvMCGetSurfaceStatus @@ -2595,7 +2432,7 @@ Status XvMCFlushSurface(Display * display, XvMCSurface *surface) // XVMC_DISPLAYING - The surface is currently being displayed or a // display is pending. ***************************************************************************/ -Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) +static int i915_xvmc_mc_get_surface_status(Display *display, XvMCSurface *surface, int *stat) { i915XvMCSurface *pI915Surface; i915XvMCContext *pI915XvMC; @@ -2643,7 +2480,7 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) // UNLOCK_HARDWARE(pI915XvMC); PPTHREAD_MUTEX_UNLOCK(pI915XvMC); - return Success; + return 0; } /*************************************************************************** @@ -2661,6 +2498,7 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) // // Returns: Status ***************************************************************************/ +#if 0 Status XvMCHideSurface(Display *display, XvMCSurface *surface) { i915XvMCSurface *pI915Surface; @@ -3229,64 +3067,4 @@ Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture, return Success; } -/*************************************************************************** -// 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 -// Notes: -***************************************************************************/ -Status XvMCGetAttribute(Display *display, XvMCContext *context, - Atom attribute, int *value) -{ - return Success; -} +#endif diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am index 0a805fb5..09c8c4de 100644 --- a/src/xvmc/Makefile.am +++ b/src/xvmc/Makefile.am @@ -1,5 +1,5 @@ if DRI -lib_LTLIBRARIES=libI810XvMC.la libI915XvMC.la +lib_LTLIBRARIES=libI810XvMC.la libIntelXvMC.la libI810XvMC_la_SOURCES = I810XvMC.c \ I810XvMC.h @@ -9,9 +9,10 @@ libI810XvMC_la_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ libI810XvMC_la_LDFLAGS = -version-number 1:0:0 libI810XvMC_la_LIBADD = @DRI_LIBS@ -libI915XvMC_la_SOURCES = I915XvMC.c \ - I915XvMC.h \ +libIntelXvMC_la_SOURCES = intel_xvmc.c \ intel_xvmc.h \ + I915XvMC.c \ + I915XvMC.h \ intel_batchbuffer.c \ intel_batchbuffer.h \ xf86dri.c \ @@ -19,7 +20,7 @@ libI915XvMC_la_SOURCES = I915XvMC.c \ xf86dristr.h \ driDrawable.c \ driDrawable.h -libI915XvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0 -libI915XvMC_la_LDFLAGS = -version-number 1:0:0 -libI915XvMC_la_LIBADD = @DRI_LIBS@ +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/intel_xvmc.c b/src/xvmc/intel_xvmc.c new file mode 100644 index 00000000..8c770cee --- /dev/null +++ b/src/xvmc/intel_xvmc.c @@ -0,0 +1,1333 @@ + +/* public interface file */ + +#include <X11/X.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 <xf86drm.h> +#include <drm_sarea.h> + +#include "intel_xvmc.h" +#include "xf86dri.h" +#include "driDrawable.h" + +static struct _intel_xvmc_driver* xvmc_driver = NULL; +static int error_base; +static int event_base; + +/*************************************************************************** +// 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; + uint magic; + int major, minor; + int priv_count; + int isCapable; + + /* Verify Obvious things first */ + if (!display || !context) + return BadValue; + + if (!(flags & XVMC_DIRECT)) { + /* Indirect */ + XVMC_ERR("Indirect Rendering not supported! Using Direct."); + return BadAccess; + } + + /* Limit use to root for now */ + /* FIXME: remove it ??? */ +/* + if (geteuid()) { + printf("Use of XvMC on i915 is currently limited to root\n"); + return BadAccess; + } +*/ + /* + 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 BadAccess; + } + ret = XvMCQueryVersion(display, &major, &minor); + if (ret) { + XVMC_ERR("XvMCQueryVersion Failed, unable to determine protocol version."); + return BadAccess; + } + + /* 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; + } + + comm = (struct _intel_xvmc_common *)priv_data; + XVMC_INFO("hw xvmc type %d", comm->type); + //XXX: how to handle different driver types + 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); + free(priv_data); + priv_data = NULL; + return BadAccess; + } + } else { + XVMC_ERR("wrong hw xvmc type returned\n"); + free(priv_data); + priv_data = NULL; + return BadAccess; + } + + if (xvmc_driver == NULL) { + XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type); + return BadAccess; + } + + /* driver hook should free priv_data after return if success. + * and set xvmc_driver->screen num */ + ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data); + if (ret) { + XVMC_ERR("driver create context failed\n"); + free(priv_data); + return BadAccess; + } + +#if 0 + ret = uniDRIQueryDirectRenderingCapable(display, xvmc_driver->screen, + &isCapable); + if (!ret || !isCapable) { + XVMC_ERR("Direct Rendering is not available on this system!"); + return BadAlloc; + } + + if (!uniDRIOpenConnection(display, xvmc_driver->screen, + &xvmc_driver->hsarea, &curBusID)) { + XVMC_ERR("Could not open DRI connection to X server!"); + return BadAlloc; + } + + strncpy(xvmc_driver->busID, curBusID, 20); + xvmc_driver->busID[20] = '\0'; + free(curBusID); + + /* Open DRI Device */ + if((xvmc_driver->fd = drmOpen("i915", NULL)) < 0) { + XVMC_ERR("DRM Device could not be opened."); + (xvmc_driver->fini)(); + xvmc_driver = NULL; + return BadAccess; + } + + /* Get magic number */ + drmGetMagic(xvmc_driver->fd, &magic); + // context->flags = (unsigned long)magic; + + if (!uniDRIAuthConnection(display, xvmc_driver->screen, magic)) { + XVMC_ERR("[XvMC]: X server did not allow DRI. Check permissions."); + (xvmc_driver->fini)(); + xvmc_driver = NULL; + 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->fini)(); + xvmc_driver = NULL; + return BadAlloc; + } + + pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address; + pI915XvMC->driHwLock = (drmLock *)&pSAREA->lock; + pI915XvMC->sarea = SAREAPTR(pI915XvMC); + XLockDisplay(display); + ret = XMatchVisualInfo(display, pI915XvMC->screen, + (pI915XvMC->depth == 32) ? 24 : pI915XvMC->depth, TrueColor, + &pI915XvMC->visualInfo); + XUnlockDisplay(display); + + if (!ret) { + XVMC_ERR("Could not find a matching TrueColor visual."); + free(pI915XvMC); + context->privData = NULL; + drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size); + return BadAlloc; + } + + if (!uniDRICreateContext(display, pI915XvMC->screen, + pI915XvMC->visualInfo.visual, &pI915XvMC->id, + &pI915XvMC->hHWContext)) { + XVMC_ERR("Could not create DRI context."); + free(pI915XvMC); + context->privData = NULL; + drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size); + return BadAlloc; + } + + if (NULL == (pI915XvMC->drawHash = drmHashCreate())) { + XVMC_ERR("Could not allocate drawable hash table."); + free(pI915XvMC); + context->privData = NULL; + drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size); + return BadAlloc; + } + + if (i915_xvmc_map_buffers(pI915XvMC)) { + i915_xvmc_unmap_buffers(pI915XvMC); + free(pI915XvMC); + context->privData = NULL; + drmUnmap(pI915XvMC->sarea_address, pI915XvMC->sarea_size); + return BadAlloc; + } + + /* Initialize private context values */ + pI915XvMC->yStride = STRIDE(width); + pI915XvMC->uvStride = STRIDE(width >> 1); + pI915XvMC->haveXv = 0; + pI915XvMC->dual_prime = 0; + pI915XvMC->last_flip = 0; + pI915XvMC->locked = 0; + pI915XvMC->port = context->port; + pthread_mutex_init(&pI915XvMC->ctxmutex, NULL); + intelInitBatchBuffer(pI915XvMC); + pI915XvMC->ref = 1; +#endif + + return Success; +} + +/*************************************************************************** +// Function: XvMCDestroyContext +// Description: Destorys the specified context. +// +// Arguments: +// display - Specifies the connection to the server. +// context - The context to be destroyed. +// +// Returns: Status +***************************************************************************/ +Status XvMCDestroyContext(Display *display, XvMCContext *context) +{ + int ret = -1; + if (!display || !context) + return BadValue; + + ret = (xvmc_driver->destroy_context)(display, context); + if (ret) { + XVMC_ERR("destroy context fail\n"); + return BadAccess; + } + + /* Pass Control to the X server to destroy the drm_context_t */ + //XXX move generic destroy method here + //i915_release_resource(display,context); + return Success; +} + +/*************************************************************************** +// Function: XvMCCreateSurface +***************************************************************************/ +Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) +{ + int ret; +// i915XvMCContext *pI915XvMC; +// i915XvMCSurface *pI915Surface; +// I915XvMCCreateSurfaceRec *tmpComm = NULL; +// int priv_count; +// uint *priv_data; + + if (!display || !context || !surface) + return BadValue; + + ret = (xvmc_driver->create_surface)(display, context, surface); + if (ret) { + XVMC_ERR("create surface failed\n"); + return BadAccess; + } + +#if 0 + if (!(pI915XvMC = context->privData)) + return (error_base + XvMCBadContext); + + PPTHREAD_MUTEX_LOCK(pI915XvMC); + surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface)); + + if (!(pI915Surface = surface->privData)) { + PPTHREAD_MUTEX_UNLOCK(pI915XvMC); + 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; + XLockDisplay(display); + + if ((ret = _xvmc_create_surface(display, context, surface, + &priv_count, &priv_data))) { + XUnlockDisplay(display); + XVMC_ERR("Unable to create XvMCSurface."); + free(pI915Surface); + surface->privData = NULL; + PPTHREAD_MUTEX_UNLOCK(pI915XvMC); + return ret; + } + + XUnlockDisplay(display); + + 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); + free(priv_data); + free(pI915Surface); + surface->privData = NULL; + PPTHREAD_MUTEX_UNLOCK(pI915XvMC); + return BadAlloc; + } + + 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; + free(priv_data); + + if (drmMap(pI915XvMC->fd, + pI915Surface->srf.handle, + pI915Surface->srf.size, + (drmAddress *)&pI915Surface->srf.map) != 0) { + _xvmc_destroy_surface(display, surface); + free(pI915Surface); + surface->privData = NULL; + PPTHREAD_MUTEX_UNLOCK(pI915XvMC); + return BadAlloc; + } + + pI915XvMC->ref++; + PPTHREAD_MUTEX_UNLOCK(pI915XvMC); +#endif + + return Success; +} + + +/*************************************************************************** +// Function: XvMCDestroySurface +***************************************************************************/ +Status XvMCDestroySurface(Display *display, XvMCSurface *surface) +{ +// i915XvMCSurface *pI915Surface; +// i915XvMCContext *pI915XvMC; + + if (!display || !surface) + return BadValue; + + (xvmc_driver->destroy_surface)(display, surface); + +#if 0 + if (!(pI915Surface = surface->privData)) + return (error_base + XvMCBadSurface); + + if (!(pI915XvMC = pI915Surface->privContext)) + return (error_base + XvMCBadSurface); + + if (pI915Surface->last_flip) + XvMCSyncSurface(display,surface); + + if (pI915Surface->srf.map) + drmUnmap(pI915Surface->srf.map, pI915Surface->srf.size); + + XLockDisplay(display); + _xvmc_destroy_surface(display, surface); + XUnlockDisplay(display); + + free(pI915Surface); + surface->privData = NULL; + pI915XvMC->ref--; +#endif + + 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) +{ + int ret; + + if (!display || !context || !target_surface) { + XVMC_ERR("Invalid Display, Context or Target!"); + return BadValue; + } + + 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 BadAccess; + } +#if 0 + 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; + + i915XvMCSurface *privTarget = NULL; + i915XvMCSurface *privFuture = NULL; + i915XvMCSurface *privPast = NULL; + i915XvMCContext *pI915XvMC = NULL; + + /* 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 (error_base + XvMCBadContext); + + if (!(privTarget = target_surface->privData)) + return (error_base + XvMCBadSurface); + + /* Test For YV12 Surface */ + if (context->surface_type_id != FOURCC_YV12) { + XVMC_ERR("HWMC only possible on YV12 Surfaces."); + 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 (error_base + 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 (error_base + XvMCBadSurface); + } + + picture_coding_type = MPEG_B_PICTURE; + } + + LOCK_HARDWARE(pI915XvMC); + corrdata_ptr = pI915XvMC->corrdata.map; + corrdata_size = 0; + + for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) { + int bspm = 0; + mb = ¯oblock_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(pI915XvMC, 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, ¯oblock_array->macro_blocks[first_macroblock]); + + for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) { + mb = ¯oblock_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 */ + renderError(); + 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 */ + renderError(); + break; + } + } /* Field Picture */ + } + + intelFlushBatch(pI915XvMC, TRUE); + pI915XvMC->last_render = pI915XvMC->alloc.irq_emitted; + privTarget->last_render = pI915XvMC->last_render; + + UNLOCK_HARDWARE(pI915XvMC); +#endif + 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. +// +// Info: Portions of this function derived from i915_video.c (XFree86) +// +// This function is organized so that we wait as long as possible before +// touching the overlay registers. Since we don't know that the last +// flip has happened yet we want to give the overlay as long as +// possible to catch up before we have to check on its progress. This +// makes it unlikely that we have to wait on the last flip. +***************************************************************************/ +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) +{ + int ret = -1; + + if (!display || !surface) + return BadValue; + + ret = (xvmc_driver->put_surface)(display, surface, draw, srcx, srcy, + srcw, srch, destx, desty, destw, desth, flags); + if (ret) { + XVMC_ERR("put surface fail\n"); + return BadAccess; + } + +#if 0 + i915XvMCContext *pI915XvMC; + i915XvMCSurface *pI915Surface; + i915XvMCSubpicture *pI915SubPic; + I915XvMCCommandBuffer buf; + + // drawableInfo *drawInfo; + Status ret; + + if (!display || !surface) + return BadValue; + + if (!(pI915Surface = surface->privData)) + return (error_base + XvMCBadSurface); + + if (!(pI915XvMC = pI915Surface->privContext)) + return (error_base + XvMCBadSurface); + + PPTHREAD_MUTEX_LOCK(pI915XvMC); + /* + if (getDRIDrawableInfoLocked(pI915XvMC->drawHash, display, + pI915XvMC->screen, draw, 0, pI915XvMC->fd, pI915XvMC->hHWContext, + pI915XvMC->sarea_address, FALSE, &drawInfo, sizeof(*drawInfo))) { + PPTHREAD_MUTEX_UNLOCK(pI915XvMC); + return BadAccess; + } + */ + if (!pI915XvMC->haveXv) { + pI915XvMC->xvImage = + XvCreateImage(display, pI915XvMC->port, FOURCC_XVMC, + (char *)&buf, pI915Surface->width, pI915Surface->height); + pI915XvMC->gc = XCreateGC(display, draw, 0, 0); + pI915XvMC->haveXv = 1; + } + + pI915XvMC->draw = draw; + pI915XvMC->xvImage->data = (char *)&buf; + + buf.command = INTEL_XVMC_COMMAND_DISPLAY; + buf.ctxNo = pI915XvMC->ctxno; + buf.srfNo = pI915Surface->srfNo; + pI915SubPic = pI915Surface->privSubPic; + buf.subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo); + buf.real_id = FOURCC_YV12; + + XLockDisplay(display); + + if ((ret = XvPutImage(display, pI915XvMC->port, draw, pI915XvMC->gc, + pI915XvMC->xvImage, srcx, srcy, srcw, srch, + destx, desty, destw, desth))) { + XUnlockDisplay(display); + PPTHREAD_MUTEX_UNLOCK(pI915XvMC); + + return ret; + } + + XSync(display, 0); + XUnlockDisplay(display); + PPTHREAD_MUTEX_UNLOCK(pI915XvMC); +#endif + + return Success; +} + +/*************************************************************************** +// Function: XvMCSyncSurface +// Arguments: +// display - Connection to the X server +// surface - The surface to synchronize +// Info: +// Returns: Status +***************************************************************************/ +Status XvMCSyncSurface(Display *display, XvMCSurface *surface) +{ + Status ret; + int stat = 0; + + 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) +{ + 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) +{ + int ret = -1; + + if (!display || !surface || !stat) + return BadValue; + + ret = (xvmc_driver->get_surface_status)(display, surface, stat); + if (ret) { + XVMC_ERR("get surface status fail\n"); + return BadAccess; + } + +#if 0 + i915XvMCSurface *pI915Surface; + i915XvMCContext *pI915XvMC; + + if (!display || !surface || !stat) + return BadValue; + + *stat = 0; + + if (!(pI915Surface = surface->privData)) + return (error_base + XvMCBadSurface); + + if (!(pI915XvMC = pI915Surface->privContext)) + return (error_base + XvMCBadSurface); + + // LOCK_HARDWARE(pI915XvMC); + PPTHREAD_MUTEX_LOCK(pI915XvMC); + 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(pI915XvMC); + 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; + } + + // UNLOCK_HARDWARE(pI915XvMC); + PPTHREAD_MUTEX_UNLOCK(pI915XvMC); +#endif + + return Success; +} + +/*************************************************************************** +// +// Surface manipulation functions +// +***************************************************************************/ + +/*************************************************************************** +// Function: XvMCHideSurface +// Description: Stops the display of a surface. +// Arguments: +// display - Connection to the X server. +// surface - surface to be hidden. +// +// Returns: Status +***************************************************************************/ +//XXX this seems broken now +Status XvMCHideSurface(Display *display, XvMCSurface *surface) +{ +// i915XvMCSurface *pI915Surface; +// i915XvMCContext *pI915XvMC; + int stat = 0, ret; + + if (!display || !surface) + return BadValue; + +#if 0 + if (!(pI915Surface = surface->privData)) + return (error_base + XvMCBadSurface); + + /* Get the associated context pointer */ + if (!(pI915XvMC = pI915Surface->privContext)) + return (error_base + XvMCBadSurface); +#endif + + 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; +} + +/*************************************************************************** +// +// Functions that deal with subpictures +// +***************************************************************************/ + + + +/*************************************************************************** +// 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + return BadValue; +#if 0 + Status ret; + int stat = 0; + + if (!display || !subpicture) + + do { + ret = XvMCGetSubpictureStatus(display, subpicture, &stat); + } while(!ret && (stat & XVMC_RENDERING)); + + return ret; +#endif +} + +/*************************************************************************** +// 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) +{ + return BadValue; +#if 0 + i915XvMCSubpicture *pI915Subpicture; + + if (!display || !subpicture) + return BadValue; + + if (!(pI915Subpicture = subpicture->privData)) + return (error_base + XvMCBadSubpicture); + + return Success; +#endif +} + +/*************************************************************************** +// 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) +{ + return BadValue; +#if 0 + i915XvMCSubpicture *pI915Subpicture; + i915XvMCContext *pI915XvMC; + + if (!display || !subpicture || stat) + return BadValue; + + *stat = 0; + + if (!(pI915Subpicture = subpicture->privData)) + return (error_base + XvMCBadSubpicture); + + if (!(pI915XvMC = pI915Subpicture->privContext)) + return (error_base + XvMCBadSubpicture); + + // LOCK_HARDWARE(pI915XvMC); + PPTHREAD_MUTEX_LOCK(pI915XvMC); + /* FIXME: */ + if (pI915Subpicture->last_render && + (pI915Subpicture->last_render > pI915XvMC->sarea->last_dispatch)) { + *stat |= XVMC_RENDERING; + } + + // UNLOCK_HARDWARE(pI915XvMC); + PPTHREAD_MUTEX_UNLOCK(pI915XvMC); + return Success; +#endif +} + +/*************************************************************************** +// 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 +// Notes: +***************************************************************************/ +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 index 0726be43..1d6ff712 100644 --- a/src/xvmc/intel_xvmc.h +++ b/src/xvmc/intel_xvmc.h @@ -2,12 +2,31 @@ #ifndef INTEL_XVMC_H #define INTEL_XVMC_H -#include "xf86drm.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/Xlibint.h> #include <X11/Xutil.h> -#include <signal.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" #define DEBUG 0 @@ -35,7 +54,7 @@ when a HW independent libXvMC is created. */ extern Status _xvmc_create_context(Display *dpy, XvMCContext *context, - int *priv_count, uint **priv_data); + int *priv_count, CARD32 **priv_data); extern Status _xvmc_destroy_context(Display *dpy, XvMCContext *context); @@ -52,4 +71,44 @@ extern Status _xvmc_create_subpicture(Display *dpy, XvMCContext *context, extern Status _xvmc_destroy_subpicture(Display *dpy, XvMCSubpicture *subpicture); + +struct _intel_xvmc_driver { + int type; /* hw xvmc type - i830_hwmc.h */ + int screen; /* current screen num*/ +#if 0 + drm_handle_t hsarea; /* DRI open connect */ + unsigned int sarea_size; + drmAddress sarea_address; +#endif + char busID[32]; + int fd; /* drm file handler */ + void *private; + /* XXX: api hooks */ + int (*init)(/*XXX*/); + void (*fini)(/*XXX*/); + int (*create_context)(Display* display, XvMCContext *context, int priv_count, CARD32 *priv_data); + int (*destroy_context)(Display* display, XvMCContext *context); + int (*create_surface)(Display* display, XvMCContext *context, XvMCSurface *surface); + int (*destroy_surface)(Display* display, XvMCSurface *surface); + int (*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 (*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); + int (*get_surface_status)(Display *display, XvMCSurface *surface, int *stat); +}; + +extern struct _intel_xvmc_driver i915_xvmc_mc_driver; + #endif |