1/*
2 * Copyright © 2007 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 *    Zhenyu Wang <zhenyu.z.wang@intel.com>
25 *
26 */
27#ifndef INTEL_XVMC_H
28#define INTEL_XVMC_H
29
30#include <pthread.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <unistd.h>
34#include <errno.h>
35#include <signal.h>
36#include <fcntl.h>
37#include <dirent.h>
38#include <string.h>
39#include <assert.h>
40#include <signal.h>
41#include <stdint.h>
42
43#include <xf86drm.h>
44#include "i830_common.h"
45#include "i830_hwmc.h"
46#include <X11/X.h>
47#include <X11/Xlibint.h>
48#include <X11/Xutil.h>
49#include <fourcc.h>
50#include <X11/extensions/Xv.h>
51#include <X11/extensions/Xvlib.h>
52#include <X11/extensions/XvMC.h>
53#include <X11/extensions/XvMClib.h>
54#include <X11/extensions/vldXvMC.h>
55#include <drm_sarea.h>
56#include "i915_drm.h"
57#include "intel_bufmgr.h"
58
59#include "intel_batchbuffer.h"
60
61extern int DEBUG;
62
63#define XVMC_ERR(s, arg...)					\
64    do {							\
65	fprintf(stderr, "[intel_xvmc] err: " s "\n", ##arg);	\
66    } while (0)
67
68#define XVMC_INFO(s, arg...)					\
69    do {							\
70	fprintf(stderr, "[intel_xvmc] info: " s "\n", ##arg);	\
71    } while (0)
72
73#define XVMC_DBG(s, arg...)						\
74    do {								\
75	if (DEBUG)							\
76	    fprintf(stderr, "[intel_xvmc] debug: " s "\n", ##arg);	\
77    } while (0)
78
79/* Subpicture fourcc */
80#define FOURCC_IA44 0x34344149
81
82/*
83  Definitions for temporary wire protocol hooks to be replaced
84  when a HW independent libXvMC is created.
85*/
86extern Status _xvmc_create_context(Display *dpy, XvMCContext *context,
87				   int *priv_count, CARD32 **priv_data);
88
89extern Status _xvmc_destroy_context(Display *dpy, XvMCContext *context);
90
91extern Status _xvmc_create_surface(Display *dpy, XvMCContext *context,
92				   XvMCSurface *surface, int *priv_count,
93				   CARD32 **priv_data);
94
95extern Status _xvmc_destroy_surface(Display *dpy, XvMCSurface *surface);
96
97extern Status  _xvmc_create_subpicture(Display *dpy, XvMCContext *context,
98				       XvMCSubpicture *subpicture,
99				       int *priv_count, uint **priv_data);
100
101extern Status   _xvmc_destroy_subpicture(Display *dpy,
102					 XvMCSubpicture *subpicture);
103
104typedef struct _intel_xvmc_context {
105    XvMCContext *context;
106    drm_context_t hw_context;	/* context id to kernel drm */
107    struct _intel_xvmc_context *next;
108} intel_xvmc_context_t, *intel_xvmc_context_ptr;
109
110typedef struct _intel_xvmc_surface {
111    XvMCSurface *surface;
112    XvImage *image;
113    GC gc;
114    Bool gc_init;
115    Drawable last_draw;
116    struct intel_xvmc_command data;
117    struct _intel_xvmc_surface *next;
118} intel_xvmc_surface_t, *intel_xvmc_surface_ptr;
119
120typedef struct _intel_xvmc_drm_map {
121    drm_handle_t handle;
122    unsigned long offset;
123    unsigned long size;
124    unsigned long bus_addr;
125    drmAddress map;
126} intel_xvmc_drm_map_t, *intel_xvmc_drm_map_ptr;
127
128typedef struct _intel_xvmc_driver {
129    int type;			/* hw xvmc type - i830_hwmc.h */
130    int screen;			/* current screen num*/
131
132    int fd;			/* drm file handler */
133
134    dri_bufmgr      *bufmgr;
135    unsigned int kernel_exec_fencing:1;
136
137    struct {
138	unsigned int init_offset;
139	unsigned int size;
140	unsigned int space;
141	unsigned char *ptr;
142	unsigned char *init_ptr;
143	dri_bo *buf;
144    } batch;
145
146    struct
147    {
148        void *ptr;
149        unsigned int size;
150        unsigned int offset;
151        unsigned int active_buf;
152        unsigned int irq_emitted;
153    } alloc;
154    intel_xvmc_drm_map_t batchbuffer;
155    unsigned int last_render;
156
157    sigset_t sa_mask;
158    pthread_mutex_t ctxmutex;
159    int locked;
160
161    int num_ctx;
162    intel_xvmc_context_ptr ctx_list;
163    int num_surf;
164    intel_xvmc_surface_ptr surf_list;
165
166    void *private;
167
168    /* driver specific xvmc callbacks */
169    Status (*create_context)(Display* display, XvMCContext *context,
170	    int priv_count, CARD32 *priv_data);
171
172    Status (*destroy_context)(Display* display, XvMCContext *context);
173
174    Status (*create_surface)(Display* display, XvMCContext *context,
175	    XvMCSurface *surface, int priv_count, CARD32 *priv_data);
176
177    Status (*destroy_surface)(Display* display, XvMCSurface *surface);
178
179    Status (*render_surface)(Display *display, XvMCContext *context,
180	    unsigned int picture_structure,
181	    XvMCSurface *target_surface,
182	    XvMCSurface *past_surface,
183	    XvMCSurface *future_surface,
184	    unsigned int flags,
185	    unsigned int num_macroblocks,
186	    unsigned int first_macroblock,
187	    XvMCMacroBlockArray *macroblock_array,
188	    XvMCBlockArray *blocks);
189
190    Status (*put_surface)(Display *display, XvMCSurface *surface,
191	    Drawable draw, short srcx, short srcy,
192	    unsigned short srcw, unsigned short srch,
193	    short destx, short desty,
194	    unsigned short destw, unsigned short desth,
195	    int flags, struct intel_xvmc_command *data);
196
197    Status (*get_surface_status)(Display *display, XvMCSurface *surface, int *stat);
198
199    Status (*begin_surface)(Display *display, XvMCContext *context,
200	    XvMCSurface *target_surface,
201	    XvMCSurface *past_surface,
202	    XvMCSurface *future_surface,
203	    const XvMCMpegControl *control);
204    Status (*load_qmatrix)(Display *display, XvMCContext *context,
205	    	const XvMCQMatrix *qmx);
206    Status (*put_slice)(Display *display, XvMCContext *context,
207	    	unsigned char *slice, int bytes);
208    Status (*put_slice2)(Display *display, XvMCContext *context,
209	    	unsigned char *slice, int bytes, int slice_code);
210
211} intel_xvmc_driver_t, *intel_xvmc_driver_ptr;
212
213extern struct _intel_xvmc_driver i915_xvmc_mc_driver;
214extern struct _intel_xvmc_driver i965_xvmc_mc_driver;
215extern struct _intel_xvmc_driver xvmc_vld_driver;
216extern struct _intel_xvmc_driver *xvmc_driver;
217
218#define SET_BLOCKED_SIGSET()   do {    \
219        sigset_t bl_mask;                       \
220        sigfillset(&bl_mask);           \
221        sigdelset(&bl_mask, SIGFPE);    \
222        sigdelset(&bl_mask, SIGILL);    \
223        sigdelset(&bl_mask, SIGSEGV);   \
224        sigdelset(&bl_mask, SIGBUS);    \
225        sigdelset(&bl_mask, SIGKILL);   \
226        pthread_sigmask(SIG_SETMASK, &bl_mask, &xvmc_driver->sa_mask); \
227    } while (0)
228
229#define RESTORE_BLOCKED_SIGSET() do {    \
230        pthread_sigmask(SIG_SETMASK, &xvmc_driver->sa_mask, NULL); \
231    } while (0)
232
233#define PPTHREAD_MUTEX_LOCK() do {             \
234        SET_BLOCKED_SIGSET();                  \
235        pthread_mutex_lock(&xvmc_driver->ctxmutex);       \
236    } while (0)
237
238#define PPTHREAD_MUTEX_UNLOCK() do {           \
239        pthread_mutex_unlock(&xvmc_driver->ctxmutex);     \
240        RESTORE_BLOCKED_SIGSET();              \
241    } while (0)
242
243extern void LOCK_HARDWARE(drm_context_t);
244extern void UNLOCK_HARDWARE(drm_context_t);
245
246static inline const char* intel_xvmc_decoder_string(int flag)
247{
248    switch (flag) {
249	case XVMC_I915_MPEG2_MC:
250	    return "i915/945 MPEG2 MC decoder";
251	case XVMC_I965_MPEG2_MC:
252	    return "i965 MPEG2 MC decoder";
253	case XVMC_I945_MPEG2_VLD:
254	    return "i945 MPEG2 VLD decoder";
255	case XVMC_I965_MPEG2_VLD:
256	    return "i965 MPEG2 VLD decoder";
257	default:
258	    return "Unknown decoder";
259    }
260}
261
262extern intel_xvmc_context_ptr intel_xvmc_find_context(XID id);
263extern intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id);
264
265extern unsigned int mb_bytes_420[64];
266
267/* dump function */
268extern void intel_xvmc_dump_open(void);
269extern void intel_xvmc_dump_close(void);
270extern void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure,
271	    XvMCSurface *target_surface, XvMCSurface *past_surface,
272	    XvMCSurface *future_surface, unsigned int flags,
273	    unsigned int num_macroblocks, unsigned int first_macroblock,
274	    XvMCMacroBlockArray *macroblock_array, XvMCBlockArray *blocks);
275
276
277#define	VFE_GENERIC_MODE	0x0
278#define	VFE_VLD_MODE		0x1
279#define VFE_IS_MODE		0x2
280#define VFE_AVC_MC_MODE		0x4
281#define VFE_AVC_IT_MODE		0x7
282#define VFE_VC1_IT_MODE		0x7
283
284#endif
285