1428d7b3dSmrg/*
2428d7b3dSmrg * Copyright © 2007 Intel Corporation
3428d7b3dSmrg *
4428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5428d7b3dSmrg * copy of this software and associated documentation files (the "Software"),
6428d7b3dSmrg * to deal in the Software without restriction, including without limitation
7428d7b3dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8428d7b3dSmrg * and/or sell copies of the Software, and to permit persons to whom the
9428d7b3dSmrg * Software is furnished to do so, subject to the following conditions:
10428d7b3dSmrg *
11428d7b3dSmrg * The above copyright notice and this permission notice (including the next
12428d7b3dSmrg * paragraph) shall be included in all copies or substantial portions of the
13428d7b3dSmrg * Software.
14428d7b3dSmrg *
15428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16428d7b3dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17428d7b3dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18428d7b3dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19428d7b3dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20428d7b3dSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21428d7b3dSmrg * SOFTWARE.
22428d7b3dSmrg *
23428d7b3dSmrg * Authors:
24428d7b3dSmrg *    Zhenyu Wang <zhenyu.z.wang@intel.com>
25428d7b3dSmrg *
26428d7b3dSmrg */
27428d7b3dSmrg#ifdef HAVE_CONFIG_H
28428d7b3dSmrg#include "config.h"
29428d7b3dSmrg#endif
30428d7b3dSmrg
31428d7b3dSmrg#define _INTEL_XVMC_SERVER_
32428d7b3dSmrg#include "intel.h"
33428d7b3dSmrg#include "intel_xvmc.h"
34428d7b3dSmrg
35428d7b3dSmrg#include <X11/extensions/Xv.h>
36428d7b3dSmrg#include <X11/extensions/XvMC.h>
37428d7b3dSmrg#include <fourcc.h>
38428d7b3dSmrg
39428d7b3dSmrgstatic int create_subpicture(ScrnInfoPtr scrn, XvMCSubpicturePtr subpicture,
40428d7b3dSmrg			     int *num_priv, CARD32 ** priv)
41428d7b3dSmrg{
42428d7b3dSmrg	return Success;
43428d7b3dSmrg}
44428d7b3dSmrg
45428d7b3dSmrgstatic void destroy_subpicture(ScrnInfoPtr scrn, XvMCSubpicturePtr subpicture)
46428d7b3dSmrg{
47428d7b3dSmrg}
48428d7b3dSmrg
49428d7b3dSmrgstatic int create_surface(ScrnInfoPtr scrn, XvMCSurfacePtr surface,
50428d7b3dSmrg			  int *num_priv, CARD32 ** priv)
51428d7b3dSmrg{
52428d7b3dSmrg	return Success;
53428d7b3dSmrg}
54428d7b3dSmrg
55428d7b3dSmrgstatic void destroy_surface(ScrnInfoPtr scrn, XvMCSurfacePtr surface)
56428d7b3dSmrg{
57428d7b3dSmrg}
58428d7b3dSmrg
59428d7b3dSmrgstatic int create_context(ScrnInfoPtr scrn, XvMCContextPtr pContext,
60428d7b3dSmrg				    int *num_priv, CARD32 **priv)
61428d7b3dSmrg{
62428d7b3dSmrg	intel_screen_private *intel = intel_get_screen_private(scrn);
63428d7b3dSmrg	struct intel_xvmc_hw_context *contextRec;
64428d7b3dSmrg
65428d7b3dSmrg	*priv = calloc(1, sizeof(struct intel_xvmc_hw_context));
66428d7b3dSmrg	contextRec = (struct intel_xvmc_hw_context *) *priv;
67428d7b3dSmrg	if (!contextRec) {
68428d7b3dSmrg		*num_priv = 0;
69428d7b3dSmrg		return BadAlloc;
70428d7b3dSmrg	}
71428d7b3dSmrg
72428d7b3dSmrg	*num_priv = sizeof(struct intel_xvmc_hw_context) >> 2;
73428d7b3dSmrg
74428d7b3dSmrg	if (IS_GEN3(intel)) {
75428d7b3dSmrg		contextRec->type = XVMC_I915_MPEG2_MC;
76428d7b3dSmrg		contextRec->i915.use_phys_addr = 0;
77428d7b3dSmrg	} else {
78428d7b3dSmrg		if (INTEL_INFO(intel)->gen >= 045)
79428d7b3dSmrg			contextRec->type = XVMC_I965_MPEG2_VLD;
80428d7b3dSmrg		else
81428d7b3dSmrg			contextRec->type = XVMC_I965_MPEG2_MC;
82428d7b3dSmrg		contextRec->i965.is_g4x = INTEL_INFO(intel)->gen == 045;
83428d7b3dSmrg		contextRec->i965.is_965_q = IS_965_Q(intel);
84428d7b3dSmrg		contextRec->i965.is_igdng = IS_GEN5(intel);
85428d7b3dSmrg	}
86428d7b3dSmrg
87428d7b3dSmrg	return Success;
88428d7b3dSmrg}
89428d7b3dSmrg
90428d7b3dSmrgstatic void destroy_context(ScrnInfoPtr scrn, XvMCContextPtr context)
91428d7b3dSmrg{
92428d7b3dSmrg}
93428d7b3dSmrg
94428d7b3dSmrg/* i915 hwmc support */
95428d7b3dSmrgstatic XF86MCSurfaceInfoRec i915_YV12_mpg2_surface = {
96428d7b3dSmrg	FOURCC_YV12,
97428d7b3dSmrg	XVMC_CHROMA_FORMAT_420,
98428d7b3dSmrg	0,
99428d7b3dSmrg	720,
100428d7b3dSmrg	576,
101428d7b3dSmrg	720,
102428d7b3dSmrg	576,
103428d7b3dSmrg	XVMC_MPEG_2,
104428d7b3dSmrg	/* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */
105428d7b3dSmrg	0,
106428d7b3dSmrg	/* &yv12_subpicture_list */
107428d7b3dSmrg	NULL,
108428d7b3dSmrg};
109428d7b3dSmrg
110428d7b3dSmrgstatic XF86MCSurfaceInfoRec i915_YV12_mpg1_surface = {
111428d7b3dSmrg	FOURCC_YV12,
112428d7b3dSmrg	XVMC_CHROMA_FORMAT_420,
113428d7b3dSmrg	0,
114428d7b3dSmrg	720,
115428d7b3dSmrg	576,
116428d7b3dSmrg	720,
117428d7b3dSmrg	576,
118428d7b3dSmrg	XVMC_MPEG_1,
119428d7b3dSmrg	/* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */
120428d7b3dSmrg	0,
121428d7b3dSmrg	NULL,
122428d7b3dSmrg};
123428d7b3dSmrg
124428d7b3dSmrgstatic XF86MCSurfaceInfoPtr surface_info_i915[2] = {
125428d7b3dSmrg	(XF86MCSurfaceInfoPtr) & i915_YV12_mpg2_surface,
126428d7b3dSmrg	(XF86MCSurfaceInfoPtr) & i915_YV12_mpg1_surface
127428d7b3dSmrg};
128428d7b3dSmrg
129428d7b3dSmrg/* i965 and later hwmc support */
130428d7b3dSmrg#ifndef XVMC_VLD
131428d7b3dSmrg#define XVMC_VLD  0x00020000
132428d7b3dSmrg#endif
133428d7b3dSmrg
134428d7b3dSmrgstatic XF86MCSurfaceInfoRec yv12_mpeg2_vld_surface = {
135428d7b3dSmrg	FOURCC_YV12,
136428d7b3dSmrg	XVMC_CHROMA_FORMAT_420,
137428d7b3dSmrg	0,
138428d7b3dSmrg	1936,
139428d7b3dSmrg	1096,
140428d7b3dSmrg	1920,
141428d7b3dSmrg	1080,
142428d7b3dSmrg	XVMC_MPEG_2 | XVMC_VLD,
143428d7b3dSmrg	XVMC_INTRA_UNSIGNED,
144428d7b3dSmrg	NULL
145428d7b3dSmrg};
146428d7b3dSmrg
147428d7b3dSmrgstatic XF86MCSurfaceInfoRec yv12_mpeg2_i965_surface = {
148428d7b3dSmrg	FOURCC_YV12,
149428d7b3dSmrg	XVMC_CHROMA_FORMAT_420,
150428d7b3dSmrg	0,
151428d7b3dSmrg	1936,
152428d7b3dSmrg	1096,
153428d7b3dSmrg	1920,
154428d7b3dSmrg	1080,
155428d7b3dSmrg	XVMC_MPEG_2 | XVMC_MOCOMP,
156428d7b3dSmrg	/* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */
157428d7b3dSmrg	XVMC_INTRA_UNSIGNED,
158428d7b3dSmrg	/* &yv12_subpicture_list */
159428d7b3dSmrg	NULL
160428d7b3dSmrg};
161428d7b3dSmrg
162428d7b3dSmrgstatic XF86MCSurfaceInfoRec yv12_mpeg1_i965_surface = {
163428d7b3dSmrg	FOURCC_YV12,
164428d7b3dSmrg	XVMC_CHROMA_FORMAT_420,
165428d7b3dSmrg	0,
166428d7b3dSmrg	1920,
167428d7b3dSmrg	1080,
168428d7b3dSmrg	1920,
169428d7b3dSmrg	1080,
170428d7b3dSmrg	XVMC_MPEG_1 | XVMC_MOCOMP,
171428d7b3dSmrg	/*XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING |
172428d7b3dSmrg	   XVMC_INTRA_UNSIGNED, */
173428d7b3dSmrg	XVMC_INTRA_UNSIGNED,
174428d7b3dSmrg
175428d7b3dSmrg	/*&yv12_subpicture_list */
176428d7b3dSmrg	NULL
177428d7b3dSmrg};
178428d7b3dSmrg
179428d7b3dSmrgstatic XF86MCSurfaceInfoPtr surface_info_i965[] = {
180428d7b3dSmrg	&yv12_mpeg2_i965_surface,
181428d7b3dSmrg	&yv12_mpeg1_i965_surface
182428d7b3dSmrg};
183428d7b3dSmrg
184428d7b3dSmrgstatic XF86MCSurfaceInfoPtr surface_info_vld[] = {
185428d7b3dSmrg	&yv12_mpeg2_vld_surface,
186428d7b3dSmrg	&yv12_mpeg2_i965_surface,
187428d7b3dSmrg};
188428d7b3dSmrg
189428d7b3dSmrg/* check chip type and load xvmc driver */
190428d7b3dSmrgBool intel_xvmc_adaptor_init(ScreenPtr pScreen)
191428d7b3dSmrg{
192428d7b3dSmrg	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
193428d7b3dSmrg	intel_screen_private *intel = intel_get_screen_private(scrn);
194428d7b3dSmrg	struct pci_device *pci;
195428d7b3dSmrg	static XF86MCAdaptorRec *pAdapt;
196428d7b3dSmrg	char *name;
197428d7b3dSmrg	char buf[64];
198428d7b3dSmrg
199428d7b3dSmrg	if (!intel->XvMCEnabled)
200428d7b3dSmrg		return FALSE;
201428d7b3dSmrg
202428d7b3dSmrg	/* Needs KMS support. */
203428d7b3dSmrg	if (IS_I915G(intel) || IS_I915GM(intel))
204428d7b3dSmrg		return FALSE;
205428d7b3dSmrg
206428d7b3dSmrg	if (IS_GEN2(intel)) {
207428d7b3dSmrg		ErrorF("Your chipset doesn't support XvMC.\n");
208428d7b3dSmrg		return FALSE;
209428d7b3dSmrg	}
210428d7b3dSmrg
211428d7b3dSmrg	pci = xf86GetPciInfoForEntity(intel->pEnt->index);
212428d7b3dSmrg	if (pci == NULL)
213428d7b3dSmrg		return FALSE;
214428d7b3dSmrg
215428d7b3dSmrg	pAdapt = calloc(1, sizeof(XF86MCAdaptorRec));
216428d7b3dSmrg	if (!pAdapt) {
217428d7b3dSmrg		ErrorF("Allocation error.\n");
218428d7b3dSmrg		return FALSE;
219428d7b3dSmrg	}
220428d7b3dSmrg
221428d7b3dSmrg	pAdapt->name = "Intel(R) Textured Video";
222428d7b3dSmrg	pAdapt->num_subpictures = 0;
223428d7b3dSmrg	pAdapt->subpictures = NULL;
224428d7b3dSmrg	pAdapt->CreateContext = create_context;
225428d7b3dSmrg	pAdapt->DestroyContext = destroy_context;
226428d7b3dSmrg	pAdapt->CreateSurface = create_surface;
227428d7b3dSmrg	pAdapt->DestroySurface = destroy_surface;
228428d7b3dSmrg	pAdapt->CreateSubpicture =  create_subpicture;
229428d7b3dSmrg	pAdapt->DestroySubpicture = destroy_subpicture;
230428d7b3dSmrg
231428d7b3dSmrg	if (IS_GEN3(intel)) {
232428d7b3dSmrg		name = "i915_xvmc",
233428d7b3dSmrg		pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i915);
234428d7b3dSmrg		pAdapt->surfaces = surface_info_i915;
235428d7b3dSmrg	} else if (INTEL_INFO(intel)->gen >= 045) {
236428d7b3dSmrg		name = "xvmc_vld",
237428d7b3dSmrg		pAdapt->num_surfaces = ARRAY_SIZE(surface_info_vld);
238428d7b3dSmrg		pAdapt->surfaces = surface_info_vld;
239428d7b3dSmrg	} else {
240428d7b3dSmrg		name = "i965_xvmc",
241428d7b3dSmrg		pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i965);
242428d7b3dSmrg		pAdapt->surfaces = surface_info_i965;
243428d7b3dSmrg	}
244428d7b3dSmrg
245428d7b3dSmrg	if (xf86XvMCScreenInit(pScreen, 1, &pAdapt)) {
246428d7b3dSmrg		xf86DrvMsg(scrn->scrnIndex, X_INFO,
247428d7b3dSmrg			   "[XvMC] %s driver initialized.\n",
248428d7b3dSmrg			   name);
249428d7b3dSmrg	} else {
250428d7b3dSmrg		intel->XvMCEnabled = FALSE;
251428d7b3dSmrg		xf86DrvMsg(scrn->scrnIndex, X_INFO,
252428d7b3dSmrg			   "[XvMC] Failed to initialize XvMC.\n");
253428d7b3dSmrg		return FALSE;
254428d7b3dSmrg	}
255428d7b3dSmrg
256428d7b3dSmrg	sprintf(buf, "pci:%04x:%02x:%02x.%d",
257428d7b3dSmrg		pci->domain, pci->bus, pci->dev, pci->func);
258428d7b3dSmrg
259428d7b3dSmrg	xf86XvMCRegisterDRInfo(pScreen, INTEL_XVMC_LIBNAME,
260428d7b3dSmrg			       buf,
261428d7b3dSmrg			       INTEL_XVMC_MAJOR, INTEL_XVMC_MINOR,
262428d7b3dSmrg			       INTEL_XVMC_PATCHLEVEL);
263428d7b3dSmrg	return TRUE;
264428d7b3dSmrg}
265