Initial code release
[profile/ivi/xorg-x11-drv-intel.git] / src / intel_hwmc.c
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 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #define _INTEL_XVMC_SERVER_
32 #include "intel.h"
33 #include "intel_hwmc.h"
34
35 #include <X11/extensions/Xv.h>
36 #include <X11/extensions/XvMC.h>
37 #include <fourcc.h>
38
39 static int create_subpicture(ScrnInfoPtr scrn, XvMCSubpicturePtr subpicture,
40                              int *num_priv, CARD32 ** priv)
41 {
42         return Success;
43 }
44
45 static void destroy_subpicture(ScrnInfoPtr scrn, XvMCSubpicturePtr subpicture)
46 {
47 }
48
49 static int create_surface(ScrnInfoPtr scrn, XvMCSurfacePtr surface,
50                           int *num_priv, CARD32 ** priv)
51 {
52         return Success;
53 }
54
55 static void destroy_surface(ScrnInfoPtr scrn, XvMCSurfacePtr surface)
56 {
57 }
58
59 static int create_context(ScrnInfoPtr scrn, XvMCContextPtr pContext,
60                                     int *num_priv, CARD32 **priv)
61 {
62         intel_screen_private *intel = intel_get_screen_private(scrn);
63         struct intel_xvmc_hw_context *contextRec;
64
65         *priv = calloc(1, sizeof(struct intel_xvmc_hw_context));
66         contextRec = (struct intel_xvmc_hw_context *) *priv;
67         if (!contextRec) {
68                 *num_priv = 0;
69                 return BadAlloc;
70         }
71
72         *num_priv = sizeof(struct intel_xvmc_hw_context) >> 2;
73
74         if (IS_GEN3(intel)) {
75                 contextRec->type = XVMC_I915_MPEG2_MC;
76                 contextRec->i915.use_phys_addr = 0;
77         } else {
78                 if (INTEL_INFO(intel)->gen >= 45)
79                         contextRec->type = XVMC_I965_MPEG2_VLD;
80                 else
81                         contextRec->type = XVMC_I965_MPEG2_MC;
82                 contextRec->i965.is_g4x = INTEL_INFO(intel)->gen == 45;
83                 contextRec->i965.is_965_q = IS_965_Q(intel);
84                 contextRec->i965.is_igdng = IS_GEN5(intel);
85         }
86
87         return Success;
88 }
89
90 static void destroy_context(ScrnInfoPtr scrn, XvMCContextPtr context)
91 {
92 }
93
94 /* i915 hwmc support */
95 static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface = {
96         FOURCC_YV12,
97         XVMC_CHROMA_FORMAT_420,
98         0,
99         720,
100         576,
101         720,
102         576,
103         XVMC_MPEG_2,
104         /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */
105         0,
106         /* &yv12_subpicture_list */
107         NULL,
108 };
109
110 static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface = {
111         FOURCC_YV12,
112         XVMC_CHROMA_FORMAT_420,
113         0,
114         720,
115         576,
116         720,
117         576,
118         XVMC_MPEG_1,
119         /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */
120         0,
121         NULL,
122 };
123
124 static XF86MCSurfaceInfoPtr surface_info_i915[2] = {
125         (XF86MCSurfaceInfoPtr) & i915_YV12_mpg2_surface,
126         (XF86MCSurfaceInfoPtr) & i915_YV12_mpg1_surface
127 };
128
129 /* i965 and later hwmc support */
130 #ifndef XVMC_VLD
131 #define XVMC_VLD  0x00020000
132 #endif
133
134 static XF86MCSurfaceInfoRec yv12_mpeg2_vld_surface = {
135         FOURCC_YV12,
136         XVMC_CHROMA_FORMAT_420,
137         0,
138         1936,
139         1096,
140         1920,
141         1080,
142         XVMC_MPEG_2 | XVMC_VLD,
143         XVMC_INTRA_UNSIGNED,
144         NULL
145 };
146
147 static XF86MCSurfaceInfoRec yv12_mpeg2_i965_surface = {
148         FOURCC_YV12,
149         XVMC_CHROMA_FORMAT_420,
150         0,
151         1936,
152         1096,
153         1920,
154         1080,
155         XVMC_MPEG_2 | XVMC_MOCOMP,
156         /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */
157         XVMC_INTRA_UNSIGNED,
158         /* &yv12_subpicture_list */
159         NULL
160 };
161
162 static XF86MCSurfaceInfoRec yv12_mpeg1_i965_surface = {
163         FOURCC_YV12,
164         XVMC_CHROMA_FORMAT_420,
165         0,
166         1920,
167         1080,
168         1920,
169         1080,
170         XVMC_MPEG_1 | XVMC_MOCOMP,
171         /*XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
172            XVMC_INTRA_UNSIGNED, */
173         XVMC_INTRA_UNSIGNED,
174
175         /*&yv12_subpicture_list */
176         NULL
177 };
178
179 static XF86MCSurfaceInfoPtr surface_info_i965[] = {
180         &yv12_mpeg2_i965_surface,
181         &yv12_mpeg1_i965_surface
182 };
183
184 static XF86MCSurfaceInfoPtr surface_info_vld[] = {
185         &yv12_mpeg2_vld_surface,
186         &yv12_mpeg2_i965_surface,
187 };
188
189 /* check chip type and load xvmc driver */
190 Bool intel_xvmc_adaptor_init(ScreenPtr pScreen)
191 {
192         ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
193         intel_screen_private *intel = intel_get_screen_private(scrn);
194         static XF86MCAdaptorRec *pAdapt;
195         char *name;
196         char buf[64];
197
198         if (!intel->XvMCEnabled)
199                 return FALSE;
200
201         /* Needs KMS support. */
202         if (IS_I915G(intel) || IS_I915GM(intel))
203                 return FALSE;
204
205         if (IS_GEN2(intel)) {
206                 ErrorF("Your chipset doesn't support XvMC.\n");
207                 return FALSE;
208         }
209
210         pAdapt = calloc(1, sizeof(XF86MCAdaptorRec));
211         if (!pAdapt) {
212                 ErrorF("Allocation error.\n");
213                 return FALSE;
214         }
215
216         pAdapt->name = "Intel(R) Textured Video";
217         pAdapt->num_subpictures = 0;
218         pAdapt->subpictures = NULL;
219         pAdapt->CreateContext = create_context;
220         pAdapt->DestroyContext = destroy_context;
221         pAdapt->CreateSurface = create_surface;
222         pAdapt->DestroySurface = destroy_surface;
223         pAdapt->CreateSubpicture =  create_subpicture;
224         pAdapt->DestroySubpicture = destroy_subpicture;
225
226         if (IS_GEN3(intel)) {
227                 name = "i915_xvmc",
228                 pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i915);
229                 pAdapt->surfaces = surface_info_i915;
230         } else if (INTEL_INFO(intel)->gen >= 45) {
231                 name = "xvmc_vld",
232                 pAdapt->num_surfaces = ARRAY_SIZE(surface_info_vld);
233                 pAdapt->surfaces = surface_info_vld;
234         } else {
235                 name = "i965_xvmc",
236                 pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i965);
237                 pAdapt->surfaces = surface_info_i965;
238         }
239
240         if (xf86XvMCScreenInit(pScreen, 1, &pAdapt)) {
241                 xf86DrvMsg(scrn->scrnIndex, X_INFO,
242                            "[XvMC] %s driver initialized.\n",
243                            name);
244         } else {
245                 intel->XvMCEnabled = FALSE;
246                 xf86DrvMsg(scrn->scrnIndex, X_INFO,
247                            "[XvMC] Failed to initialize XvMC.\n");
248                 return FALSE;
249         }
250
251         sprintf(buf, "pci:%04x:%02x:%02x.%d",
252                 intel->PciInfo->domain,
253                 intel->PciInfo->bus, intel->PciInfo->dev, intel->PciInfo->func);
254
255         xf86XvMCRegisterDRInfo(pScreen, INTEL_XVMC_LIBNAME,
256                                buf,
257                                INTEL_XVMC_MAJOR, INTEL_XVMC_MINOR,
258                                INTEL_XVMC_PATCHLEVEL);
259         return TRUE;
260 }