xvmc_vld.c revision 428d7b3d
1428d7b3dSmrg/*
2428d7b3dSmrg * Copyright © 2009 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 * Author:
24428d7b3dSmrg *    Zou Nan hai <nanhai.zou@intel.com>
25428d7b3dSmrg */
26428d7b3dSmrg#include "intel_xvmc_private.h"
27428d7b3dSmrg#include "i830_reg.h"
28428d7b3dSmrg#include "i965_reg.h"
29428d7b3dSmrg#include "brw_defines.h"
30428d7b3dSmrg#include "brw_structs.h"
31428d7b3dSmrg
32428d7b3dSmrg#ifndef ALIGN
33428d7b3dSmrg#define ALIGN(m,n) (((m) + (n) - 1) & ~((n) - 1))
34428d7b3dSmrg#endif
35428d7b3dSmrg
36428d7b3dSmrg#define BATCH_STRUCT(x) intelBatchbufferData(&x, sizeof(x), 0)
37428d7b3dSmrg#define VLD_MAX_SLICE_SIZE (32 * 1024)
38428d7b3dSmrg#define CS_SIZE 	30
39428d7b3dSmrg#define URB_SIZE 	384
40428d7b3dSmrg/* idct table */
41428d7b3dSmrg#define C0 23170
42428d7b3dSmrg#define C1 22725
43428d7b3dSmrg#define C2 21407
44428d7b3dSmrg#define C3 19266
45428d7b3dSmrg#define C4 16383
46428d7b3dSmrg#define C5 12873
47428d7b3dSmrg#define C6 8867
48428d7b3dSmrg#define C7 4520
49428d7b3dSmrgconst uint32_t idct_table[] = {
50428d7b3dSmrg	C4, C1, C2, C3, C4, C5, C6, C7,	//g5
51428d7b3dSmrg	C4, C1, C2, C3, C4, C5, C6, C7,
52428d7b3dSmrg	C4, C3, C6, -C7, -C4, -C1, -C2, -C5,
53428d7b3dSmrg	C4, C3, C6, -C7, -C4, -C1, -C2, -C5,
54428d7b3dSmrg	C4, C5, -C6, -C1, -C4, C7, C2, C3,
55428d7b3dSmrg	C4, C5, -C6, -C1, -C4, C7, C2, C3,
56428d7b3dSmrg	C4, C7, -C2, -C5, C4, C3, -C6, -C1,
57428d7b3dSmrg	C4, C7, -C2, -C5, C4, C3, -C6, -C1,
58428d7b3dSmrg	C4, -C7, -C2, C5, C4, -C3, -C6, C1,
59428d7b3dSmrg	C4, -C7, -C2, C5, C4, -C3, -C6, C1,
60428d7b3dSmrg	C4, -C5, -C6, C1, -C4, -C7, C2, -C3,
61428d7b3dSmrg	C4, -C5, -C6, C1, -C4, -C7, C2, -C3,
62428d7b3dSmrg	C4, -C3, C6, C7, -C4, C1, -C2, C5,
63428d7b3dSmrg	C4, -C3, C6, C7, -C4, C1, -C2, C5,
64428d7b3dSmrg	C4, -C1, C2, -C3, C4, -C5, C6, -C7,
65428d7b3dSmrg	C4, -C1, C2, -C3, C4, -C5, C6, -C7	//g20
66428d7b3dSmrg};
67428d7b3dSmrg
68428d7b3dSmrg#undef C0
69428d7b3dSmrg#undef C1
70428d7b3dSmrg#undef C2
71428d7b3dSmrg#undef C3
72428d7b3dSmrg#undef C4
73428d7b3dSmrg#undef C5
74428d7b3dSmrg#undef C6
75428d7b3dSmrg#undef C7
76428d7b3dSmrg
77428d7b3dSmrg#define INTERFACE_NUM	8
78428d7b3dSmrgenum interface {
79428d7b3dSmrg	FRAME_INTRA = 0,
80428d7b3dSmrg	FRAME_FRAME_PRED_FORWARD,
81428d7b3dSmrg	FRAME_FRAME_PRED_BACKWARD,
82428d7b3dSmrg	FRAME_FRAME_PRED_BIDIRECT,
83428d7b3dSmrg	FRAME_FIELD_PRED_FORWARD,
84428d7b3dSmrg	FRAME_FIELD_PRED_BACKWARD,
85428d7b3dSmrg	FRAME_FIELD_PRED_BIDIRECT,
86428d7b3dSmrg	LIB_INTERFACE
87428d7b3dSmrg};
88428d7b3dSmrg
89428d7b3dSmrg/*kernels for vld mode*/
90428d7b3dSmrgstatic uint32_t lib_kernel[][4] = {
91428d7b3dSmrg#include "shader/vld/lib.g4b"
92428d7b3dSmrg};
93428d7b3dSmrg
94428d7b3dSmrgstatic uint32_t ipicture_kernel[][4] = {
95428d7b3dSmrg#include "shader/vld/ipicture.g4b"
96428d7b3dSmrg};
97428d7b3dSmrg
98428d7b3dSmrgstatic uint32_t frame_forward_kernel[][4] = {
99428d7b3dSmrg#include "shader/vld/frame_forward.g4b"
100428d7b3dSmrg};
101428d7b3dSmrg
102428d7b3dSmrgstatic uint32_t frame_backward_kernel[][4] = {
103428d7b3dSmrg#include "shader/vld/frame_backward.g4b"
104428d7b3dSmrg};
105428d7b3dSmrg
106428d7b3dSmrgstatic uint32_t frame_f_b_kernel[][4] = {
107428d7b3dSmrg#include "shader/vld/frame_f_b.g4b"
108428d7b3dSmrg};
109428d7b3dSmrg
110428d7b3dSmrgstatic uint32_t field_forward_kernel[][4] = {
111428d7b3dSmrg#include "shader/vld/field_forward.g4b"
112428d7b3dSmrg};
113428d7b3dSmrg
114428d7b3dSmrgstatic uint32_t field_backward_kernel[][4] = {
115428d7b3dSmrg#include "shader/vld/field_backward.g4b"
116428d7b3dSmrg};
117428d7b3dSmrg
118428d7b3dSmrgstatic uint32_t field_f_b_kernel[][4] = {
119428d7b3dSmrg#include "shader/vld/field_f_b.g4b"
120428d7b3dSmrg};
121428d7b3dSmrg
122428d7b3dSmrg/* on Ironlake */
123428d7b3dSmrgstatic uint32_t lib_kernel_gen5[][4] = {
124428d7b3dSmrg#include "shader/vld/lib.g4b.gen5"
125428d7b3dSmrg};
126428d7b3dSmrg
127428d7b3dSmrgstatic uint32_t ipicture_kernel_gen5[][4] = {
128428d7b3dSmrg#include "shader/vld/ipicture.g4b.gen5"
129428d7b3dSmrg};
130428d7b3dSmrg
131428d7b3dSmrgstatic uint32_t frame_forward_kernel_gen5[][4] = {
132428d7b3dSmrg#include "shader/vld/frame_forward.g4b.gen5"
133428d7b3dSmrg};
134428d7b3dSmrg
135428d7b3dSmrgstatic uint32_t frame_backward_kernel_gen5[][4] = {
136428d7b3dSmrg#include "shader/vld/frame_backward.g4b.gen5"
137428d7b3dSmrg};
138428d7b3dSmrg
139428d7b3dSmrgstatic uint32_t frame_f_b_kernel_gen5[][4] = {
140428d7b3dSmrg#include "shader/vld/frame_f_b.g4b.gen5"
141428d7b3dSmrg};
142428d7b3dSmrg
143428d7b3dSmrgstatic uint32_t field_forward_kernel_gen5[][4] = {
144428d7b3dSmrg#include "shader/vld/field_forward.g4b.gen5"
145428d7b3dSmrg};
146428d7b3dSmrg
147428d7b3dSmrgstatic uint32_t field_backward_kernel_gen5[][4] = {
148428d7b3dSmrg#include "shader/vld/field_backward.g4b.gen5"
149428d7b3dSmrg};
150428d7b3dSmrg
151428d7b3dSmrgstatic uint32_t field_f_b_kernel_gen5[][4] = {
152428d7b3dSmrg#include "shader/vld/field_f_b.g4b.gen5"
153428d7b3dSmrg};
154428d7b3dSmrg
155428d7b3dSmrg/*kernels for mc mode*/
156428d7b3dSmrgstatic uint32_t lib_kernel_idct[][4] = {
157428d7b3dSmrg#include "shader/mc/lib_igd.g4b"
158428d7b3dSmrg};
159428d7b3dSmrg
160428d7b3dSmrgstatic uint32_t ipicture_kernel_idct[][4] = {
161428d7b3dSmrg#include "shader/mc/ipicture_igd.g4b"
162428d7b3dSmrg};
163428d7b3dSmrg
164428d7b3dSmrgstatic uint32_t frame_forward_kernel_idct[][4] = {
165428d7b3dSmrg#include "shader/mc/frame_forward_igd.g4b"
166428d7b3dSmrg};
167428d7b3dSmrg
168428d7b3dSmrgstatic uint32_t frame_backward_kernel_idct[][4] = {
169428d7b3dSmrg#include "shader/mc/frame_backward_igd.g4b"
170428d7b3dSmrg};
171428d7b3dSmrg
172428d7b3dSmrgstatic uint32_t frame_f_b_kernel_idct[][4] = {
173428d7b3dSmrg#include "shader/mc/frame_f_b_igd.g4b"
174428d7b3dSmrg};
175428d7b3dSmrg
176428d7b3dSmrgstatic uint32_t field_forward_kernel_idct[][4] = {
177428d7b3dSmrg#include "shader/mc/field_forward_igd.g4b"
178428d7b3dSmrg};
179428d7b3dSmrg
180428d7b3dSmrgstatic uint32_t field_backward_kernel_idct[][4] = {
181428d7b3dSmrg#include "shader/mc/field_backward_igd.g4b"
182428d7b3dSmrg};
183428d7b3dSmrg
184428d7b3dSmrgstatic uint32_t field_f_b_kernel_idct[][4] = {
185428d7b3dSmrg#include "shader/mc/field_f_b_igd.g4b"
186428d7b3dSmrg};
187428d7b3dSmrg
188428d7b3dSmrg/* on Ironlake */
189428d7b3dSmrgstatic uint32_t lib_kernel_idct_gen5[][4] = {
190428d7b3dSmrg#include "shader/mc/lib_igd.g4b.gen5"
191428d7b3dSmrg};
192428d7b3dSmrg
193428d7b3dSmrgstatic uint32_t ipicture_kernel_idct_gen5[][4] = {
194428d7b3dSmrg#include "shader/mc/ipicture_igd.g4b.gen5"
195428d7b3dSmrg};
196428d7b3dSmrg
197428d7b3dSmrgstatic uint32_t frame_forward_kernel_idct_gen5[][4] = {
198428d7b3dSmrg#include "shader/mc/frame_forward_igd.g4b.gen5"
199428d7b3dSmrg};
200428d7b3dSmrg
201428d7b3dSmrgstatic uint32_t frame_backward_kernel_idct_gen5[][4] = {
202428d7b3dSmrg#include "shader/mc/frame_backward_igd.g4b.gen5"
203428d7b3dSmrg};
204428d7b3dSmrg
205428d7b3dSmrgstatic uint32_t frame_f_b_kernel_idct_gen5[][4] = {
206428d7b3dSmrg#include "shader/mc/frame_f_b_igd.g4b.gen5"
207428d7b3dSmrg};
208428d7b3dSmrg
209428d7b3dSmrgstatic uint32_t field_forward_kernel_idct_gen5[][4] = {
210428d7b3dSmrg#include "shader/mc/field_forward_igd.g4b.gen5"
211428d7b3dSmrg};
212428d7b3dSmrg
213428d7b3dSmrgstatic uint32_t field_backward_kernel_idct_gen5[][4] = {
214428d7b3dSmrg#include "shader/mc/field_backward_igd.g4b.gen5"
215428d7b3dSmrg};
216428d7b3dSmrg
217428d7b3dSmrgstatic uint32_t field_f_b_kernel_idct_gen5[][4] = {
218428d7b3dSmrg#include "shader/mc/field_f_b_igd.g4b.gen5"
219428d7b3dSmrg};
220428d7b3dSmrg
221428d7b3dSmrgstruct media_kernel {
222428d7b3dSmrg	uint32_t(*bin)[4];
223428d7b3dSmrg	int size;
224428d7b3dSmrg};
225428d7b3dSmrgstatic struct media_kernel media_kernels[] = {
226428d7b3dSmrg	/*kernels for vld mode */
227428d7b3dSmrg	{ipicture_kernel, sizeof(ipicture_kernel)}
228428d7b3dSmrg	,
229428d7b3dSmrg	{frame_forward_kernel, sizeof(frame_forward_kernel)}
230428d7b3dSmrg	,
231428d7b3dSmrg	{frame_backward_kernel, sizeof(frame_backward_kernel)}
232428d7b3dSmrg	,
233428d7b3dSmrg	{frame_f_b_kernel, sizeof(frame_f_b_kernel)}
234428d7b3dSmrg	,
235428d7b3dSmrg	{field_forward_kernel, sizeof(field_forward_kernel)}
236428d7b3dSmrg	,
237428d7b3dSmrg	{field_backward_kernel, sizeof(field_backward_kernel)}
238428d7b3dSmrg	,
239428d7b3dSmrg	{field_f_b_kernel, sizeof(field_f_b_kernel)}
240428d7b3dSmrg	,
241428d7b3dSmrg	{lib_kernel, sizeof(lib_kernel)}
242428d7b3dSmrg	,
243428d7b3dSmrg	/*kernels for mc mode */
244428d7b3dSmrg	{ipicture_kernel_idct, sizeof(ipicture_kernel_idct)}
245428d7b3dSmrg	,
246428d7b3dSmrg	{frame_forward_kernel_idct, sizeof(frame_forward_kernel_idct)}
247428d7b3dSmrg	,
248428d7b3dSmrg	{frame_backward_kernel_idct, sizeof(frame_backward_kernel_idct)}
249428d7b3dSmrg	,
250428d7b3dSmrg	{frame_f_b_kernel_idct, sizeof(frame_f_b_kernel_idct)}
251428d7b3dSmrg	,
252428d7b3dSmrg	{field_forward_kernel_idct, sizeof(field_forward_kernel_idct)}
253428d7b3dSmrg	,
254428d7b3dSmrg	{field_backward_kernel_idct, sizeof(field_backward_kernel_idct)}
255428d7b3dSmrg	,
256428d7b3dSmrg	{field_f_b_kernel_idct, sizeof(field_f_b_kernel_idct)}
257428d7b3dSmrg	,
258428d7b3dSmrg	{lib_kernel_idct, sizeof(lib_kernel_idct)}
259428d7b3dSmrg};
260428d7b3dSmrg
261428d7b3dSmrgstatic struct media_kernel media_gen5_kernels[] = {
262428d7b3dSmrg	/*kernels for vld mode */
263428d7b3dSmrg	{ipicture_kernel_gen5, sizeof(ipicture_kernel_gen5)}
264428d7b3dSmrg	,
265428d7b3dSmrg	{frame_forward_kernel_gen5, sizeof(frame_forward_kernel_gen5)}
266428d7b3dSmrg	,
267428d7b3dSmrg	{frame_backward_kernel_gen5, sizeof(frame_backward_kernel_gen5)}
268428d7b3dSmrg	,
269428d7b3dSmrg	{frame_f_b_kernel_gen5, sizeof(frame_f_b_kernel_gen5)}
270428d7b3dSmrg	,
271428d7b3dSmrg	{field_forward_kernel_gen5, sizeof(field_forward_kernel_gen5)}
272428d7b3dSmrg	,
273428d7b3dSmrg	{field_backward_kernel_gen5, sizeof(field_backward_kernel_gen5)}
274428d7b3dSmrg	,
275428d7b3dSmrg	{field_f_b_kernel_gen5, sizeof(field_f_b_kernel_gen5)}
276428d7b3dSmrg	,
277428d7b3dSmrg	{lib_kernel_gen5, sizeof(lib_kernel_gen5)}
278428d7b3dSmrg	,
279428d7b3dSmrg	/*kernels for mc mode */
280428d7b3dSmrg	{ipicture_kernel_idct_gen5, sizeof(ipicture_kernel_idct_gen5)}
281428d7b3dSmrg	,
282428d7b3dSmrg	{frame_forward_kernel_idct_gen5, sizeof(frame_forward_kernel_idct_gen5)}
283428d7b3dSmrg	,
284428d7b3dSmrg	{frame_backward_kernel_idct_gen5,
285428d7b3dSmrg	 sizeof(frame_backward_kernel_idct_gen5)}
286428d7b3dSmrg	,
287428d7b3dSmrg	{frame_f_b_kernel_idct_gen5, sizeof(frame_f_b_kernel_idct_gen5)}
288428d7b3dSmrg	,
289428d7b3dSmrg	{field_forward_kernel_idct_gen5, sizeof(field_forward_kernel_idct_gen5)}
290428d7b3dSmrg	,
291428d7b3dSmrg	{field_backward_kernel_idct_gen5,
292428d7b3dSmrg	 sizeof(field_backward_kernel_idct_gen5)}
293428d7b3dSmrg	,
294428d7b3dSmrg	{field_f_b_kernel_idct_gen5, sizeof(field_f_b_kernel_idct_gen5)}
295428d7b3dSmrg	,
296428d7b3dSmrg	{lib_kernel_idct_gen5, sizeof(lib_kernel_idct_gen5)}
297428d7b3dSmrg};
298428d7b3dSmrg
299428d7b3dSmrg#define MEDIA_KERNEL_NUM (sizeof(media_kernels)/sizeof(media_kernels[0]))
300428d7b3dSmrg
301428d7b3dSmrgstruct media_kernel_obj {
302428d7b3dSmrg	dri_bo *bo;
303428d7b3dSmrg};
304428d7b3dSmrg
305428d7b3dSmrgstruct interface_descriptor_obj {
306428d7b3dSmrg	dri_bo *bo;
307428d7b3dSmrg	struct media_kernel_obj kernels[MEDIA_KERNEL_NUM];
308428d7b3dSmrg};
309428d7b3dSmrg
310428d7b3dSmrgstruct vfe_state_obj {
311428d7b3dSmrg	dri_bo *bo;
312428d7b3dSmrg	struct interface_descriptor_obj interface;
313428d7b3dSmrg};
314428d7b3dSmrg
315428d7b3dSmrgstruct vld_state_obj {
316428d7b3dSmrg	dri_bo *bo;
317428d7b3dSmrg};
318428d7b3dSmrg
319428d7b3dSmrgstruct surface_obj {
320428d7b3dSmrg	dri_bo *bo;
321428d7b3dSmrg};
322428d7b3dSmrg
323428d7b3dSmrgstruct surface_state_obj {
324428d7b3dSmrg	struct surface_obj surface;
325428d7b3dSmrg	dri_bo *bo;
326428d7b3dSmrg};
327428d7b3dSmrg
328428d7b3dSmrg#define MAX_SURFACES 12
329428d7b3dSmrgstruct binding_table_obj {
330428d7b3dSmrg	dri_bo *bo;
331428d7b3dSmrg	struct surface_state_obj surface_states[MAX_SURFACES];
332428d7b3dSmrg};
333428d7b3dSmrg
334428d7b3dSmrgstruct slice_data_obj {
335428d7b3dSmrg	dri_bo *bo;
336428d7b3dSmrg};
337428d7b3dSmrg
338428d7b3dSmrgstruct mb_data_obj {
339428d7b3dSmrg	dri_bo *bo;
340428d7b3dSmrg};
341428d7b3dSmrg
342428d7b3dSmrgstruct cs_state_obj {
343428d7b3dSmrg	dri_bo *bo;
344428d7b3dSmrg};
345428d7b3dSmrg
346428d7b3dSmrgstatic struct media_state {
347428d7b3dSmrg	struct vfe_state_obj vfe_state;
348428d7b3dSmrg	struct vld_state_obj vld_state;
349428d7b3dSmrg	struct binding_table_obj binding_table;
350428d7b3dSmrg	struct cs_state_obj cs_object;
351428d7b3dSmrg	struct slice_data_obj slice_data;
352428d7b3dSmrg	struct mb_data_obj mb_data;
353428d7b3dSmrg} media_state;
354428d7b3dSmrg
355428d7b3dSmrg/* XvMCQMatrix * 2 + idct_table + 8 * kernel offset pointer */
356428d7b3dSmrg#define CS_OBJECT_SIZE (32*20 + sizeof(unsigned int) * 8)
357428d7b3dSmrgstatic void free_object(struct media_state *s)
358428d7b3dSmrg{
359428d7b3dSmrg	int i;
360428d7b3dSmrg#define FREE_ONE_BO(bo) \
361428d7b3dSmrg    if (bo) \
362428d7b3dSmrg        drm_intel_bo_unreference(bo)
363428d7b3dSmrg	FREE_ONE_BO(s->vfe_state.bo);
364428d7b3dSmrg	FREE_ONE_BO(s->vfe_state.interface.bo);
365428d7b3dSmrg	for (i = 0; i < MEDIA_KERNEL_NUM; i++)
366428d7b3dSmrg		FREE_ONE_BO(s->vfe_state.interface.kernels[i].bo);
367428d7b3dSmrg	FREE_ONE_BO(s->binding_table.bo);
368428d7b3dSmrg	for (i = 0; i < MAX_SURFACES; i++)
369428d7b3dSmrg		FREE_ONE_BO(s->binding_table.surface_states[i].bo);
370428d7b3dSmrg	FREE_ONE_BO(s->slice_data.bo);
371428d7b3dSmrg	FREE_ONE_BO(s->mb_data.bo);
372428d7b3dSmrg	FREE_ONE_BO(s->cs_object.bo);
373428d7b3dSmrg	FREE_ONE_BO(s->vld_state.bo);
374428d7b3dSmrg}
375428d7b3dSmrg
376428d7b3dSmrgstatic int alloc_object(struct media_state *s)
377428d7b3dSmrg{
378428d7b3dSmrg	int i;
379428d7b3dSmrg
380428d7b3dSmrg	for (i = 0; i < MAX_SURFACES; i++) {
381428d7b3dSmrg		s->binding_table.surface_states[i].bo =
382428d7b3dSmrg		    drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state",
383428d7b3dSmrg				       sizeof(struct brw_surface_state),
384428d7b3dSmrg				       0x1000);
385428d7b3dSmrg		if (!s->binding_table.surface_states[i].bo)
386428d7b3dSmrg			goto out;
387428d7b3dSmrg	}
388428d7b3dSmrg	return 0;
389428d7b3dSmrgout:
390428d7b3dSmrg	free_object(s);
391428d7b3dSmrg	return BadAlloc;
392428d7b3dSmrg}
393428d7b3dSmrg
394428d7b3dSmrgstatic void flush()
395428d7b3dSmrg{
396428d7b3dSmrg#define FLUSH_STATE_CACHE  	1
397428d7b3dSmrg	struct brw_mi_flush f;
398428d7b3dSmrg	memset(&f, 0, sizeof(f));
399428d7b3dSmrg	f.opcode = CMD_MI_FLUSH;
400428d7b3dSmrg	f.flags = (1 << FLUSH_STATE_CACHE);
401428d7b3dSmrg	BATCH_STRUCT(f);
402428d7b3dSmrg}
403428d7b3dSmrg
404428d7b3dSmrgstatic Status vfe_state(int vfe_mode)
405428d7b3dSmrg{
406428d7b3dSmrg	struct brw_vfe_state tmp, *vfe_state = &tmp;
407428d7b3dSmrg	memset(vfe_state, 0, sizeof(*vfe_state));
408428d7b3dSmrg	if (vfe_mode == VFE_VLD_MODE) {
409428d7b3dSmrg		vfe_state->vfe0.extend_vfe_state_present = 1;
410428d7b3dSmrg	} else {
411428d7b3dSmrg		vfe_state->vfe0.extend_vfe_state_present = 0;
412428d7b3dSmrg	}
413428d7b3dSmrg	vfe_state->vfe1.vfe_mode = vfe_mode;
414428d7b3dSmrg	vfe_state->vfe1.num_urb_entries = 1;
415428d7b3dSmrg	vfe_state->vfe1.children_present = 0;
416428d7b3dSmrg	vfe_state->vfe1.urb_entry_alloc_size = 2;
417428d7b3dSmrg	vfe_state->vfe1.max_threads = 31;
418428d7b3dSmrg	vfe_state->vfe2.interface_descriptor_base =
419428d7b3dSmrg	    media_state.vfe_state.interface.bo->offset >> 4;
420428d7b3dSmrg
421428d7b3dSmrg	if (media_state.vfe_state.bo)
422428d7b3dSmrg		drm_intel_bo_unreference(media_state.vfe_state.bo);
423428d7b3dSmrg
424428d7b3dSmrg	media_state.vfe_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
425428d7b3dSmrg						      "vfe state",
426428d7b3dSmrg						      sizeof(struct
427428d7b3dSmrg							     brw_vfe_state),
428428d7b3dSmrg						      0x1000);
429428d7b3dSmrg	if (!media_state.vfe_state.bo)
430428d7b3dSmrg		return BadAlloc;
431428d7b3dSmrg
432428d7b3dSmrg	drm_intel_bo_subdata(media_state.vfe_state.bo, 0, sizeof(tmp), &tmp);
433428d7b3dSmrg
434428d7b3dSmrg	drm_intel_bo_emit_reloc(media_state.vfe_state.bo,
435428d7b3dSmrg				offsetof(struct brw_vfe_state, vfe2),
436428d7b3dSmrg				media_state.vfe_state.interface.bo, 0,
437428d7b3dSmrg				I915_GEM_DOMAIN_INSTRUCTION, 0);
438428d7b3dSmrg	return Success;
439428d7b3dSmrg}
440428d7b3dSmrg
441428d7b3dSmrgstatic Status interface_descriptor()
442428d7b3dSmrg{
443428d7b3dSmrg	int i;
444428d7b3dSmrg	struct brw_interface_descriptor tmp, *desc = &tmp;
445428d7b3dSmrg
446428d7b3dSmrg	if (media_state.vfe_state.interface.bo)
447428d7b3dSmrg		drm_intel_bo_unreference(media_state.vfe_state.interface.bo);
448428d7b3dSmrg
449428d7b3dSmrg	media_state.vfe_state.interface.bo =
450428d7b3dSmrg	    drm_intel_bo_alloc(xvmc_driver->bufmgr, "interfaces",
451428d7b3dSmrg			       MEDIA_KERNEL_NUM *
452428d7b3dSmrg			       sizeof(struct brw_interface_descriptor), 0x1000);
453428d7b3dSmrg	if (!media_state.vfe_state.interface.bo)
454428d7b3dSmrg		return BadAlloc;
455428d7b3dSmrg
456428d7b3dSmrg	for (i = 0; i < MEDIA_KERNEL_NUM; i++) {
457428d7b3dSmrg		memset(desc, 0, sizeof(*desc));
458428d7b3dSmrg		desc->desc0.grf_reg_blocks = 15;
459428d7b3dSmrg		desc->desc0.kernel_start_pointer =
460428d7b3dSmrg		    media_state.vfe_state.interface.kernels[i].bo->offset >> 6;
461428d7b3dSmrg
462428d7b3dSmrg		desc->desc1.const_urb_entry_read_offset = 0;
463428d7b3dSmrg		desc->desc1.const_urb_entry_read_len = 30;
464428d7b3dSmrg
465428d7b3dSmrg		desc->desc3.binding_table_entry_count = MAX_SURFACES - 1;
466428d7b3dSmrg		desc->desc3.binding_table_pointer =
467428d7b3dSmrg		    media_state.binding_table.bo->offset >> 5;
468428d7b3dSmrg
469428d7b3dSmrg		drm_intel_bo_subdata(media_state.vfe_state.interface.bo,
470428d7b3dSmrg				     i * sizeof(tmp), sizeof(tmp), desc);
471428d7b3dSmrg
472428d7b3dSmrg		drm_intel_bo_emit_reloc(media_state.vfe_state.interface.bo,
473428d7b3dSmrg					i * sizeof(*desc) + offsetof(struct
474428d7b3dSmrg								     brw_interface_descriptor,
475428d7b3dSmrg								     desc0),
476428d7b3dSmrg					media_state.vfe_state.
477428d7b3dSmrg					interface.kernels[i].bo,
478428d7b3dSmrg					desc->desc0.grf_reg_blocks,
479428d7b3dSmrg					I915_GEM_DOMAIN_INSTRUCTION, 0);
480428d7b3dSmrg
481428d7b3dSmrg		drm_intel_bo_emit_reloc(media_state.vfe_state.interface.bo,
482428d7b3dSmrg					i * sizeof(*desc) + offsetof(struct
483428d7b3dSmrg								     brw_interface_descriptor,
484428d7b3dSmrg								     desc3),
485428d7b3dSmrg					media_state.binding_table.bo,
486428d7b3dSmrg					desc->desc3.binding_table_entry_count,
487428d7b3dSmrg					I915_GEM_DOMAIN_INSTRUCTION, 0);
488428d7b3dSmrg	}
489428d7b3dSmrg	return Success;
490428d7b3dSmrg}
491428d7b3dSmrg
492428d7b3dSmrgstatic int setup_media_kernels(struct intel_xvmc_hw_context *ctx)
493428d7b3dSmrg{
494428d7b3dSmrg	int i;
495428d7b3dSmrg
496428d7b3dSmrg	assert(MEDIA_KERNEL_NUM ==
497428d7b3dSmrg	       sizeof(media_gen5_kernels) / sizeof(media_gen5_kernels[0]));
498428d7b3dSmrg
499428d7b3dSmrg	for (i = 0; i < MEDIA_KERNEL_NUM; i++) {
500428d7b3dSmrg		if (ctx->i965.is_igdng)
501428d7b3dSmrg			media_state.vfe_state.interface.kernels[i].bo =
502428d7b3dSmrg			    drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernel",
503428d7b3dSmrg					       media_gen5_kernels[i].size,
504428d7b3dSmrg					       0x1000);
505428d7b3dSmrg		else
506428d7b3dSmrg			media_state.vfe_state.interface.kernels[i].bo =
507428d7b3dSmrg			    drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernels",
508428d7b3dSmrg					       media_kernels[i].size, 0x1000);
509428d7b3dSmrg
510428d7b3dSmrg		if (!media_state.vfe_state.interface.kernels[i].bo)
511428d7b3dSmrg			goto out;
512428d7b3dSmrg	}
513428d7b3dSmrg
514428d7b3dSmrg	for (i = 0; i < MEDIA_KERNEL_NUM; i++) {
515428d7b3dSmrg		dri_bo *bo = media_state.vfe_state.interface.kernels[i].bo;
516428d7b3dSmrg
517428d7b3dSmrg		if (ctx->i965.is_igdng)
518428d7b3dSmrg			drm_intel_bo_subdata(bo, 0, media_gen5_kernels[i].size,
519428d7b3dSmrg					     media_gen5_kernels[i].bin);
520428d7b3dSmrg		else
521428d7b3dSmrg			drm_intel_bo_subdata(bo, 0, media_kernels[i].size,
522428d7b3dSmrg					     media_kernels[i].bin);
523428d7b3dSmrg	}
524428d7b3dSmrg	return 0;
525428d7b3dSmrgout:
526428d7b3dSmrg	free_object(&media_state);
527428d7b3dSmrg	return BadAlloc;
528428d7b3dSmrg}
529428d7b3dSmrg
530428d7b3dSmrgstatic Status binding_tables()
531428d7b3dSmrg{
532428d7b3dSmrg	unsigned int table[MAX_SURFACES];
533428d7b3dSmrg	int i;
534428d7b3dSmrg
535428d7b3dSmrg	if (media_state.binding_table.bo)
536428d7b3dSmrg		drm_intel_bo_unreference(media_state.binding_table.bo);
537428d7b3dSmrg	media_state.binding_table.bo =
538428d7b3dSmrg	    drm_intel_bo_alloc(xvmc_driver->bufmgr, "binding_table",
539428d7b3dSmrg			       MAX_SURFACES * 4, 0x1000);
540428d7b3dSmrg	if (!media_state.binding_table.bo)
541428d7b3dSmrg		return BadAlloc;
542428d7b3dSmrg
543428d7b3dSmrg	for (i = 0; i < MAX_SURFACES; i++) {
544428d7b3dSmrg		table[i] =
545428d7b3dSmrg		    media_state.binding_table.surface_states[i].bo->offset;
546428d7b3dSmrg		drm_intel_bo_emit_reloc(media_state.binding_table.bo,
547428d7b3dSmrg					i * sizeof(unsigned int),
548428d7b3dSmrg					media_state.
549428d7b3dSmrg					binding_table.surface_states[i].bo, 0,
550428d7b3dSmrg					I915_GEM_DOMAIN_INSTRUCTION, 0);
551428d7b3dSmrg	}
552428d7b3dSmrg
553428d7b3dSmrg	drm_intel_bo_subdata(media_state.binding_table.bo, 0, sizeof(table),
554428d7b3dSmrg			     table);
555428d7b3dSmrg	return Success;
556428d7b3dSmrg}
557428d7b3dSmrg
558428d7b3dSmrgstatic Status cs_init(int interface_offset)
559428d7b3dSmrg{
560428d7b3dSmrg	char buf[CS_OBJECT_SIZE];
561428d7b3dSmrg	unsigned int *lib_reloc;
562428d7b3dSmrg	int i;
563428d7b3dSmrg
564428d7b3dSmrg	if (media_state.cs_object.bo)
565428d7b3dSmrg		drm_intel_bo_unreference(media_state.cs_object.bo);
566428d7b3dSmrg
567428d7b3dSmrg	media_state.cs_object.bo =
568428d7b3dSmrg	    drm_intel_bo_alloc(xvmc_driver->bufmgr, "cs object", CS_OBJECT_SIZE,
569428d7b3dSmrg			       64);
570428d7b3dSmrg	if (!media_state.cs_object.bo)
571428d7b3dSmrg		return BadAlloc;
572428d7b3dSmrg
573428d7b3dSmrg	memcpy(buf + 32 * 4, idct_table, sizeof(idct_table));
574428d7b3dSmrg	/* idct lib reloction */
575428d7b3dSmrg	lib_reloc = (unsigned int *)(buf + 32 * 20);
576428d7b3dSmrg	for (i = 0; i < 8; i++)
577428d7b3dSmrg		lib_reloc[i] =
578428d7b3dSmrg		    media_state.vfe_state.interface.kernels[LIB_INTERFACE +
579428d7b3dSmrg							    interface_offset].bo->
580428d7b3dSmrg		    offset;
581428d7b3dSmrg	drm_intel_bo_subdata(media_state.cs_object.bo, 32 * 4,
582428d7b3dSmrg			     32 * 16 + 8 * sizeof(unsigned int), buf + 32 * 4);
583428d7b3dSmrg
584428d7b3dSmrg	for (i = 0; i < 8; i++)
585428d7b3dSmrg		drm_intel_bo_emit_reloc(media_state.cs_object.bo,
586428d7b3dSmrg					32 * 20 + sizeof(unsigned int) * i,
587428d7b3dSmrg					media_state.vfe_state.
588428d7b3dSmrg					interface.kernels[LIB_INTERFACE +
589428d7b3dSmrg							  interface_offset].bo,
590428d7b3dSmrg					0, I915_GEM_DOMAIN_INSTRUCTION, 0);
591428d7b3dSmrg
592428d7b3dSmrg	return Success;
593428d7b3dSmrg}
594428d7b3dSmrg
595428d7b3dSmrg#define STRIDE(w)               (w)
596428d7b3dSmrg#define SIZE_YUV420(w, h)       (h * (STRIDE(w) + STRIDE(w >> 1)))
597428d7b3dSmrgstatic Status create_context(Display * display, XvMCContext * context,
598428d7b3dSmrg			     int priv_count, CARD32 * priv_data)
599428d7b3dSmrg{
600428d7b3dSmrg	struct intel_xvmc_context *intel_ctx;
601428d7b3dSmrg	struct intel_xvmc_hw_context *hw_ctx;
602428d7b3dSmrg	hw_ctx = (struct intel_xvmc_hw_context *)priv_data;
603428d7b3dSmrg
604428d7b3dSmrg	intel_ctx = calloc(1, sizeof(struct intel_xvmc_context));
605428d7b3dSmrg	if (!intel_ctx)
606428d7b3dSmrg		return BadAlloc;
607428d7b3dSmrg	intel_ctx->hw = hw_ctx;
608428d7b3dSmrg	context->privData = intel_ctx;
609428d7b3dSmrg	intel_ctx->surface_bo_size
610428d7b3dSmrg		= SIZE_YUV420(context->width, context->height);
611428d7b3dSmrg
612428d7b3dSmrg	if (alloc_object(&media_state))
613428d7b3dSmrg		return BadAlloc;
614428d7b3dSmrg
615428d7b3dSmrg	if (setup_media_kernels(hw_ctx))
616428d7b3dSmrg		return BadAlloc;
617428d7b3dSmrg	return Success;
618428d7b3dSmrg}
619428d7b3dSmrg
620428d7b3dSmrgstatic Status destroy_context(Display * display, XvMCContext * context)
621428d7b3dSmrg{
622428d7b3dSmrg	struct intel_xvmc_context *intel_ctx;
623428d7b3dSmrg	intel_ctx = context->privData;
624428d7b3dSmrg	free(intel_ctx->hw);
625428d7b3dSmrg	free(intel_ctx);
626428d7b3dSmrg	return Success;
627428d7b3dSmrg}
628428d7b3dSmrg
629428d7b3dSmrgstatic Status load_qmatrix(Display * display, XvMCContext * context,
630428d7b3dSmrg			   const XvMCQMatrix * qmx)
631428d7b3dSmrg{
632428d7b3dSmrg	Status ret;
633428d7b3dSmrg	ret = cs_init(0);
634428d7b3dSmrg	if (ret != Success)
635428d7b3dSmrg		return ret;
636428d7b3dSmrg	drm_intel_bo_subdata(media_state.cs_object.bo, 0, 64,
637428d7b3dSmrg			     qmx->intra_quantiser_matrix);
638428d7b3dSmrg	drm_intel_bo_subdata(media_state.cs_object.bo, 64, 64,
639428d7b3dSmrg			     qmx->non_intra_quantiser_matrix);
640428d7b3dSmrg
641428d7b3dSmrg	return Success;
642428d7b3dSmrg}
643428d7b3dSmrg
644428d7b3dSmrgstatic Status vld_state(const XvMCMpegControl * control)
645428d7b3dSmrg{
646428d7b3dSmrg	struct brw_vld_state tmp, *vld = &tmp;
647428d7b3dSmrg
648428d7b3dSmrg	if (media_state.vld_state.bo)
649428d7b3dSmrg		drm_intel_bo_unreference(media_state.vld_state.bo);
650428d7b3dSmrg	media_state.vld_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
651428d7b3dSmrg						      "vld state",
652428d7b3dSmrg						      sizeof(struct
653428d7b3dSmrg							     brw_vld_state),
654428d7b3dSmrg						      64);
655428d7b3dSmrg	if (!media_state.vld_state.bo)
656428d7b3dSmrg		return BadAlloc;
657428d7b3dSmrg
658428d7b3dSmrg	memset(vld, 0, sizeof(*vld));
659428d7b3dSmrg	vld->vld0.f_code_0_0 = control->FHMV_range + 1;
660428d7b3dSmrg	vld->vld0.f_code_0_1 = control->FVMV_range + 1;
661428d7b3dSmrg	vld->vld0.f_code_1_0 = control->BHMV_range + 1;
662428d7b3dSmrg	vld->vld0.f_code_1_1 = control->BVMV_range + 1;
663428d7b3dSmrg	vld->vld0.intra_dc_precision = control->intra_dc_precision;
664428d7b3dSmrg	vld->vld0.picture_structure = control->picture_structure;
665428d7b3dSmrg	vld->vld0.top_field_first = !!(control->flags & XVMC_TOP_FIELD_FIRST);
666428d7b3dSmrg	vld->vld0.frame_predict_frame_dct =
667428d7b3dSmrg	    !!(control->flags & XVMC_PRED_DCT_FRAME);
668428d7b3dSmrg	vld->vld0.concealment_motion_vector =
669428d7b3dSmrg	    !!(control->flags & XVMC_CONCEALMENT_MOTION_VECTORS);
670428d7b3dSmrg	vld->vld0.quantizer_scale_type = !!(control->flags & XVMC_Q_SCALE_TYPE);
671428d7b3dSmrg	vld->vld0.intra_vlc_format = !!(control->flags & XVMC_INTRA_VLC_FORMAT);
672428d7b3dSmrg	vld->vld0.scan_order = !!(control->flags & XVMC_ALTERNATE_SCAN);
673428d7b3dSmrg
674428d7b3dSmrg	vld->vld1.picture_coding_type = control->picture_coding_type;
675428d7b3dSmrg
676428d7b3dSmrg	vld->desc_remap_table0.index_0 = FRAME_INTRA;
677428d7b3dSmrg	vld->desc_remap_table0.index_1 = FRAME_FRAME_PRED_FORWARD;
678428d7b3dSmrg	vld->desc_remap_table0.index_2 = FRAME_FIELD_PRED_FORWARD;
679428d7b3dSmrg	vld->desc_remap_table0.index_3 = FRAME_FIELD_PRED_BIDIRECT;	/* dual prime */
680428d7b3dSmrg	vld->desc_remap_table0.index_4 = FRAME_FRAME_PRED_BACKWARD;
681428d7b3dSmrg	vld->desc_remap_table0.index_5 = FRAME_FIELD_PRED_BACKWARD;
682428d7b3dSmrg	vld->desc_remap_table0.index_6 = FRAME_FRAME_PRED_BIDIRECT;
683428d7b3dSmrg	vld->desc_remap_table0.index_7 = FRAME_FIELD_PRED_BIDIRECT;
684428d7b3dSmrg
685428d7b3dSmrg	vld->desc_remap_table1.index_8 = FRAME_INTRA;
686428d7b3dSmrg	vld->desc_remap_table1.index_9 = FRAME_FRAME_PRED_FORWARD;
687428d7b3dSmrg	vld->desc_remap_table1.index_10 = FRAME_FIELD_PRED_FORWARD;
688428d7b3dSmrg	vld->desc_remap_table1.index_11 = FRAME_FIELD_PRED_BIDIRECT;
689428d7b3dSmrg	vld->desc_remap_table1.index_12 = FRAME_FRAME_PRED_BACKWARD;
690428d7b3dSmrg	vld->desc_remap_table1.index_13 = FRAME_FIELD_PRED_BACKWARD;
691428d7b3dSmrg	vld->desc_remap_table1.index_14 = FRAME_FRAME_PRED_BIDIRECT;
692428d7b3dSmrg	vld->desc_remap_table1.index_15 = FRAME_FIELD_PRED_BIDIRECT;
693428d7b3dSmrg
694428d7b3dSmrg	drm_intel_bo_subdata(media_state.vld_state.bo, 0, sizeof(tmp), vld);
695428d7b3dSmrg	return Success;
696428d7b3dSmrg}
697428d7b3dSmrg
698428d7b3dSmrgstatic Status setup_media_surface(int index, dri_bo * bo,
699428d7b3dSmrg				  unsigned long offset, int w, int h,
700428d7b3dSmrg				  Bool write)
701428d7b3dSmrg{
702428d7b3dSmrg	struct brw_surface_state tmp, *ss = &tmp;
703428d7b3dSmrg	memset(ss, 0, sizeof(*ss));
704428d7b3dSmrg	ss->ss0.surface_type = BRW_SURFACE_2D;
705428d7b3dSmrg	ss->ss0.surface_format = BRW_SURFACEFORMAT_R8_SINT;
706428d7b3dSmrg	ss->ss1.base_addr = offset + bo->offset;
707428d7b3dSmrg	ss->ss2.width = w - 1;
708428d7b3dSmrg	ss->ss2.height = h - 1;
709428d7b3dSmrg	ss->ss3.pitch = w - 1;
710428d7b3dSmrg
711428d7b3dSmrg	if (media_state.binding_table.surface_states[index].bo)
712428d7b3dSmrg		drm_intel_bo_unreference(media_state.
713428d7b3dSmrg					 binding_table.surface_states[index].
714428d7b3dSmrg					 bo);
715428d7b3dSmrg
716428d7b3dSmrg	media_state.binding_table.surface_states[index].bo =
717428d7b3dSmrg	    drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state",
718428d7b3dSmrg			       sizeof(struct brw_surface_state), 0x1000);
719428d7b3dSmrg	if (!media_state.binding_table.surface_states[index].bo)
720428d7b3dSmrg		return BadAlloc;
721428d7b3dSmrg
722428d7b3dSmrg	drm_intel_bo_subdata(media_state.binding_table.surface_states[index].bo,
723428d7b3dSmrg			     0, sizeof(*ss), ss);
724428d7b3dSmrg	drm_intel_bo_emit_reloc(media_state.binding_table.
725428d7b3dSmrg				surface_states[index].bo,
726428d7b3dSmrg				offsetof(struct brw_surface_state, ss1), bo,
727428d7b3dSmrg				offset, I915_GEM_DOMAIN_RENDER,
728428d7b3dSmrg				write ? I915_GEM_DOMAIN_RENDER : 0);
729428d7b3dSmrg	return Success;
730428d7b3dSmrg}
731428d7b3dSmrg
732428d7b3dSmrgstatic Status setup_surface(struct intel_xvmc_surface *target,
733428d7b3dSmrg			    struct intel_xvmc_surface *past,
734428d7b3dSmrg			    struct intel_xvmc_surface *future, int w, int h)
735428d7b3dSmrg{
736428d7b3dSmrg	Status ret;
737428d7b3dSmrg	ret = setup_media_surface(0, target->bo, 0, w, h, TRUE);
738428d7b3dSmrg	if (ret != Success)
739428d7b3dSmrg		return ret;
740428d7b3dSmrg	ret = setup_media_surface(1, target->bo, w * h, w / 2, h / 2, TRUE);
741428d7b3dSmrg	if (ret != Success)
742428d7b3dSmrg		return ret;
743428d7b3dSmrg	ret =
744428d7b3dSmrg	    setup_media_surface(2, target->bo, w * h + w * h / 4, w / 2, h / 2,
745428d7b3dSmrg				TRUE);
746428d7b3dSmrg	if (ret != Success)
747428d7b3dSmrg		return ret;
748428d7b3dSmrg	if (past) {
749428d7b3dSmrg		ret = setup_media_surface(4, past->bo, 0, w, h, FALSE);
750428d7b3dSmrg		if (ret != Success)
751428d7b3dSmrg			return ret;
752428d7b3dSmrg		ret =
753428d7b3dSmrg		    setup_media_surface(5, past->bo, w * h, w / 2, h / 2,
754428d7b3dSmrg					FALSE);
755428d7b3dSmrg		if (ret != Success)
756428d7b3dSmrg			return ret;
757428d7b3dSmrg		ret =
758428d7b3dSmrg		    setup_media_surface(6, past->bo, w * h + w * h / 4, w / 2,
759428d7b3dSmrg					h / 2, FALSE);
760428d7b3dSmrg		if (ret != Success)
761428d7b3dSmrg			return ret;
762428d7b3dSmrg	}
763428d7b3dSmrg	if (future) {
764428d7b3dSmrg		ret = setup_media_surface(7, future->bo, 0, w, h, FALSE);
765428d7b3dSmrg		if (ret != Success)
766428d7b3dSmrg			return ret;
767428d7b3dSmrg		ret =
768428d7b3dSmrg		    setup_media_surface(8, future->bo, w * h, w / 2, h / 2,
769428d7b3dSmrg					FALSE);
770428d7b3dSmrg		if (ret != Success)
771428d7b3dSmrg			return ret;
772428d7b3dSmrg		ret =
773428d7b3dSmrg		    setup_media_surface(9, future->bo, w * h + w * h / 4, w / 2,
774428d7b3dSmrg					h / 2, FALSE);
775428d7b3dSmrg		if (ret != Success)
776428d7b3dSmrg			return ret;
777428d7b3dSmrg	}
778428d7b3dSmrg	return Success;
779428d7b3dSmrg}
780428d7b3dSmrg
781428d7b3dSmrgstatic Status begin_surface(Display * display, XvMCContext * context,
782428d7b3dSmrg			    XvMCSurface * target,
783428d7b3dSmrg			    XvMCSurface * past,
784428d7b3dSmrg			    XvMCSurface * future,
785428d7b3dSmrg			    const XvMCMpegControl * control)
786428d7b3dSmrg{
787428d7b3dSmrg	struct intel_xvmc_surface *priv_target, *priv_past, *priv_future;
788428d7b3dSmrg	intel_xvmc_context_ptr intel_ctx = context->privData;
789428d7b3dSmrg	Status ret;
790428d7b3dSmrg
791428d7b3dSmrg	priv_target = target->privData;
792428d7b3dSmrg	priv_past = past ? past->privData : NULL;
793428d7b3dSmrg	priv_future = future ? future->privData : NULL;
794428d7b3dSmrg
795428d7b3dSmrg	ret = vld_state(control);
796428d7b3dSmrg	if (ret != Success)
797428d7b3dSmrg		return ret;
798428d7b3dSmrg	ret = setup_surface(priv_target, priv_past, priv_future,
799428d7b3dSmrg			    context->width, context->height);
800428d7b3dSmrg	if (ret != Success)
801428d7b3dSmrg		return ret;
802428d7b3dSmrg	ret = binding_tables();
803428d7b3dSmrg	if (ret != Success)
804428d7b3dSmrg		return ret;
805428d7b3dSmrg	ret = interface_descriptor();
806428d7b3dSmrg	if (ret != Success)
807428d7b3dSmrg		return ret;
808428d7b3dSmrg	ret = vfe_state(VFE_VLD_MODE);
809428d7b3dSmrg	if (ret != Success)
810428d7b3dSmrg		return ret;
811428d7b3dSmrg
812428d7b3dSmrg	LOCK_HARDWARE(intel_ctx->hw_context);
813428d7b3dSmrg	flush();
814428d7b3dSmrg	UNLOCK_HARDWARE(intel_ctx->hw_context);
815428d7b3dSmrg	return Success;
816428d7b3dSmrg}
817428d7b3dSmrg
818428d7b3dSmrgstatic Status put_slice(Display * display, XvMCContext * context,
819428d7b3dSmrg			unsigned char *slice, int nbytes)
820428d7b3dSmrg{
821428d7b3dSmrg	return Success;
822428d7b3dSmrg}
823428d7b3dSmrg
824428d7b3dSmrgstatic void state_base_address(struct intel_xvmc_hw_context *ctx)
825428d7b3dSmrg{
826428d7b3dSmrg	BATCH_LOCALS;
827428d7b3dSmrg
828428d7b3dSmrg	if (ctx->i965.is_igdng) {
829428d7b3dSmrg		BEGIN_BATCH(8);
830428d7b3dSmrg		OUT_BATCH(BRW_STATE_BASE_ADDRESS | 6);
831428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
832428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
833428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
834428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
835428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
836428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
837428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
838428d7b3dSmrg		ADVANCE_BATCH();
839428d7b3dSmrg	} else {
840428d7b3dSmrg		BEGIN_BATCH(6);
841428d7b3dSmrg		OUT_BATCH(BRW_STATE_BASE_ADDRESS | 4);
842428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
843428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
844428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
845428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
846428d7b3dSmrg		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
847428d7b3dSmrg		ADVANCE_BATCH();
848428d7b3dSmrg	}
849428d7b3dSmrg}
850428d7b3dSmrg
851428d7b3dSmrgstatic void pipeline_select()
852428d7b3dSmrg{
853428d7b3dSmrg	BATCH_LOCALS;
854428d7b3dSmrg	BEGIN_BATCH(1);
855428d7b3dSmrg	OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
856428d7b3dSmrg	ADVANCE_BATCH();
857428d7b3dSmrg}
858428d7b3dSmrg
859428d7b3dSmrgstatic void media_state_pointers(int vfe_mode)
860428d7b3dSmrg{
861428d7b3dSmrg	BATCH_LOCALS;
862428d7b3dSmrg	BEGIN_BATCH(3);
863428d7b3dSmrg	OUT_BATCH(BRW_MEDIA_STATE_POINTERS | 1);
864428d7b3dSmrg	if (vfe_mode == VFE_VLD_MODE)
865428d7b3dSmrg		OUT_RELOC(media_state.vld_state.bo, I915_GEM_DOMAIN_INSTRUCTION,
866428d7b3dSmrg			  0, 1);
867428d7b3dSmrg	else
868428d7b3dSmrg		OUT_BATCH(0);
869428d7b3dSmrg	OUT_RELOC(media_state.vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
870428d7b3dSmrg	ADVANCE_BATCH();
871428d7b3dSmrg}
872428d7b3dSmrg
873428d7b3dSmrgstatic void align_urb_fence()
874428d7b3dSmrg{
875428d7b3dSmrg	BATCH_LOCALS;
876428d7b3dSmrg	int i, offset_to_next_cacheline;
877428d7b3dSmrg	unsigned long batch_offset;
878428d7b3dSmrg	BEGIN_BATCH(3);
879428d7b3dSmrg	batch_offset = (void *)batch_ptr - xvmc_driver->alloc.ptr;
880428d7b3dSmrg	offset_to_next_cacheline = ALIGN(batch_offset, 64) - batch_offset;
881428d7b3dSmrg	if (offset_to_next_cacheline <= 12 && offset_to_next_cacheline != 0) {
882428d7b3dSmrg		for (i = 0; i < offset_to_next_cacheline / 4; i++)
883428d7b3dSmrg			OUT_BATCH(0);
884428d7b3dSmrg		ADVANCE_BATCH();
885428d7b3dSmrg	}
886428d7b3dSmrg}
887428d7b3dSmrg
888428d7b3dSmrgstatic void urb_layout()
889428d7b3dSmrg{
890428d7b3dSmrg	BATCH_LOCALS;
891428d7b3dSmrg	align_urb_fence();
892428d7b3dSmrg	BEGIN_BATCH(3);
893428d7b3dSmrg	OUT_BATCH(BRW_URB_FENCE |
894428d7b3dSmrg		  UF0_VFE_REALLOC |
895428d7b3dSmrg		  UF0_CS_REALLOC |
896428d7b3dSmrg		  UF0_SF_REALLOC |
897428d7b3dSmrg		  UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1);
898428d7b3dSmrg
899428d7b3dSmrg	OUT_BATCH((0 << UF1_CLIP_FENCE_SHIFT) |
900428d7b3dSmrg		  (0 << UF1_GS_FENCE_SHIFT) | (0 << UF1_VS_FENCE_SHIFT));
901428d7b3dSmrg
902428d7b3dSmrg	OUT_BATCH((0 << UF2_CS_FENCE_SHIFT) | (0 << UF2_SF_FENCE_SHIFT) | ((URB_SIZE - CS_SIZE - 1) << UF2_VFE_FENCE_SHIFT) |	/* VFE_SIZE */
903428d7b3dSmrg		  ((URB_SIZE) << UF2_CS_FENCE_SHIFT));	/* CS_SIZE */
904428d7b3dSmrg	ADVANCE_BATCH();
905428d7b3dSmrg}
906428d7b3dSmrg
907428d7b3dSmrgstatic void cs_urb_layout()
908428d7b3dSmrg{
909428d7b3dSmrg	BATCH_LOCALS;
910428d7b3dSmrg	BEGIN_BATCH(2);
911428d7b3dSmrg	OUT_BATCH(BRW_CS_URB_STATE | 0);
912428d7b3dSmrg	OUT_BATCH((CS_SIZE << 4) |	/* URB Entry Allocation Size */
913428d7b3dSmrg		  (1 << 0));	/* Number of URB Entries */
914428d7b3dSmrg	ADVANCE_BATCH();
915428d7b3dSmrg}
916428d7b3dSmrg
917428d7b3dSmrgstatic void cs_buffer()
918428d7b3dSmrg{
919428d7b3dSmrg	BATCH_LOCALS;
920428d7b3dSmrg	BEGIN_BATCH(2);
921428d7b3dSmrg	OUT_BATCH(BRW_CONSTANT_BUFFER | 0 | (1 << 8));
922428d7b3dSmrg	OUT_RELOC(media_state.cs_object.bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
923428d7b3dSmrg		  CS_SIZE);
924428d7b3dSmrg	ADVANCE_BATCH();
925428d7b3dSmrg}
926428d7b3dSmrg
927428d7b3dSmrg/* kick media object to gpu in idct mode*/
928428d7b3dSmrgstatic void send_media_object(XvMCMacroBlock * mb, dri_bo * bo,
929428d7b3dSmrg			      uint32_t offset, enum interface interface)
930428d7b3dSmrg{
931428d7b3dSmrg	BATCH_LOCALS;
932428d7b3dSmrg	BEGIN_BATCH(13);
933428d7b3dSmrg	OUT_BATCH(BRW_MEDIA_OBJECT | 11);
934428d7b3dSmrg	OUT_BATCH(interface);
935428d7b3dSmrg	OUT_BATCH(6 * 128);
936428d7b3dSmrg	OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offset);
937428d7b3dSmrg
938428d7b3dSmrg	OUT_BATCH(mb->x << 4);
939428d7b3dSmrg	OUT_BATCH(mb->y << 4);
940428d7b3dSmrg	OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offset);
941428d7b3dSmrg	OUT_BATCH_SHORT(mb->coded_block_pattern);
942428d7b3dSmrg	OUT_BATCH_SHORT(mb->PMV[0][0][0]);
943428d7b3dSmrg	OUT_BATCH_SHORT(mb->PMV[0][0][1]);
944428d7b3dSmrg	OUT_BATCH_SHORT(mb->PMV[0][1][0]);
945428d7b3dSmrg	OUT_BATCH_SHORT(mb->PMV[0][1][1]);
946428d7b3dSmrg
947428d7b3dSmrg	OUT_BATCH_SHORT(mb->PMV[1][0][0]);
948428d7b3dSmrg	OUT_BATCH_SHORT(mb->PMV[1][0][1]);
949428d7b3dSmrg	OUT_BATCH_SHORT(mb->PMV[1][1][0]);
950428d7b3dSmrg	OUT_BATCH_SHORT(mb->PMV[1][1][1]);
951428d7b3dSmrg	OUT_BATCH_CHAR(mb->dct_type);
952428d7b3dSmrg	OUT_BATCH_CHAR(mb->motion_vertical_field_select);
953428d7b3dSmrg
954428d7b3dSmrg	OUT_BATCH(0xffffffff);
955428d7b3dSmrg	ADVANCE_BATCH();
956428d7b3dSmrg}
957428d7b3dSmrg
958428d7b3dSmrg/* kick media object to gpu in vld mode*/
959428d7b3dSmrgstatic void vld_send_media_object(dri_bo * bo,
960428d7b3dSmrg				  int slice_len, int mb_h_pos, int mb_v_pos,
961428d7b3dSmrg				  int mb_bit_offset, int mb_count,
962428d7b3dSmrg				  int q_scale_code)
963428d7b3dSmrg{
964428d7b3dSmrg	BATCH_LOCALS;
965428d7b3dSmrg	BEGIN_BATCH(6);
966428d7b3dSmrg	OUT_BATCH(BRW_MEDIA_OBJECT | 4);
967428d7b3dSmrg	OUT_BATCH(0);
968428d7b3dSmrg	OUT_BATCH(slice_len);
969428d7b3dSmrg	OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
970428d7b3dSmrg	OUT_BATCH((mb_h_pos << 24) | (mb_v_pos << 16) | (mb_count << 8) |
971428d7b3dSmrg		  (mb_bit_offset));
972428d7b3dSmrg	OUT_BATCH(q_scale_code << 24);
973428d7b3dSmrg	ADVANCE_BATCH();
974428d7b3dSmrg}
975428d7b3dSmrg
976428d7b3dSmrgstatic Status put_slice2(Display * display, XvMCContext * context,
977428d7b3dSmrg			 unsigned char *slice, int nbytes, int sliceCode)
978428d7b3dSmrg{
979428d7b3dSmrg	unsigned int bit_buf;
980428d7b3dSmrg	intel_xvmc_context_ptr intel_ctx = context->privData;
981428d7b3dSmrg	struct intel_xvmc_hw_context *hw_ctx = intel_ctx->hw;
982428d7b3dSmrg	int q_scale_code, mb_row;
983428d7b3dSmrg
984428d7b3dSmrg	mb_row = *(slice - 1) - 1;
985428d7b3dSmrg	bit_buf =
986428d7b3dSmrg	    (slice[0] << 24) | (slice[1] << 16) | (slice[2] << 8) | (slice[3]);
987428d7b3dSmrg
988428d7b3dSmrg	q_scale_code = bit_buf >> 27;
989428d7b3dSmrg
990428d7b3dSmrg	if (media_state.slice_data.bo) {
991428d7b3dSmrg		drm_intel_gem_bo_unmap_gtt(media_state.slice_data.bo);
992428d7b3dSmrg
993428d7b3dSmrg		drm_intel_bo_unreference(media_state.slice_data.bo);
994428d7b3dSmrg	}
995428d7b3dSmrg	media_state.slice_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
996428d7b3dSmrg						       "slice data",
997428d7b3dSmrg						       VLD_MAX_SLICE_SIZE, 64);
998428d7b3dSmrg	if (!media_state.slice_data.bo)
999428d7b3dSmrg		return BadAlloc;
1000428d7b3dSmrg	drm_intel_gem_bo_map_gtt(media_state.slice_data.bo);
1001428d7b3dSmrg
1002428d7b3dSmrg	memcpy(media_state.slice_data.bo->virtual, slice, nbytes);
1003428d7b3dSmrg
1004428d7b3dSmrg	LOCK_HARDWARE(intel_ctx->hw_context);
1005428d7b3dSmrg	state_base_address(hw_ctx);
1006428d7b3dSmrg	pipeline_select();
1007428d7b3dSmrg	media_state_pointers(VFE_VLD_MODE);
1008428d7b3dSmrg	urb_layout();
1009428d7b3dSmrg	cs_urb_layout();
1010428d7b3dSmrg	cs_buffer();
1011428d7b3dSmrg	vld_send_media_object(media_state.slice_data.bo,
1012428d7b3dSmrg			      nbytes, 0, mb_row, 6, 127, q_scale_code);
1013428d7b3dSmrg	intelFlushBatch();
1014428d7b3dSmrg	UNLOCK_HARDWARE(intel_ctx->hw_context);
1015428d7b3dSmrg
1016428d7b3dSmrg	return Success;
1017428d7b3dSmrg}
1018428d7b3dSmrg
1019428d7b3dSmrgstatic Status render_surface(Display * display,
1020428d7b3dSmrg			     XvMCContext * context,
1021428d7b3dSmrg			     unsigned int picture_structure,
1022428d7b3dSmrg			     XvMCSurface * target_surface,
1023428d7b3dSmrg			     XvMCSurface * past_surface,
1024428d7b3dSmrg			     XvMCSurface * future_surface,
1025428d7b3dSmrg			     unsigned int flags,
1026428d7b3dSmrg			     unsigned int num_macroblocks,
1027428d7b3dSmrg			     unsigned int first_macroblock,
1028428d7b3dSmrg			     XvMCMacroBlockArray * macroblock_array,
1029428d7b3dSmrg			     XvMCBlockArray * blocks)
1030428d7b3dSmrg{
1031428d7b3dSmrg	struct intel_xvmc_surface *priv_target, *priv_past, *priv_future;
1032428d7b3dSmrg	intel_xvmc_context_ptr intel_ctx;
1033428d7b3dSmrg	XvMCMacroBlock *mb;
1034428d7b3dSmrg	Status ret;
1035428d7b3dSmrg	unsigned short *block_ptr;
1036428d7b3dSmrg	int i, j;
1037428d7b3dSmrg	int block_offset = 0;
1038428d7b3dSmrg	struct intel_xvmc_hw_context *hw_ctx;
1039428d7b3dSmrg
1040428d7b3dSmrg	intel_ctx = context->privData;
1041428d7b3dSmrg
1042428d7b3dSmrg	hw_ctx = (struct intel_xvmc_hw_context *)context->privData;
1043428d7b3dSmrg	priv_target = target_surface->privData;
1044428d7b3dSmrg	priv_past = past_surface ? past_surface->privData : NULL;
1045428d7b3dSmrg	priv_future = future_surface ? future_surface->privData : NULL;
1046428d7b3dSmrg
1047428d7b3dSmrg	ret = setup_surface(priv_target, priv_past, priv_future,
1048428d7b3dSmrg			    context->width, context->height);
1049428d7b3dSmrg	if (ret != Success)
1050428d7b3dSmrg		return ret;
1051428d7b3dSmrg	ret = binding_tables();
1052428d7b3dSmrg	if (ret != Success)
1053428d7b3dSmrg		return ret;
1054428d7b3dSmrg	ret = interface_descriptor();
1055428d7b3dSmrg	if (ret != Success)
1056428d7b3dSmrg		return ret;
1057428d7b3dSmrg	ret = cs_init(INTERFACE_NUM);
1058428d7b3dSmrg	if (ret != Success)
1059428d7b3dSmrg		return ret;
1060428d7b3dSmrg	ret = vfe_state(VFE_GENERIC_MODE);
1061428d7b3dSmrg	if (ret != Success)
1062428d7b3dSmrg		return ret;
1063428d7b3dSmrg
1064428d7b3dSmrg	if (media_state.mb_data.bo) {
1065428d7b3dSmrg		drm_intel_gem_bo_unmap_gtt(media_state.mb_data.bo);
1066428d7b3dSmrg
1067428d7b3dSmrg		drm_intel_bo_unreference(media_state.mb_data.bo);
1068428d7b3dSmrg	}
1069428d7b3dSmrg	unsigned int block_num =
1070428d7b3dSmrg	    (((context->width + 15) >> 4) * ((context->height + 15) >> 4));
1071428d7b3dSmrg	unsigned int surface_size = (64 * sizeof(short) * 6 * block_num);
1072428d7b3dSmrg	media_state.mb_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
1073428d7b3dSmrg						    "macroblock data",
1074428d7b3dSmrg						    surface_size, 64);
1075428d7b3dSmrg	if (!media_state.mb_data.bo)
1076428d7b3dSmrg		return BadAlloc;
1077428d7b3dSmrg	drm_intel_gem_bo_map_gtt(media_state.mb_data.bo);
1078428d7b3dSmrg
1079428d7b3dSmrg	block_ptr = media_state.mb_data.bo->virtual;
1080428d7b3dSmrg	unsigned short *mb_block_ptr;
1081428d7b3dSmrg	for (i = first_macroblock; i < num_macroblocks + first_macroblock; i++) {
1082428d7b3dSmrg		mb = &macroblock_array->macro_blocks[i];
1083428d7b3dSmrg		mb_block_ptr = &blocks->blocks[(mb->index << 6)];
1084428d7b3dSmrg
1085428d7b3dSmrg		if (mb->coded_block_pattern & 0x20) {
1086428d7b3dSmrg			for (j = 0; j < 8; j++)
1087428d7b3dSmrg				memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j,
1088428d7b3dSmrg				       16);
1089428d7b3dSmrg			mb_block_ptr += 64;
1090428d7b3dSmrg		}
1091428d7b3dSmrg		if (mb->coded_block_pattern & 0x10) {
1092428d7b3dSmrg			for (j = 0; j < 8; j++)
1093428d7b3dSmrg				memcpy(block_ptr + 16 * j + 8,
1094428d7b3dSmrg				       mb_block_ptr + 8 * j, 16);
1095428d7b3dSmrg			mb_block_ptr += 64;
1096428d7b3dSmrg		}
1097428d7b3dSmrg
1098428d7b3dSmrg		block_ptr += 2 * 64;
1099428d7b3dSmrg		if (mb->coded_block_pattern & 0x08) {
1100428d7b3dSmrg			for (j = 0; j < 8; j++)
1101428d7b3dSmrg				memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j,
1102428d7b3dSmrg				       16);
1103428d7b3dSmrg			mb_block_ptr += 64;
1104428d7b3dSmrg		}
1105428d7b3dSmrg		if (mb->coded_block_pattern & 0x04) {
1106428d7b3dSmrg			for (j = 0; j < 8; j++)
1107428d7b3dSmrg				memcpy(block_ptr + 16 * j + 8,
1108428d7b3dSmrg				       mb_block_ptr + 8 * j, 16);
1109428d7b3dSmrg			mb_block_ptr += 64;
1110428d7b3dSmrg		}
1111428d7b3dSmrg
1112428d7b3dSmrg		block_ptr += 2 * 64;
1113428d7b3dSmrg		if (mb->coded_block_pattern & 0x2) {
1114428d7b3dSmrg			memcpy(block_ptr, mb_block_ptr, 128);
1115428d7b3dSmrg			mb_block_ptr += 64;
1116428d7b3dSmrg		}
1117428d7b3dSmrg
1118428d7b3dSmrg		block_ptr += 64;
1119428d7b3dSmrg		if (mb->coded_block_pattern & 0x1)
1120428d7b3dSmrg			memcpy(block_ptr, mb_block_ptr, 128);
1121428d7b3dSmrg		block_ptr += 64;
1122428d7b3dSmrg	}
1123428d7b3dSmrg
1124428d7b3dSmrg	LOCK_HARDWARE(intel_ctx->hw_context);
1125428d7b3dSmrg	state_base_address(hw_ctx);
1126428d7b3dSmrg	flush();
1127428d7b3dSmrg	pipeline_select();
1128428d7b3dSmrg	urb_layout();
1129428d7b3dSmrg	media_state_pointers(VFE_GENERIC_MODE);
1130428d7b3dSmrg	cs_urb_layout();
1131428d7b3dSmrg	cs_buffer();
1132428d7b3dSmrg	for (i = first_macroblock;
1133428d7b3dSmrg	     i < num_macroblocks + first_macroblock;
1134428d7b3dSmrg	     i++, block_offset += 128 * 6) {
1135428d7b3dSmrg		mb = &macroblock_array->macro_blocks[i];
1136428d7b3dSmrg
1137428d7b3dSmrg		if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
1138428d7b3dSmrg			send_media_object(mb, media_state.mb_data.bo,
1139428d7b3dSmrg					  block_offset,
1140428d7b3dSmrg					  FRAME_INTRA + INTERFACE_NUM);
1141428d7b3dSmrg		} else {
1142428d7b3dSmrg			if (((mb->motion_type & 3) == XVMC_PREDICTION_FRAME)) {
1143428d7b3dSmrg				if ((mb->macroblock_type &
1144428d7b3dSmrg				     XVMC_MB_TYPE_MOTION_FORWARD)) {
1145428d7b3dSmrg					if ((mb->macroblock_type &
1146428d7b3dSmrg					     XVMC_MB_TYPE_MOTION_BACKWARD)) {
1147428d7b3dSmrg						send_media_object(mb,
1148428d7b3dSmrg								  media_state.mb_data.
1149428d7b3dSmrg								  bo,
1150428d7b3dSmrg								  block_offset,
1151428d7b3dSmrg								  FRAME_FRAME_PRED_BIDIRECT
1152428d7b3dSmrg								  +
1153428d7b3dSmrg								  INTERFACE_NUM);
1154428d7b3dSmrg					} else {
1155428d7b3dSmrg						send_media_object(mb,
1156428d7b3dSmrg								  media_state.mb_data.
1157428d7b3dSmrg								  bo,
1158428d7b3dSmrg								  block_offset,
1159428d7b3dSmrg								  FRAME_FRAME_PRED_FORWARD
1160428d7b3dSmrg								  +
1161428d7b3dSmrg								  INTERFACE_NUM);
1162428d7b3dSmrg					}
1163428d7b3dSmrg				} else
1164428d7b3dSmrg				    if ((mb->macroblock_type &
1165428d7b3dSmrg					 XVMC_MB_TYPE_MOTION_BACKWARD)) {
1166428d7b3dSmrg					send_media_object(mb,
1167428d7b3dSmrg							  media_state.
1168428d7b3dSmrg							  mb_data.bo,
1169428d7b3dSmrg							  block_offset,
1170428d7b3dSmrg							  FRAME_FRAME_PRED_BACKWARD
1171428d7b3dSmrg							  + INTERFACE_NUM);
1172428d7b3dSmrg				}
1173428d7b3dSmrg			} else if ((mb->motion_type & 3) ==
1174428d7b3dSmrg				   XVMC_PREDICTION_FIELD) {
1175428d7b3dSmrg				if ((mb->macroblock_type &
1176428d7b3dSmrg				     XVMC_MB_TYPE_MOTION_FORWARD)) {
1177428d7b3dSmrg					if (((mb->macroblock_type &
1178428d7b3dSmrg					      XVMC_MB_TYPE_MOTION_BACKWARD))) {
1179428d7b3dSmrg						send_media_object(mb,
1180428d7b3dSmrg								  media_state.mb_data.
1181428d7b3dSmrg								  bo,
1182428d7b3dSmrg								  block_offset,
1183428d7b3dSmrg								  FRAME_FIELD_PRED_BIDIRECT
1184428d7b3dSmrg								  +
1185428d7b3dSmrg								  INTERFACE_NUM);
1186428d7b3dSmrg					} else {
1187428d7b3dSmrg						send_media_object(mb,
1188428d7b3dSmrg								  media_state.mb_data.
1189428d7b3dSmrg								  bo,
1190428d7b3dSmrg								  block_offset,
1191428d7b3dSmrg								  FRAME_FIELD_PRED_FORWARD
1192428d7b3dSmrg								  +
1193428d7b3dSmrg								  INTERFACE_NUM);
1194428d7b3dSmrg					}
1195428d7b3dSmrg				} else
1196428d7b3dSmrg				    if ((mb->macroblock_type &
1197428d7b3dSmrg					 XVMC_MB_TYPE_MOTION_BACKWARD)) {
1198428d7b3dSmrg					send_media_object(mb,
1199428d7b3dSmrg							  media_state.
1200428d7b3dSmrg							  mb_data.bo,
1201428d7b3dSmrg							  block_offset,
1202428d7b3dSmrg							  FRAME_FIELD_PRED_BACKWARD
1203428d7b3dSmrg							  + INTERFACE_NUM);
1204428d7b3dSmrg				}
1205428d7b3dSmrg			} else {
1206428d7b3dSmrg				send_media_object(mb, media_state.mb_data.bo, block_offset, FRAME_FIELD_PRED_BIDIRECT + INTERFACE_NUM);	/*dual prime */
1207428d7b3dSmrg			}
1208428d7b3dSmrg		}
1209428d7b3dSmrg	}
1210428d7b3dSmrg	intelFlushBatch();
1211428d7b3dSmrg	UNLOCK_HARDWARE(intel_ctx->hw_context);
1212428d7b3dSmrg	return Success;
1213428d7b3dSmrg}
1214428d7b3dSmrg
1215428d7b3dSmrgstruct _intel_xvmc_driver xvmc_vld_driver = {
1216428d7b3dSmrg	.type = XVMC_I965_MPEG2_VLD,
1217428d7b3dSmrg	.create_context = create_context,
1218428d7b3dSmrg	.destroy_context = destroy_context,
1219428d7b3dSmrg	.load_qmatrix = load_qmatrix,
1220428d7b3dSmrg	.begin_surface = begin_surface,
1221428d7b3dSmrg	.render_surface = render_surface,
1222428d7b3dSmrg	.put_slice = put_slice,
1223428d7b3dSmrg	.put_slice2 = put_slice2
1224428d7b3dSmrg};
1225