1 /*
2  * Copyright © 2009 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  * Author:
24  *    Zou Nan hai <nanhai.zou@intel.com>
25  */
26 #include "intel_xvmc_private.h"
27 #include "i830_reg.h"
28 #include "i965_reg.h"
29 #include "brw_defines.h"
30 #include "brw_structs.h"
31 
32 #ifndef ALIGN
33 #define ALIGN(m,n) (((m) + (n) - 1) & ~((n) - 1))
34 #endif
35 
36 #define BATCH_STRUCT(x) intelBatchbufferData(&x, sizeof(x), 0)
37 #define VLD_MAX_SLICE_SIZE (32 * 1024)
38 #define CS_SIZE 	30
39 #define URB_SIZE 	384
40 /* idct table */
41 #define C0 23170
42 #define C1 22725
43 #define C2 21407
44 #define C3 19266
45 #define C4 16383
46 #define C5 12873
47 #define C6 8867
48 #define C7 4520
49 const uint32_t idct_table[] = {
50 	C4, C1, C2, C3, C4, C5, C6, C7,	//g5
51 	C4, C1, C2, C3, C4, C5, C6, C7,
52 	C4, C3, C6, -C7, -C4, -C1, -C2, -C5,
53 	C4, C3, C6, -C7, -C4, -C1, -C2, -C5,
54 	C4, C5, -C6, -C1, -C4, C7, C2, C3,
55 	C4, C5, -C6, -C1, -C4, C7, C2, C3,
56 	C4, C7, -C2, -C5, C4, C3, -C6, -C1,
57 	C4, C7, -C2, -C5, C4, C3, -C6, -C1,
58 	C4, -C7, -C2, C5, C4, -C3, -C6, C1,
59 	C4, -C7, -C2, C5, C4, -C3, -C6, C1,
60 	C4, -C5, -C6, C1, -C4, -C7, C2, -C3,
61 	C4, -C5, -C6, C1, -C4, -C7, C2, -C3,
62 	C4, -C3, C6, C7, -C4, C1, -C2, C5,
63 	C4, -C3, C6, C7, -C4, C1, -C2, C5,
64 	C4, -C1, C2, -C3, C4, -C5, C6, -C7,
65 	C4, -C1, C2, -C3, C4, -C5, C6, -C7	//g20
66 };
67 
68 #undef C0
69 #undef C1
70 #undef C2
71 #undef C3
72 #undef C4
73 #undef C5
74 #undef C6
75 #undef C7
76 
77 #define INTERFACE_NUM	8
78 enum interface {
79 	FRAME_INTRA = 0,
80 	FRAME_FRAME_PRED_FORWARD,
81 	FRAME_FRAME_PRED_BACKWARD,
82 	FRAME_FRAME_PRED_BIDIRECT,
83 	FRAME_FIELD_PRED_FORWARD,
84 	FRAME_FIELD_PRED_BACKWARD,
85 	FRAME_FIELD_PRED_BIDIRECT,
86 	LIB_INTERFACE
87 };
88 
89 /*kernels for vld mode*/
90 static uint32_t lib_kernel[][4] = {
91 #include "shader/vld/lib.g4b"
92 };
93 
94 static uint32_t ipicture_kernel[][4] = {
95 #include "shader/vld/ipicture.g4b"
96 };
97 
98 static uint32_t frame_forward_kernel[][4] = {
99 #include "shader/vld/frame_forward.g4b"
100 };
101 
102 static uint32_t frame_backward_kernel[][4] = {
103 #include "shader/vld/frame_backward.g4b"
104 };
105 
106 static uint32_t frame_f_b_kernel[][4] = {
107 #include "shader/vld/frame_f_b.g4b"
108 };
109 
110 static uint32_t field_forward_kernel[][4] = {
111 #include "shader/vld/field_forward.g4b"
112 };
113 
114 static uint32_t field_backward_kernel[][4] = {
115 #include "shader/vld/field_backward.g4b"
116 };
117 
118 static uint32_t field_f_b_kernel[][4] = {
119 #include "shader/vld/field_f_b.g4b"
120 };
121 
122 /* on Ironlake */
123 static uint32_t lib_kernel_gen5[][4] = {
124 #include "shader/vld/lib.g4b.gen5"
125 };
126 
127 static uint32_t ipicture_kernel_gen5[][4] = {
128 #include "shader/vld/ipicture.g4b.gen5"
129 };
130 
131 static uint32_t frame_forward_kernel_gen5[][4] = {
132 #include "shader/vld/frame_forward.g4b.gen5"
133 };
134 
135 static uint32_t frame_backward_kernel_gen5[][4] = {
136 #include "shader/vld/frame_backward.g4b.gen5"
137 };
138 
139 static uint32_t frame_f_b_kernel_gen5[][4] = {
140 #include "shader/vld/frame_f_b.g4b.gen5"
141 };
142 
143 static uint32_t field_forward_kernel_gen5[][4] = {
144 #include "shader/vld/field_forward.g4b.gen5"
145 };
146 
147 static uint32_t field_backward_kernel_gen5[][4] = {
148 #include "shader/vld/field_backward.g4b.gen5"
149 };
150 
151 static uint32_t field_f_b_kernel_gen5[][4] = {
152 #include "shader/vld/field_f_b.g4b.gen5"
153 };
154 
155 /*kernels for mc mode*/
156 static uint32_t lib_kernel_idct[][4] = {
157 #include "shader/mc/lib_igd.g4b"
158 };
159 
160 static uint32_t ipicture_kernel_idct[][4] = {
161 #include "shader/mc/ipicture_igd.g4b"
162 };
163 
164 static uint32_t frame_forward_kernel_idct[][4] = {
165 #include "shader/mc/frame_forward_igd.g4b"
166 };
167 
168 static uint32_t frame_backward_kernel_idct[][4] = {
169 #include "shader/mc/frame_backward_igd.g4b"
170 };
171 
172 static uint32_t frame_f_b_kernel_idct[][4] = {
173 #include "shader/mc/frame_f_b_igd.g4b"
174 };
175 
176 static uint32_t field_forward_kernel_idct[][4] = {
177 #include "shader/mc/field_forward_igd.g4b"
178 };
179 
180 static uint32_t field_backward_kernel_idct[][4] = {
181 #include "shader/mc/field_backward_igd.g4b"
182 };
183 
184 static uint32_t field_f_b_kernel_idct[][4] = {
185 #include "shader/mc/field_f_b_igd.g4b"
186 };
187 
188 /* on Ironlake */
189 static uint32_t lib_kernel_idct_gen5[][4] = {
190 #include "shader/mc/lib_igd.g4b.gen5"
191 };
192 
193 static uint32_t ipicture_kernel_idct_gen5[][4] = {
194 #include "shader/mc/ipicture_igd.g4b.gen5"
195 };
196 
197 static uint32_t frame_forward_kernel_idct_gen5[][4] = {
198 #include "shader/mc/frame_forward_igd.g4b.gen5"
199 };
200 
201 static uint32_t frame_backward_kernel_idct_gen5[][4] = {
202 #include "shader/mc/frame_backward_igd.g4b.gen5"
203 };
204 
205 static uint32_t frame_f_b_kernel_idct_gen5[][4] = {
206 #include "shader/mc/frame_f_b_igd.g4b.gen5"
207 };
208 
209 static uint32_t field_forward_kernel_idct_gen5[][4] = {
210 #include "shader/mc/field_forward_igd.g4b.gen5"
211 };
212 
213 static uint32_t field_backward_kernel_idct_gen5[][4] = {
214 #include "shader/mc/field_backward_igd.g4b.gen5"
215 };
216 
217 static uint32_t field_f_b_kernel_idct_gen5[][4] = {
218 #include "shader/mc/field_f_b_igd.g4b.gen5"
219 };
220 
221 struct media_kernel {
222 	uint32_t(*bin)[4];
223 	int size;
224 };
225 static struct media_kernel media_kernels[] = {
226 	/*kernels for vld mode */
227 	{ipicture_kernel, sizeof(ipicture_kernel)}
228 	,
229 	{frame_forward_kernel, sizeof(frame_forward_kernel)}
230 	,
231 	{frame_backward_kernel, sizeof(frame_backward_kernel)}
232 	,
233 	{frame_f_b_kernel, sizeof(frame_f_b_kernel)}
234 	,
235 	{field_forward_kernel, sizeof(field_forward_kernel)}
236 	,
237 	{field_backward_kernel, sizeof(field_backward_kernel)}
238 	,
239 	{field_f_b_kernel, sizeof(field_f_b_kernel)}
240 	,
241 	{lib_kernel, sizeof(lib_kernel)}
242 	,
243 	/*kernels for mc mode */
244 	{ipicture_kernel_idct, sizeof(ipicture_kernel_idct)}
245 	,
246 	{frame_forward_kernel_idct, sizeof(frame_forward_kernel_idct)}
247 	,
248 	{frame_backward_kernel_idct, sizeof(frame_backward_kernel_idct)}
249 	,
250 	{frame_f_b_kernel_idct, sizeof(frame_f_b_kernel_idct)}
251 	,
252 	{field_forward_kernel_idct, sizeof(field_forward_kernel_idct)}
253 	,
254 	{field_backward_kernel_idct, sizeof(field_backward_kernel_idct)}
255 	,
256 	{field_f_b_kernel_idct, sizeof(field_f_b_kernel_idct)}
257 	,
258 	{lib_kernel_idct, sizeof(lib_kernel_idct)}
259 };
260 
261 static struct media_kernel media_gen5_kernels[] = {
262 	/*kernels for vld mode */
263 	{ipicture_kernel_gen5, sizeof(ipicture_kernel_gen5)}
264 	,
265 	{frame_forward_kernel_gen5, sizeof(frame_forward_kernel_gen5)}
266 	,
267 	{frame_backward_kernel_gen5, sizeof(frame_backward_kernel_gen5)}
268 	,
269 	{frame_f_b_kernel_gen5, sizeof(frame_f_b_kernel_gen5)}
270 	,
271 	{field_forward_kernel_gen5, sizeof(field_forward_kernel_gen5)}
272 	,
273 	{field_backward_kernel_gen5, sizeof(field_backward_kernel_gen5)}
274 	,
275 	{field_f_b_kernel_gen5, sizeof(field_f_b_kernel_gen5)}
276 	,
277 	{lib_kernel_gen5, sizeof(lib_kernel_gen5)}
278 	,
279 	/*kernels for mc mode */
280 	{ipicture_kernel_idct_gen5, sizeof(ipicture_kernel_idct_gen5)}
281 	,
282 	{frame_forward_kernel_idct_gen5, sizeof(frame_forward_kernel_idct_gen5)}
283 	,
284 	{frame_backward_kernel_idct_gen5,
285 	 sizeof(frame_backward_kernel_idct_gen5)}
286 	,
287 	{frame_f_b_kernel_idct_gen5, sizeof(frame_f_b_kernel_idct_gen5)}
288 	,
289 	{field_forward_kernel_idct_gen5, sizeof(field_forward_kernel_idct_gen5)}
290 	,
291 	{field_backward_kernel_idct_gen5,
292 	 sizeof(field_backward_kernel_idct_gen5)}
293 	,
294 	{field_f_b_kernel_idct_gen5, sizeof(field_f_b_kernel_idct_gen5)}
295 	,
296 	{lib_kernel_idct_gen5, sizeof(lib_kernel_idct_gen5)}
297 };
298 
299 #define MEDIA_KERNEL_NUM (sizeof(media_kernels)/sizeof(media_kernels[0]))
300 
301 struct media_kernel_obj {
302 	dri_bo *bo;
303 };
304 
305 struct interface_descriptor_obj {
306 	dri_bo *bo;
307 	struct media_kernel_obj kernels[MEDIA_KERNEL_NUM];
308 };
309 
310 struct vfe_state_obj {
311 	dri_bo *bo;
312 	struct interface_descriptor_obj interface;
313 };
314 
315 struct vld_state_obj {
316 	dri_bo *bo;
317 };
318 
319 struct surface_obj {
320 	dri_bo *bo;
321 };
322 
323 struct surface_state_obj {
324 	struct surface_obj surface;
325 	dri_bo *bo;
326 };
327 
328 #define MAX_SURFACES 12
329 struct binding_table_obj {
330 	dri_bo *bo;
331 	struct surface_state_obj surface_states[MAX_SURFACES];
332 };
333 
334 struct slice_data_obj {
335 	dri_bo *bo;
336 };
337 
338 struct mb_data_obj {
339 	dri_bo *bo;
340 };
341 
342 struct cs_state_obj {
343 	dri_bo *bo;
344 };
345 
346 static struct media_state {
347 	struct vfe_state_obj vfe_state;
348 	struct vld_state_obj vld_state;
349 	struct binding_table_obj binding_table;
350 	struct cs_state_obj cs_object;
351 	struct slice_data_obj slice_data;
352 	struct mb_data_obj mb_data;
353 } media_state;
354 
355 /* XvMCQMatrix * 2 + idct_table + 8 * kernel offset pointer */
356 #define CS_OBJECT_SIZE (32*20 + sizeof(unsigned int) * 8)
free_object(struct media_state * s)357 static void free_object(struct media_state *s)
358 {
359 	int i;
360 #define FREE_ONE_BO(bo) \
361     if (bo) \
362         drm_intel_bo_unreference(bo)
363 	FREE_ONE_BO(s->vfe_state.bo);
364 	FREE_ONE_BO(s->vfe_state.interface.bo);
365 	for (i = 0; i < MEDIA_KERNEL_NUM; i++)
366 		FREE_ONE_BO(s->vfe_state.interface.kernels[i].bo);
367 	FREE_ONE_BO(s->binding_table.bo);
368 	for (i = 0; i < MAX_SURFACES; i++)
369 		FREE_ONE_BO(s->binding_table.surface_states[i].bo);
370 	FREE_ONE_BO(s->slice_data.bo);
371 	FREE_ONE_BO(s->mb_data.bo);
372 	FREE_ONE_BO(s->cs_object.bo);
373 	FREE_ONE_BO(s->vld_state.bo);
374 }
375 
alloc_object(struct media_state * s)376 static int alloc_object(struct media_state *s)
377 {
378 	int i;
379 
380 	for (i = 0; i < MAX_SURFACES; i++) {
381 		s->binding_table.surface_states[i].bo =
382 		    drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state",
383 				       sizeof(struct brw_surface_state),
384 				       0x1000);
385 		if (!s->binding_table.surface_states[i].bo)
386 			goto out;
387 	}
388 	return 0;
389 out:
390 	free_object(s);
391 	return BadAlloc;
392 }
393 
flush()394 static void flush()
395 {
396 #define FLUSH_STATE_CACHE  	1
397 	struct brw_mi_flush f;
398 	memset(&f, 0, sizeof(f));
399 	f.opcode = CMD_MI_FLUSH;
400 	f.flags = (1 << FLUSH_STATE_CACHE);
401 	BATCH_STRUCT(f);
402 }
403 
vfe_state(int vfe_mode)404 static Status vfe_state(int vfe_mode)
405 {
406 	struct brw_vfe_state tmp, *vfe_state = &tmp;
407 	memset(vfe_state, 0, sizeof(*vfe_state));
408 	if (vfe_mode == VFE_VLD_MODE) {
409 		vfe_state->vfe0.extend_vfe_state_present = 1;
410 	} else {
411 		vfe_state->vfe0.extend_vfe_state_present = 0;
412 	}
413 	vfe_state->vfe1.vfe_mode = vfe_mode;
414 	vfe_state->vfe1.num_urb_entries = 1;
415 	vfe_state->vfe1.children_present = 0;
416 	vfe_state->vfe1.urb_entry_alloc_size = 2;
417 	vfe_state->vfe1.max_threads = 31;
418 	vfe_state->vfe2.interface_descriptor_base =
419 	    media_state.vfe_state.interface.bo->offset >> 4;
420 
421 	if (media_state.vfe_state.bo)
422 		drm_intel_bo_unreference(media_state.vfe_state.bo);
423 
424 	media_state.vfe_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
425 						      "vfe state",
426 						      sizeof(struct
427 							     brw_vfe_state),
428 						      0x1000);
429 	if (!media_state.vfe_state.bo)
430 		return BadAlloc;
431 
432 	drm_intel_bo_subdata(media_state.vfe_state.bo, 0, sizeof(tmp), &tmp);
433 
434 	drm_intel_bo_emit_reloc(media_state.vfe_state.bo,
435 				offsetof(struct brw_vfe_state, vfe2),
436 				media_state.vfe_state.interface.bo, 0,
437 				I915_GEM_DOMAIN_INSTRUCTION, 0);
438 	return Success;
439 }
440 
interface_descriptor()441 static Status interface_descriptor()
442 {
443 	int i;
444 	struct brw_interface_descriptor tmp, *desc = &tmp;
445 
446 	if (media_state.vfe_state.interface.bo)
447 		drm_intel_bo_unreference(media_state.vfe_state.interface.bo);
448 
449 	media_state.vfe_state.interface.bo =
450 	    drm_intel_bo_alloc(xvmc_driver->bufmgr, "interfaces",
451 			       MEDIA_KERNEL_NUM *
452 			       sizeof(struct brw_interface_descriptor), 0x1000);
453 	if (!media_state.vfe_state.interface.bo)
454 		return BadAlloc;
455 
456 	for (i = 0; i < MEDIA_KERNEL_NUM; i++) {
457 		memset(desc, 0, sizeof(*desc));
458 		desc->desc0.grf_reg_blocks = 15;
459 		desc->desc0.kernel_start_pointer =
460 		    media_state.vfe_state.interface.kernels[i].bo->offset >> 6;
461 
462 		desc->desc1.const_urb_entry_read_offset = 0;
463 		desc->desc1.const_urb_entry_read_len = 30;
464 
465 		desc->desc3.binding_table_entry_count = MAX_SURFACES - 1;
466 		desc->desc3.binding_table_pointer =
467 		    media_state.binding_table.bo->offset >> 5;
468 
469 		drm_intel_bo_subdata(media_state.vfe_state.interface.bo,
470 				     i * sizeof(tmp), sizeof(tmp), desc);
471 
472 		drm_intel_bo_emit_reloc(media_state.vfe_state.interface.bo,
473 					i * sizeof(*desc) + offsetof(struct
474 								     brw_interface_descriptor,
475 								     desc0),
476 					media_state.vfe_state.
477 					interface.kernels[i].bo,
478 					desc->desc0.grf_reg_blocks,
479 					I915_GEM_DOMAIN_INSTRUCTION, 0);
480 
481 		drm_intel_bo_emit_reloc(media_state.vfe_state.interface.bo,
482 					i * sizeof(*desc) + offsetof(struct
483 								     brw_interface_descriptor,
484 								     desc3),
485 					media_state.binding_table.bo,
486 					desc->desc3.binding_table_entry_count,
487 					I915_GEM_DOMAIN_INSTRUCTION, 0);
488 	}
489 	return Success;
490 }
491 
setup_media_kernels(struct intel_xvmc_hw_context * ctx)492 static int setup_media_kernels(struct intel_xvmc_hw_context *ctx)
493 {
494 	int i;
495 
496 	assert(MEDIA_KERNEL_NUM ==
497 	       sizeof(media_gen5_kernels) / sizeof(media_gen5_kernels[0]));
498 
499 	for (i = 0; i < MEDIA_KERNEL_NUM; i++) {
500 		if (ctx->i965.is_igdng)
501 			media_state.vfe_state.interface.kernels[i].bo =
502 			    drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernel",
503 					       media_gen5_kernels[i].size,
504 					       0x1000);
505 		else
506 			media_state.vfe_state.interface.kernels[i].bo =
507 			    drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernels",
508 					       media_kernels[i].size, 0x1000);
509 
510 		if (!media_state.vfe_state.interface.kernels[i].bo)
511 			goto out;
512 	}
513 
514 	for (i = 0; i < MEDIA_KERNEL_NUM; i++) {
515 		dri_bo *bo = media_state.vfe_state.interface.kernels[i].bo;
516 
517 		if (ctx->i965.is_igdng)
518 			drm_intel_bo_subdata(bo, 0, media_gen5_kernels[i].size,
519 					     media_gen5_kernels[i].bin);
520 		else
521 			drm_intel_bo_subdata(bo, 0, media_kernels[i].size,
522 					     media_kernels[i].bin);
523 	}
524 	return 0;
525 out:
526 	free_object(&media_state);
527 	return BadAlloc;
528 }
529 
binding_tables()530 static Status binding_tables()
531 {
532 	unsigned int table[MAX_SURFACES];
533 	int i;
534 
535 	if (media_state.binding_table.bo)
536 		drm_intel_bo_unreference(media_state.binding_table.bo);
537 	media_state.binding_table.bo =
538 	    drm_intel_bo_alloc(xvmc_driver->bufmgr, "binding_table",
539 			       MAX_SURFACES * 4, 0x1000);
540 	if (!media_state.binding_table.bo)
541 		return BadAlloc;
542 
543 	for (i = 0; i < MAX_SURFACES; i++) {
544 		table[i] =
545 		    media_state.binding_table.surface_states[i].bo->offset;
546 		drm_intel_bo_emit_reloc(media_state.binding_table.bo,
547 					i * sizeof(unsigned int),
548 					media_state.
549 					binding_table.surface_states[i].bo, 0,
550 					I915_GEM_DOMAIN_INSTRUCTION, 0);
551 	}
552 
553 	drm_intel_bo_subdata(media_state.binding_table.bo, 0, sizeof(table),
554 			     table);
555 	return Success;
556 }
557 
cs_init(int interface_offset)558 static Status cs_init(int interface_offset)
559 {
560 	char buf[CS_OBJECT_SIZE];
561 	unsigned int *lib_reloc;
562 	int i;
563 
564 	if (media_state.cs_object.bo)
565 		drm_intel_bo_unreference(media_state.cs_object.bo);
566 
567 	media_state.cs_object.bo =
568 	    drm_intel_bo_alloc(xvmc_driver->bufmgr, "cs object", CS_OBJECT_SIZE,
569 			       64);
570 	if (!media_state.cs_object.bo)
571 		return BadAlloc;
572 
573 	memcpy(buf + 32 * 4, idct_table, sizeof(idct_table));
574 	/* idct lib reloction */
575 	lib_reloc = (unsigned int *)(buf + 32 * 20);
576 	for (i = 0; i < 8; i++)
577 		lib_reloc[i] =
578 		    media_state.vfe_state.interface.kernels[LIB_INTERFACE +
579 							    interface_offset].bo->
580 		    offset;
581 	drm_intel_bo_subdata(media_state.cs_object.bo, 32 * 4,
582 			     32 * 16 + 8 * sizeof(unsigned int), buf + 32 * 4);
583 
584 	for (i = 0; i < 8; i++)
585 		drm_intel_bo_emit_reloc(media_state.cs_object.bo,
586 					32 * 20 + sizeof(unsigned int) * i,
587 					media_state.vfe_state.
588 					interface.kernels[LIB_INTERFACE +
589 							  interface_offset].bo,
590 					0, I915_GEM_DOMAIN_INSTRUCTION, 0);
591 
592 	return Success;
593 }
594 
595 #define STRIDE(w)               (w)
596 #define SIZE_YUV420(w, h)       (h * (STRIDE(w) + STRIDE(w >> 1)))
create_context(Display * display,XvMCContext * context,int priv_count,CARD32 * priv_data)597 static Status create_context(Display * display, XvMCContext * context,
598 			     int priv_count, CARD32 * priv_data)
599 {
600 	struct intel_xvmc_context *intel_ctx;
601 	struct intel_xvmc_hw_context *hw_ctx;
602 	hw_ctx = (struct intel_xvmc_hw_context *)priv_data;
603 
604 	intel_ctx = calloc(1, sizeof(struct intel_xvmc_context));
605 	if (!intel_ctx)
606 		return BadAlloc;
607 	intel_ctx->hw = hw_ctx;
608 	context->privData = intel_ctx;
609 	intel_ctx->surface_bo_size
610 		= SIZE_YUV420(context->width, context->height);
611 
612 	if (alloc_object(&media_state))
613 		return BadAlloc;
614 
615 	if (setup_media_kernels(hw_ctx))
616 		return BadAlloc;
617 	return Success;
618 }
619 
destroy_context(Display * display,XvMCContext * context)620 static Status destroy_context(Display * display, XvMCContext * context)
621 {
622 	struct intel_xvmc_context *intel_ctx;
623 	intel_ctx = context->privData;
624 	free(intel_ctx->hw);
625 	free(intel_ctx);
626 	return Success;
627 }
628 
load_qmatrix(Display * display,XvMCContext * context,const XvMCQMatrix * qmx)629 static Status load_qmatrix(Display * display, XvMCContext * context,
630 			   const XvMCQMatrix * qmx)
631 {
632 	Status ret;
633 	ret = cs_init(0);
634 	if (ret != Success)
635 		return ret;
636 	drm_intel_bo_subdata(media_state.cs_object.bo, 0, 64,
637 			     qmx->intra_quantiser_matrix);
638 	drm_intel_bo_subdata(media_state.cs_object.bo, 64, 64,
639 			     qmx->non_intra_quantiser_matrix);
640 
641 	return Success;
642 }
643 
vld_state(const XvMCMpegControl * control)644 static Status vld_state(const XvMCMpegControl * control)
645 {
646 	struct brw_vld_state tmp, *vld = &tmp;
647 
648 	if (media_state.vld_state.bo)
649 		drm_intel_bo_unreference(media_state.vld_state.bo);
650 	media_state.vld_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
651 						      "vld state",
652 						      sizeof(struct
653 							     brw_vld_state),
654 						      64);
655 	if (!media_state.vld_state.bo)
656 		return BadAlloc;
657 
658 	memset(vld, 0, sizeof(*vld));
659 	vld->vld0.f_code_0_0 = control->FHMV_range + 1;
660 	vld->vld0.f_code_0_1 = control->FVMV_range + 1;
661 	vld->vld0.f_code_1_0 = control->BHMV_range + 1;
662 	vld->vld0.f_code_1_1 = control->BVMV_range + 1;
663 	vld->vld0.intra_dc_precision = control->intra_dc_precision;
664 	vld->vld0.picture_structure = control->picture_structure;
665 	vld->vld0.top_field_first = !!(control->flags & XVMC_TOP_FIELD_FIRST);
666 	vld->vld0.frame_predict_frame_dct =
667 	    !!(control->flags & XVMC_PRED_DCT_FRAME);
668 	vld->vld0.concealment_motion_vector =
669 	    !!(control->flags & XVMC_CONCEALMENT_MOTION_VECTORS);
670 	vld->vld0.quantizer_scale_type = !!(control->flags & XVMC_Q_SCALE_TYPE);
671 	vld->vld0.intra_vlc_format = !!(control->flags & XVMC_INTRA_VLC_FORMAT);
672 	vld->vld0.scan_order = !!(control->flags & XVMC_ALTERNATE_SCAN);
673 
674 	vld->vld1.picture_coding_type = control->picture_coding_type;
675 
676 	vld->desc_remap_table0.index_0 = FRAME_INTRA;
677 	vld->desc_remap_table0.index_1 = FRAME_FRAME_PRED_FORWARD;
678 	vld->desc_remap_table0.index_2 = FRAME_FIELD_PRED_FORWARD;
679 	vld->desc_remap_table0.index_3 = FRAME_FIELD_PRED_BIDIRECT;	/* dual prime */
680 	vld->desc_remap_table0.index_4 = FRAME_FRAME_PRED_BACKWARD;
681 	vld->desc_remap_table0.index_5 = FRAME_FIELD_PRED_BACKWARD;
682 	vld->desc_remap_table0.index_6 = FRAME_FRAME_PRED_BIDIRECT;
683 	vld->desc_remap_table0.index_7 = FRAME_FIELD_PRED_BIDIRECT;
684 
685 	vld->desc_remap_table1.index_8 = FRAME_INTRA;
686 	vld->desc_remap_table1.index_9 = FRAME_FRAME_PRED_FORWARD;
687 	vld->desc_remap_table1.index_10 = FRAME_FIELD_PRED_FORWARD;
688 	vld->desc_remap_table1.index_11 = FRAME_FIELD_PRED_BIDIRECT;
689 	vld->desc_remap_table1.index_12 = FRAME_FRAME_PRED_BACKWARD;
690 	vld->desc_remap_table1.index_13 = FRAME_FIELD_PRED_BACKWARD;
691 	vld->desc_remap_table1.index_14 = FRAME_FRAME_PRED_BIDIRECT;
692 	vld->desc_remap_table1.index_15 = FRAME_FIELD_PRED_BIDIRECT;
693 
694 	drm_intel_bo_subdata(media_state.vld_state.bo, 0, sizeof(tmp), vld);
695 	return Success;
696 }
697 
setup_media_surface(int index,dri_bo * bo,unsigned long offset,int w,int h,Bool write)698 static Status setup_media_surface(int index, dri_bo * bo,
699 				  unsigned long offset, int w, int h,
700 				  Bool write)
701 {
702 	struct brw_surface_state tmp, *ss = &tmp;
703 	memset(ss, 0, sizeof(*ss));
704 	ss->ss0.surface_type = BRW_SURFACE_2D;
705 	ss->ss0.surface_format = BRW_SURFACEFORMAT_R8_SINT;
706 	ss->ss1.base_addr = offset + bo->offset;
707 	ss->ss2.width = w - 1;
708 	ss->ss2.height = h - 1;
709 	ss->ss3.pitch = w - 1;
710 
711 	if (media_state.binding_table.surface_states[index].bo)
712 		drm_intel_bo_unreference(media_state.
713 					 binding_table.surface_states[index].
714 					 bo);
715 
716 	media_state.binding_table.surface_states[index].bo =
717 	    drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state",
718 			       sizeof(struct brw_surface_state), 0x1000);
719 	if (!media_state.binding_table.surface_states[index].bo)
720 		return BadAlloc;
721 
722 	drm_intel_bo_subdata(media_state.binding_table.surface_states[index].bo,
723 			     0, sizeof(*ss), ss);
724 	drm_intel_bo_emit_reloc(media_state.binding_table.
725 				surface_states[index].bo,
726 				offsetof(struct brw_surface_state, ss1), bo,
727 				offset, I915_GEM_DOMAIN_RENDER,
728 				write ? I915_GEM_DOMAIN_RENDER : 0);
729 	return Success;
730 }
731 
setup_surface(struct intel_xvmc_surface * target,struct intel_xvmc_surface * past,struct intel_xvmc_surface * future,int w,int h)732 static Status setup_surface(struct intel_xvmc_surface *target,
733 			    struct intel_xvmc_surface *past,
734 			    struct intel_xvmc_surface *future, int w, int h)
735 {
736 	Status ret;
737 	ret = setup_media_surface(0, target->bo, 0, w, h, TRUE);
738 	if (ret != Success)
739 		return ret;
740 	ret = setup_media_surface(1, target->bo, w * h, w / 2, h / 2, TRUE);
741 	if (ret != Success)
742 		return ret;
743 	ret =
744 	    setup_media_surface(2, target->bo, w * h + w * h / 4, w / 2, h / 2,
745 				TRUE);
746 	if (ret != Success)
747 		return ret;
748 	if (past) {
749 		ret = setup_media_surface(4, past->bo, 0, w, h, FALSE);
750 		if (ret != Success)
751 			return ret;
752 		ret =
753 		    setup_media_surface(5, past->bo, w * h, w / 2, h / 2,
754 					FALSE);
755 		if (ret != Success)
756 			return ret;
757 		ret =
758 		    setup_media_surface(6, past->bo, w * h + w * h / 4, w / 2,
759 					h / 2, FALSE);
760 		if (ret != Success)
761 			return ret;
762 	}
763 	if (future) {
764 		ret = setup_media_surface(7, future->bo, 0, w, h, FALSE);
765 		if (ret != Success)
766 			return ret;
767 		ret =
768 		    setup_media_surface(8, future->bo, w * h, w / 2, h / 2,
769 					FALSE);
770 		if (ret != Success)
771 			return ret;
772 		ret =
773 		    setup_media_surface(9, future->bo, w * h + w * h / 4, w / 2,
774 					h / 2, FALSE);
775 		if (ret != Success)
776 			return ret;
777 	}
778 	return Success;
779 }
780 
begin_surface(Display * display,XvMCContext * context,XvMCSurface * target,XvMCSurface * past,XvMCSurface * future,const XvMCMpegControl * control)781 static Status begin_surface(Display * display, XvMCContext * context,
782 			    XvMCSurface * target,
783 			    XvMCSurface * past,
784 			    XvMCSurface * future,
785 			    const XvMCMpegControl * control)
786 {
787 	struct intel_xvmc_surface *priv_target, *priv_past, *priv_future;
788 	intel_xvmc_context_ptr intel_ctx = context->privData;
789 	Status ret;
790 
791 	priv_target = target->privData;
792 	priv_past = past ? past->privData : NULL;
793 	priv_future = future ? future->privData : NULL;
794 
795 	ret = vld_state(control);
796 	if (ret != Success)
797 		return ret;
798 	ret = setup_surface(priv_target, priv_past, priv_future,
799 			    context->width, context->height);
800 	if (ret != Success)
801 		return ret;
802 	ret = binding_tables();
803 	if (ret != Success)
804 		return ret;
805 	ret = interface_descriptor();
806 	if (ret != Success)
807 		return ret;
808 	ret = vfe_state(VFE_VLD_MODE);
809 	if (ret != Success)
810 		return ret;
811 
812 	LOCK_HARDWARE(intel_ctx->hw_context);
813 	flush();
814 	UNLOCK_HARDWARE(intel_ctx->hw_context);
815 	return Success;
816 }
817 
put_slice(Display * display,XvMCContext * context,unsigned char * slice,int nbytes)818 static Status put_slice(Display * display, XvMCContext * context,
819 			unsigned char *slice, int nbytes)
820 {
821 	return Success;
822 }
823 
state_base_address(struct intel_xvmc_hw_context * ctx)824 static void state_base_address(struct intel_xvmc_hw_context *ctx)
825 {
826 	BATCH_LOCALS;
827 
828 	if (ctx->i965.is_igdng) {
829 		BEGIN_BATCH(8);
830 		OUT_BATCH(BRW_STATE_BASE_ADDRESS | 6);
831 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
832 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
833 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
834 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
835 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
836 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
837 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
838 		ADVANCE_BATCH();
839 	} else {
840 		BEGIN_BATCH(6);
841 		OUT_BATCH(BRW_STATE_BASE_ADDRESS | 4);
842 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
843 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
844 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
845 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
846 		OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
847 		ADVANCE_BATCH();
848 	}
849 }
850 
pipeline_select()851 static void pipeline_select()
852 {
853 	BATCH_LOCALS;
854 	BEGIN_BATCH(1);
855 	OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
856 	ADVANCE_BATCH();
857 }
858 
media_state_pointers(int vfe_mode)859 static void media_state_pointers(int vfe_mode)
860 {
861 	BATCH_LOCALS;
862 	BEGIN_BATCH(3);
863 	OUT_BATCH(BRW_MEDIA_STATE_POINTERS | 1);
864 	if (vfe_mode == VFE_VLD_MODE)
865 		OUT_RELOC(media_state.vld_state.bo, I915_GEM_DOMAIN_INSTRUCTION,
866 			  0, 1);
867 	else
868 		OUT_BATCH(0);
869 	OUT_RELOC(media_state.vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
870 	ADVANCE_BATCH();
871 }
872 
align_urb_fence()873 static void align_urb_fence()
874 {
875 	BATCH_LOCALS;
876 	int i, offset_to_next_cacheline;
877 	unsigned long batch_offset;
878 	BEGIN_BATCH(3);
879 	batch_offset = (void *)batch_ptr - xvmc_driver->alloc.ptr;
880 	offset_to_next_cacheline = ALIGN(batch_offset, 64) - batch_offset;
881 	if (offset_to_next_cacheline <= 12 && offset_to_next_cacheline != 0) {
882 		for (i = 0; i < offset_to_next_cacheline / 4; i++)
883 			OUT_BATCH(0);
884 		ADVANCE_BATCH();
885 	}
886 }
887 
urb_layout()888 static void urb_layout()
889 {
890 	BATCH_LOCALS;
891 	align_urb_fence();
892 	BEGIN_BATCH(3);
893 	OUT_BATCH(BRW_URB_FENCE |
894 		  UF0_VFE_REALLOC |
895 		  UF0_CS_REALLOC |
896 		  UF0_SF_REALLOC |
897 		  UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1);
898 
899 	OUT_BATCH((0 << UF1_CLIP_FENCE_SHIFT) |
900 		  (0 << UF1_GS_FENCE_SHIFT) | (0 << UF1_VS_FENCE_SHIFT));
901 
902 	OUT_BATCH((0 << UF2_CS_FENCE_SHIFT) | (0 << UF2_SF_FENCE_SHIFT) | ((URB_SIZE - CS_SIZE - 1) << UF2_VFE_FENCE_SHIFT) |	/* VFE_SIZE */
903 		  ((URB_SIZE) << UF2_CS_FENCE_SHIFT));	/* CS_SIZE */
904 	ADVANCE_BATCH();
905 }
906 
cs_urb_layout()907 static void cs_urb_layout()
908 {
909 	BATCH_LOCALS;
910 	BEGIN_BATCH(2);
911 	OUT_BATCH(BRW_CS_URB_STATE | 0);
912 	OUT_BATCH((CS_SIZE << 4) |	/* URB Entry Allocation Size */
913 		  (1 << 0));	/* Number of URB Entries */
914 	ADVANCE_BATCH();
915 }
916 
cs_buffer()917 static void cs_buffer()
918 {
919 	BATCH_LOCALS;
920 	BEGIN_BATCH(2);
921 	OUT_BATCH(BRW_CONSTANT_BUFFER | 0 | (1 << 8));
922 	OUT_RELOC(media_state.cs_object.bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
923 		  CS_SIZE);
924 	ADVANCE_BATCH();
925 }
926 
927 /* kick media object to gpu in idct mode*/
send_media_object(XvMCMacroBlock * mb,dri_bo * bo,uint32_t offset,enum interface interface)928 static void send_media_object(XvMCMacroBlock * mb, dri_bo * bo,
929 			      uint32_t offset, enum interface interface)
930 {
931 	BATCH_LOCALS;
932 	BEGIN_BATCH(13);
933 	OUT_BATCH(BRW_MEDIA_OBJECT | 11);
934 	OUT_BATCH(interface);
935 	OUT_BATCH(6 * 128);
936 	OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offset);
937 
938 	OUT_BATCH(mb->x << 4);
939 	OUT_BATCH(mb->y << 4);
940 	OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offset);
941 	OUT_BATCH_SHORT(mb->coded_block_pattern);
942 	OUT_BATCH_SHORT(mb->PMV[0][0][0]);
943 	OUT_BATCH_SHORT(mb->PMV[0][0][1]);
944 	OUT_BATCH_SHORT(mb->PMV[0][1][0]);
945 	OUT_BATCH_SHORT(mb->PMV[0][1][1]);
946 
947 	OUT_BATCH_SHORT(mb->PMV[1][0][0]);
948 	OUT_BATCH_SHORT(mb->PMV[1][0][1]);
949 	OUT_BATCH_SHORT(mb->PMV[1][1][0]);
950 	OUT_BATCH_SHORT(mb->PMV[1][1][1]);
951 	OUT_BATCH_CHAR(mb->dct_type);
952 	OUT_BATCH_CHAR(mb->motion_vertical_field_select);
953 
954 	OUT_BATCH(0xffffffff);
955 	ADVANCE_BATCH();
956 }
957 
958 /* kick media object to gpu in vld mode*/
vld_send_media_object(dri_bo * bo,int slice_len,int mb_h_pos,int mb_v_pos,int mb_bit_offset,int mb_count,int q_scale_code)959 static void vld_send_media_object(dri_bo * bo,
960 				  int slice_len, int mb_h_pos, int mb_v_pos,
961 				  int mb_bit_offset, int mb_count,
962 				  int q_scale_code)
963 {
964 	BATCH_LOCALS;
965 	BEGIN_BATCH(6);
966 	OUT_BATCH(BRW_MEDIA_OBJECT | 4);
967 	OUT_BATCH(0);
968 	OUT_BATCH(slice_len);
969 	OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
970 	OUT_BATCH((mb_h_pos << 24) | (mb_v_pos << 16) | (mb_count << 8) |
971 		  (mb_bit_offset));
972 	OUT_BATCH(q_scale_code << 24);
973 	ADVANCE_BATCH();
974 }
975 
put_slice2(Display * display,XvMCContext * context,unsigned char * slice,int nbytes,int sliceCode)976 static Status put_slice2(Display * display, XvMCContext * context,
977 			 unsigned char *slice, int nbytes, int sliceCode)
978 {
979 	unsigned int bit_buf;
980 	intel_xvmc_context_ptr intel_ctx = context->privData;
981 	struct intel_xvmc_hw_context *hw_ctx = intel_ctx->hw;
982 	int q_scale_code, mb_row;
983 
984 	mb_row = *(slice - 1) - 1;
985 	bit_buf =
986 	    (slice[0] << 24) | (slice[1] << 16) | (slice[2] << 8) | (slice[3]);
987 
988 	q_scale_code = bit_buf >> 27;
989 
990 	if (media_state.slice_data.bo) {
991 		drm_intel_gem_bo_unmap_gtt(media_state.slice_data.bo);
992 
993 		drm_intel_bo_unreference(media_state.slice_data.bo);
994 	}
995 	media_state.slice_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
996 						       "slice data",
997 						       VLD_MAX_SLICE_SIZE, 64);
998 	if (!media_state.slice_data.bo)
999 		return BadAlloc;
1000 	drm_intel_gem_bo_map_gtt(media_state.slice_data.bo);
1001 
1002 	memcpy(media_state.slice_data.bo->virtual, slice, nbytes);
1003 
1004 	LOCK_HARDWARE(intel_ctx->hw_context);
1005 	state_base_address(hw_ctx);
1006 	pipeline_select();
1007 	media_state_pointers(VFE_VLD_MODE);
1008 	urb_layout();
1009 	cs_urb_layout();
1010 	cs_buffer();
1011 	vld_send_media_object(media_state.slice_data.bo,
1012 			      nbytes, 0, mb_row, 6, 127, q_scale_code);
1013 	intelFlushBatch();
1014 	UNLOCK_HARDWARE(intel_ctx->hw_context);
1015 
1016 	return Success;
1017 }
1018 
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)1019 static Status render_surface(Display * display,
1020 			     XvMCContext * context,
1021 			     unsigned int picture_structure,
1022 			     XvMCSurface * target_surface,
1023 			     XvMCSurface * past_surface,
1024 			     XvMCSurface * future_surface,
1025 			     unsigned int flags,
1026 			     unsigned int num_macroblocks,
1027 			     unsigned int first_macroblock,
1028 			     XvMCMacroBlockArray * macroblock_array,
1029 			     XvMCBlockArray * blocks)
1030 {
1031 	struct intel_xvmc_surface *priv_target, *priv_past, *priv_future;
1032 	intel_xvmc_context_ptr intel_ctx;
1033 	XvMCMacroBlock *mb;
1034 	Status ret;
1035 	unsigned short *block_ptr;
1036 	int i, j;
1037 	int block_offset = 0;
1038 	struct intel_xvmc_hw_context *hw_ctx;
1039 
1040 	intel_ctx = context->privData;
1041 
1042 	hw_ctx = (struct intel_xvmc_hw_context *)context->privData;
1043 	priv_target = target_surface->privData;
1044 	priv_past = past_surface ? past_surface->privData : NULL;
1045 	priv_future = future_surface ? future_surface->privData : NULL;
1046 
1047 	ret = setup_surface(priv_target, priv_past, priv_future,
1048 			    context->width, context->height);
1049 	if (ret != Success)
1050 		return ret;
1051 	ret = binding_tables();
1052 	if (ret != Success)
1053 		return ret;
1054 	ret = interface_descriptor();
1055 	if (ret != Success)
1056 		return ret;
1057 	ret = cs_init(INTERFACE_NUM);
1058 	if (ret != Success)
1059 		return ret;
1060 	ret = vfe_state(VFE_GENERIC_MODE);
1061 	if (ret != Success)
1062 		return ret;
1063 
1064 	if (media_state.mb_data.bo) {
1065 		drm_intel_gem_bo_unmap_gtt(media_state.mb_data.bo);
1066 
1067 		drm_intel_bo_unreference(media_state.mb_data.bo);
1068 	}
1069 	unsigned int block_num =
1070 	    (((context->width + 15) >> 4) * ((context->height + 15) >> 4));
1071 	unsigned int surface_size = (64 * sizeof(short) * 6 * block_num);
1072 	media_state.mb_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
1073 						    "macroblock data",
1074 						    surface_size, 64);
1075 	if (!media_state.mb_data.bo)
1076 		return BadAlloc;
1077 	drm_intel_gem_bo_map_gtt(media_state.mb_data.bo);
1078 
1079 	block_ptr = media_state.mb_data.bo->virtual;
1080 	unsigned short *mb_block_ptr;
1081 	for (i = first_macroblock; i < num_macroblocks + first_macroblock; i++) {
1082 		mb = &macroblock_array->macro_blocks[i];
1083 		mb_block_ptr = &blocks->blocks[(mb->index << 6)];
1084 
1085 		if (mb->coded_block_pattern & 0x20) {
1086 			for (j = 0; j < 8; j++)
1087 				memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j,
1088 				       16);
1089 			mb_block_ptr += 64;
1090 		}
1091 		if (mb->coded_block_pattern & 0x10) {
1092 			for (j = 0; j < 8; j++)
1093 				memcpy(block_ptr + 16 * j + 8,
1094 				       mb_block_ptr + 8 * j, 16);
1095 			mb_block_ptr += 64;
1096 		}
1097 
1098 		block_ptr += 2 * 64;
1099 		if (mb->coded_block_pattern & 0x08) {
1100 			for (j = 0; j < 8; j++)
1101 				memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j,
1102 				       16);
1103 			mb_block_ptr += 64;
1104 		}
1105 		if (mb->coded_block_pattern & 0x04) {
1106 			for (j = 0; j < 8; j++)
1107 				memcpy(block_ptr + 16 * j + 8,
1108 				       mb_block_ptr + 8 * j, 16);
1109 			mb_block_ptr += 64;
1110 		}
1111 
1112 		block_ptr += 2 * 64;
1113 		if (mb->coded_block_pattern & 0x2) {
1114 			memcpy(block_ptr, mb_block_ptr, 128);
1115 			mb_block_ptr += 64;
1116 		}
1117 
1118 		block_ptr += 64;
1119 		if (mb->coded_block_pattern & 0x1)
1120 			memcpy(block_ptr, mb_block_ptr, 128);
1121 		block_ptr += 64;
1122 	}
1123 
1124 	LOCK_HARDWARE(intel_ctx->hw_context);
1125 	state_base_address(hw_ctx);
1126 	flush();
1127 	pipeline_select();
1128 	urb_layout();
1129 	media_state_pointers(VFE_GENERIC_MODE);
1130 	cs_urb_layout();
1131 	cs_buffer();
1132 	for (i = first_macroblock;
1133 	     i < num_macroblocks + first_macroblock;
1134 	     i++, block_offset += 128 * 6) {
1135 		mb = &macroblock_array->macro_blocks[i];
1136 
1137 		if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
1138 			send_media_object(mb, media_state.mb_data.bo,
1139 					  block_offset,
1140 					  FRAME_INTRA + INTERFACE_NUM);
1141 		} else {
1142 			if (((mb->motion_type & 3) == XVMC_PREDICTION_FRAME)) {
1143 				if ((mb->macroblock_type &
1144 				     XVMC_MB_TYPE_MOTION_FORWARD)) {
1145 					if ((mb->macroblock_type &
1146 					     XVMC_MB_TYPE_MOTION_BACKWARD)) {
1147 						send_media_object(mb,
1148 								  media_state.mb_data.
1149 								  bo,
1150 								  block_offset,
1151 								  FRAME_FRAME_PRED_BIDIRECT
1152 								  +
1153 								  INTERFACE_NUM);
1154 					} else {
1155 						send_media_object(mb,
1156 								  media_state.mb_data.
1157 								  bo,
1158 								  block_offset,
1159 								  FRAME_FRAME_PRED_FORWARD
1160 								  +
1161 								  INTERFACE_NUM);
1162 					}
1163 				} else
1164 				    if ((mb->macroblock_type &
1165 					 XVMC_MB_TYPE_MOTION_BACKWARD)) {
1166 					send_media_object(mb,
1167 							  media_state.
1168 							  mb_data.bo,
1169 							  block_offset,
1170 							  FRAME_FRAME_PRED_BACKWARD
1171 							  + INTERFACE_NUM);
1172 				}
1173 			} else if ((mb->motion_type & 3) ==
1174 				   XVMC_PREDICTION_FIELD) {
1175 				if ((mb->macroblock_type &
1176 				     XVMC_MB_TYPE_MOTION_FORWARD)) {
1177 					if (((mb->macroblock_type &
1178 					      XVMC_MB_TYPE_MOTION_BACKWARD))) {
1179 						send_media_object(mb,
1180 								  media_state.mb_data.
1181 								  bo,
1182 								  block_offset,
1183 								  FRAME_FIELD_PRED_BIDIRECT
1184 								  +
1185 								  INTERFACE_NUM);
1186 					} else {
1187 						send_media_object(mb,
1188 								  media_state.mb_data.
1189 								  bo,
1190 								  block_offset,
1191 								  FRAME_FIELD_PRED_FORWARD
1192 								  +
1193 								  INTERFACE_NUM);
1194 					}
1195 				} else
1196 				    if ((mb->macroblock_type &
1197 					 XVMC_MB_TYPE_MOTION_BACKWARD)) {
1198 					send_media_object(mb,
1199 							  media_state.
1200 							  mb_data.bo,
1201 							  block_offset,
1202 							  FRAME_FIELD_PRED_BACKWARD
1203 							  + INTERFACE_NUM);
1204 				}
1205 			} else {
1206 				send_media_object(mb, media_state.mb_data.bo, block_offset, FRAME_FIELD_PRED_BIDIRECT + INTERFACE_NUM);	/*dual prime */
1207 			}
1208 		}
1209 	}
1210 	intelFlushBatch();
1211 	UNLOCK_HARDWARE(intel_ctx->hw_context);
1212 	return Success;
1213 }
1214 
1215 struct _intel_xvmc_driver xvmc_vld_driver = {
1216 	.type = XVMC_I965_MPEG2_VLD,
1217 	.create_context = create_context,
1218 	.destroy_context = destroy_context,
1219 	.load_qmatrix = load_qmatrix,
1220 	.begin_surface = begin_surface,
1221 	.render_surface = render_surface,
1222 	.put_slice = put_slice,
1223 	.put_slice2 = put_slice2
1224 };
1225