summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Zanussi <tom.zanussi@intel.com>2012-12-20 02:29:38 (GMT)
committerTom Zanussi <tom.zanussi@linux.intel.com>2013-02-12 16:10:19 (GMT)
commit0d850c9068a11f2d0907e3987de69c645ff8906a (patch)
tree04d5f24eaa1094063d9d0afbbd36ff2d0f153610
parent0ace9c0e268886727182e1f6bb368cfab2b0552e (diff)
downloadmeta-intel-0d850c9068a11f2d0907e3987de69c645ff8906a.tar.gz
libva-intel-driver: workaround for concurrent VC1 and H264 playback issue
Explanation from Terence Chiang: "encountered a GFX issue while enabling HW video playback VC-1 and H.264 simultaneously, the graphic driver report error with gfx hang on Sandy Bridge platform. We worked with Intel Linux graphic team and provided a patch" Signed-off-by: Tom Zanussi <tom.zanussi@intel.com>
-rw-r--r--common/recipes-multimedia/libva/libva-intel-driver-1.0.18/0001-Workaround-for-concurrently-playing-VC1-and-H264-vid.patch440
-rw-r--r--common/recipes-multimedia/libva/libva-intel-driver_1.0.18.bb2
2 files changed, 442 insertions, 0 deletions
diff --git a/common/recipes-multimedia/libva/libva-intel-driver-1.0.18/0001-Workaround-for-concurrently-playing-VC1-and-H264-vid.patch b/common/recipes-multimedia/libva/libva-intel-driver-1.0.18/0001-Workaround-for-concurrently-playing-VC1-and-H264-vid.patch
new file mode 100644
index 0000000..e000632
--- /dev/null
+++ b/common/recipes-multimedia/libva/libva-intel-driver-1.0.18/0001-Workaround-for-concurrently-playing-VC1-and-H264-vid.patch
@@ -0,0 +1,440 @@
1Upstream-Status: Pending
2
3From 43c3fd3ea485a0b9ad12c248a0a94a959ab4d5ee Mon Sep 17 00:00:00 2001
4From: "Xiang, Haihao" <haihao.xiang@intel.com>
5Date: Mon, 29 Oct 2012 10:01:16 +0800
6Subject: [PATCH] Workaround for concurrently playing VC1 and H264 video on SNB
7
8Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
9---
10 src/gen6_mfd.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
11 src/gen6_mfd.h | 3 +
12 2 files changed, 380 insertions(+), 2 deletions(-)
13
14diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c
15index fa2f128..b8c671b 100755
16--- a/src/gen6_mfd.c
17+++ b/src/gen6_mfd.c
18@@ -50,6 +50,377 @@ static const uint32_t zigzag_direct[64] = {
19 53, 60, 61, 54, 47, 55, 62, 63
20 };
21
22+/* Workaround for VC1 decoding */
23+
24+VAStatus
25+i965_DestroySurfaces(VADriverContextP ctx,
26+ VASurfaceID *surface_list,
27+ int num_surfaces);
28+VAStatus
29+i965_CreateSurfaces(VADriverContextP ctx,
30+ int width,
31+ int height,
32+ int format,
33+ int num_surfaces,
34+ VASurfaceID *surfaces);
35+
36+static struct {
37+ int width;
38+ int height;
39+ int mb_count;
40+ unsigned char data[32];
41+ int data_size;
42+ int data_bit_offset;
43+
44+ unsigned int f_code:16;
45+ unsigned int intra_dc_precision:2;
46+ unsigned int picture_structure:2;
47+ unsigned int top_field_first:1;
48+ unsigned int frame_pred_frame_dct:1;
49+ unsigned int concealment_motion_vectors:1;
50+ unsigned int q_scale_type:1;
51+ unsigned int intra_vlc_format:1;
52+ unsigned int alternate_scan:1;
53+ unsigned int picture_coding_type:1;
54+ unsigned int pad0: 5;
55+
56+ unsigned int quantiser_scale_code;
57+
58+ unsigned char qm[2][64];
59+} gen6_dwa_clip = {
60+ width: 32,
61+ height: 16,
62+ mb_count: 2,
63+ data: {
64+ 0x00, 0x00, 0x01, 0x01, 0x1b, 0xfb, 0xfd, 0xf8,
65+ 0x02, 0x97, 0xef, 0xf8, 0x8b, 0x97, 0xe0, 0x0a,
66+ 0x5f, 0xbf, 0xe2, 0x20, 0x00, 0x00, 0x01, 0x00
67+ },
68+ data_size: 20,
69+ data_bit_offset: 38,
70+
71+ f_code: 0xffff,
72+ intra_dc_precision: 0,
73+ picture_structure: 3,
74+ top_field_first: 0,
75+ frame_pred_frame_dct: 1,
76+ concealment_motion_vectors: 0,
77+ q_scale_type: 0,
78+ intra_vlc_format: 0,
79+ alternate_scan: 0,
80+ picture_coding_type: 1, /* I frame */
81+
82+ quantiser_scale_code: 3,
83+
84+ qm: {
85+ {
86+ 8, 16, 19, 22, 26, 27, 29, 34,
87+ 16, 16, 22, 24, 27, 29, 34, 37,
88+ 19, 22, 26, 27, 29, 34, 34, 38,
89+ 22, 22, 26, 27, 29, 34, 37, 40,
90+ 22, 26, 27, 29, 32, 35, 40, 48,
91+ 26, 27, 29, 32, 35, 40, 48, 58,
92+ 26, 27, 29, 34, 38, 46, 56, 69,
93+ 27, 29, 35, 38, 46, 56, 69, 83
94+ },
95+
96+ {
97+ 16, 16, 16, 16, 16, 16, 16, 16,
98+ 16, 16, 16, 16, 16, 16, 16, 16,
99+ 16, 16, 16, 16, 16, 16, 16, 16,
100+ 16, 16, 16, 16, 16, 16, 16, 16,
101+ 16, 16, 16, 16, 16, 16, 16, 16,
102+ 16, 16, 16, 16, 16, 16, 16, 16,
103+ 16, 16, 16, 16, 16, 16, 16, 16,
104+ 16, 16, 16, 16, 16, 16, 16, 16,
105+ }
106+ },
107+};
108+
109+static void
110+gen6_dwa_init(VADriverContextP ctx,
111+ struct gen6_mfd_context *gen6_mfd_context)
112+{
113+ struct i965_driver_data *i965 = i965_driver_data(ctx);
114+ VAStatus status;
115+ struct object_surface *obj_surface;
116+
117+ if (gen6_mfd_context->dwa_surface_id != VA_INVALID_SURFACE)
118+ i965_DestroySurfaces(ctx,
119+ &gen6_mfd_context->dwa_surface_id,
120+ 1);
121+
122+ status = i965_CreateSurfaces(ctx,
123+ gen6_dwa_clip.width,
124+ gen6_dwa_clip.height,
125+ VA_RT_FORMAT_YUV420,
126+ 1,
127+ &gen6_mfd_context->dwa_surface_id);
128+ assert(status == VA_STATUS_SUCCESS);
129+
130+ obj_surface = SURFACE(gen6_mfd_context->dwa_surface_id);
131+ assert(obj_surface);
132+ i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N', 'V', '1', '2'), SUBSAMPLE_YUV420);
133+
134+ if (!gen6_mfd_context->dwa_slice_data_bo)
135+ dri_bo_unreference(gen6_mfd_context->dwa_slice_data_bo);
136+
137+ gen6_mfd_context->dwa_slice_data_bo = dri_bo_alloc(i965->intel.bufmgr,
138+ "WA data",
139+ 0x1000,
140+ 0x1000);
141+ dri_bo_subdata(gen6_mfd_context->dwa_slice_data_bo,
142+ 0,
143+ gen6_dwa_clip.data_size,
144+ gen6_dwa_clip.data);
145+}
146+
147+static void
148+gen6_dwa_pipe_mode_select(VADriverContextP ctx,
149+ struct gen6_mfd_context *gen6_mfd_context)
150+{
151+ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
152+
153+ BEGIN_BCS_BATCH(batch, 4);
154+ OUT_BCS_BATCH(batch, MFX_PIPE_MODE_SELECT | (4 - 2));
155+ OUT_BCS_BATCH(batch,
156+ (MFD_MODE_VLD << 16) | /* VLD mode */
157+ (0 << 10) | /* disable Stream-Out */
158+ (0 << 9) | /* Post Deblocking Output */
159+ (1 << 8) | /* Pre Deblocking Output */
160+ (0 << 7) | /* disable TLB prefectch */
161+ (0 << 5) | /* not in stitch mode */
162+ (MFX_CODEC_DECODE << 4) | /* decoding mode */
163+ (MFX_FORMAT_MPEG2 << 0));
164+ OUT_BCS_BATCH(batch,
165+ (0 << 20) | /* round flag in PB slice */
166+ (0 << 19) | /* round flag in Intra8x8 */
167+ (0 << 7) | /* expand NOA bus flag */
168+ (1 << 6) | /* must be 1 */
169+ (0 << 5) | /* disable clock gating for NOA */
170+ (0 << 4) | /* terminate if AVC motion and POC table error occurs */
171+ (0 << 3) | /* terminate if AVC mbdata error occurs */
172+ (0 << 2) | /* terminate if AVC CABAC/CAVLC decode error occurs */
173+ (0 << 1) | /* AVC long field motion vector */
174+ (0 << 0)); /* always calculate AVC ILDB boundary strength */
175+ OUT_BCS_BATCH(batch, 0);
176+ ADVANCE_BCS_BATCH(batch);
177+}
178+
179+static void
180+gen6_dwa_surface_state(VADriverContextP ctx,
181+ struct gen6_mfd_context *gen6_mfd_context)
182+{
183+ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
184+ struct i965_driver_data *i965 = i965_driver_data(ctx);
185+ struct object_surface *obj_surface = SURFACE(gen6_mfd_context->dwa_surface_id);
186+
187+ BEGIN_BCS_BATCH(batch, 6);
188+ OUT_BCS_BATCH(batch, MFX_SURFACE_STATE | (6 - 2));
189+ OUT_BCS_BATCH(batch, 0);
190+ OUT_BCS_BATCH(batch,
191+ ((obj_surface->orig_width - 1) << 19) |
192+ ((obj_surface->orig_height - 1) << 6));
193+ OUT_BCS_BATCH(batch,
194+ (MFX_SURFACE_PLANAR_420_8 << 28) | /* 420 planar YUV surface */
195+ (1 << 27) | /* interleave chroma */
196+ (0 << 22) | /* surface object control state, ignored */
197+ ((obj_surface->width - 1) << 3) | /* pitch */
198+ (0 << 2) | /* must be 0 */
199+ (1 << 1) | /* must be tiled */
200+ (I965_TILEWALK_YMAJOR << 0)); /* tile walk, must be 1 */
201+ OUT_BCS_BATCH(batch,
202+ (0 << 16) | /* X offset for U(Cb), must be 0 */
203+ (obj_surface->y_cb_offset << 0)); /* Y offset for U(Cb) */
204+ OUT_BCS_BATCH(batch,
205+ (0 << 16) | /* X offset for V(Cr), must be 0 */
206+ (0 << 0)); /* Y offset for V(Cr), must be 0 for video codec */
207+ ADVANCE_BCS_BATCH(batch);
208+}
209+
210+static void
211+gen6_dwa_pipe_buf_addr_state(VADriverContextP ctx,
212+ struct gen6_mfd_context *gen6_mfd_context)
213+{
214+ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
215+ struct i965_driver_data *i965 = i965_driver_data(ctx);
216+ struct object_surface *obj_surface = SURFACE(gen6_mfd_context->dwa_surface_id);
217+ dri_bo *intra_bo;
218+ int i;
219+
220+ intra_bo = dri_bo_alloc(i965->intel.bufmgr,
221+ "intra row store",
222+ 128 * 64,
223+ 0x1000);
224+
225+ BEGIN_BCS_BATCH(batch, 24);
226+ OUT_BCS_BATCH(batch, MFX_PIPE_BUF_ADDR_STATE | (24 - 2));
227+ OUT_BCS_RELOC(batch,
228+ obj_surface->bo,
229+ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
230+ 0);
231+
232+ OUT_BCS_BATCH(batch, 0); /* post deblocking */
233+
234+ OUT_BCS_BATCH(batch, 0); /* ignore for decoding */
235+ OUT_BCS_BATCH(batch, 0); /* ignore for decoding */
236+
237+ OUT_BCS_RELOC(batch,
238+ intra_bo,
239+ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
240+ 0);
241+
242+ OUT_BCS_BATCH(batch, 0);
243+
244+ /* DW 7..22 */
245+ for (i = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
246+ OUT_BCS_BATCH(batch, 0);
247+ }
248+
249+ OUT_BCS_BATCH(batch, 0); /* ignore DW23 for decoding */
250+ ADVANCE_BCS_BATCH(batch);
251+
252+ dri_bo_unreference(intra_bo);
253+}
254+
255+static void
256+gen6_dwa_bsp_buf_base_addr_state(VADriverContextP ctx,
257+ struct gen6_mfd_context *gen6_mfd_context)
258+{
259+ struct i965_driver_data *i965 = i965_driver_data(ctx);
260+ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
261+ dri_bo *bsd_mpc_bo;
262+
263+ bsd_mpc_bo = dri_bo_alloc(i965->intel.bufmgr,
264+ "bsd mpc row store",
265+ 11520, /* 1.5 * 120 * 64 */
266+ 0x1000);
267+
268+ BEGIN_BCS_BATCH(batch, 4);
269+ OUT_BCS_BATCH(batch, MFX_BSP_BUF_BASE_ADDR_STATE | (4 - 2));
270+
271+ OUT_BCS_RELOC(batch,
272+ bsd_mpc_bo,
273+ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
274+ 0);
275+ OUT_BCS_BATCH(batch, 0);
276+ OUT_BCS_BATCH(batch, 0);
277+ ADVANCE_BCS_BATCH(batch);
278+
279+ dri_bo_unreference(bsd_mpc_bo);
280+}
281+
282+static void
283+gen6_dwa_mpeg2_pic_state(VADriverContextP ctx,
284+ struct gen6_mfd_context *gen6_mfd_context)
285+
286+{
287+ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
288+ unsigned int width_in_mbs = ALIGN(gen6_dwa_clip.width, 16) / 16;
289+ unsigned int height_in_mbs = ALIGN(gen6_dwa_clip.height, 16) / 16;
290+
291+ BEGIN_BCS_BATCH(batch, 4);
292+ OUT_BCS_BATCH(batch, MFX_MPEG2_PIC_STATE | (4 - 2));
293+ OUT_BCS_BATCH(batch,
294+ gen6_dwa_clip.f_code << 16 |
295+ gen6_dwa_clip.intra_dc_precision << 14 |
296+ gen6_dwa_clip.picture_structure << 12 |
297+ gen6_dwa_clip.top_field_first << 11 |
298+ gen6_dwa_clip.frame_pred_frame_dct << 10 |
299+ gen6_dwa_clip.concealment_motion_vectors << 9 |
300+ gen6_dwa_clip.q_scale_type << 8 |
301+ gen6_dwa_clip.intra_vlc_format << 7 |
302+ gen6_dwa_clip.alternate_scan << 6);
303+ OUT_BCS_BATCH(batch,
304+ gen6_dwa_clip.picture_coding_type << 9);
305+ OUT_BCS_BATCH(batch,
306+ height_in_mbs << 16 |
307+ width_in_mbs);
308+ ADVANCE_BCS_BATCH(batch);
309+}
310+
311+static void
312+gen6_dwa_mpeg2_qm_state(VADriverContextP ctx,
313+ struct gen6_mfd_context *gen6_mfd_context)
314+{
315+ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
316+ int i;
317+
318+ for (i = 0; i < 2; i++) {
319+ BEGIN_BCS_BATCH(batch, 18);
320+ OUT_BCS_BATCH(batch, MFX_MPEG2_QM_STATE | (18 - 2));
321+ OUT_BCS_BATCH(batch, i);
322+ intel_batchbuffer_data(batch, gen6_dwa_clip.qm[i], 64);
323+ ADVANCE_BCS_BATCH(batch);
324+ }
325+}
326+
327+static void
328+gen6_dwa_ind_obj_base_addr_state(VADriverContextP ctx,
329+ struct gen6_mfd_context *gen6_mfd_context)
330+{
331+ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
332+
333+ BEGIN_BCS_BATCH(batch, 11);
334+ OUT_BCS_BATCH(batch, MFX_IND_OBJ_BASE_ADDR_STATE | (11 - 2));
335+ OUT_BCS_RELOC(batch,
336+ gen6_mfd_context->dwa_slice_data_bo,
337+ I915_GEM_DOMAIN_INSTRUCTION, 0,
338+ 0);
339+ OUT_BCS_BATCH(batch, 0);
340+ OUT_BCS_BATCH(batch, 0); /* ignore for VLD mode */
341+ OUT_BCS_BATCH(batch, 0);
342+ OUT_BCS_BATCH(batch, 0); /* ignore for VLD mode */
343+ OUT_BCS_BATCH(batch, 0);
344+ OUT_BCS_BATCH(batch, 0); /* ignore for VLD mode */
345+ OUT_BCS_BATCH(batch, 0);
346+ OUT_BCS_BATCH(batch, 0); /* ignore for VLD mode */
347+ OUT_BCS_BATCH(batch, 0);
348+ ADVANCE_BCS_BATCH(batch);
349+}
350+
351+static void
352+gen6_dwa_mpeg2_bsd_object(VADriverContextP ctx,
353+ struct gen6_mfd_context *gen6_mfd_context)
354+{
355+ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
356+
357+ BEGIN_BCS_BATCH(batch, 5);
358+ OUT_BCS_BATCH(batch, MFD_MPEG2_BSD_OBJECT | (5 - 2));
359+ OUT_BCS_BATCH(batch,
360+ gen6_dwa_clip.data_size - (gen6_dwa_clip.data_bit_offset >> 3));
361+ OUT_BCS_BATCH(batch, gen6_dwa_clip.data_bit_offset >> 3);
362+ OUT_BCS_BATCH(batch,
363+ (0 << 24) |
364+ (0 << 16) |
365+ (gen6_dwa_clip.mb_count << 8) |
366+ (1 << 5) |
367+ (1 << 3) |
368+ (gen6_dwa_clip.data_bit_offset & 0x7));
369+ OUT_BCS_BATCH(batch,
370+ gen6_dwa_clip.quantiser_scale_code << 24);
371+ ADVANCE_BCS_BATCH(batch);
372+}
373+
374+static void
375+gen6_mfd_dwa(VADriverContextP ctx,
376+ struct gen6_mfd_context *gen6_mfd_context)
377+{
378+ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
379+ gen6_dwa_init(ctx, gen6_mfd_context);
380+ intel_batchbuffer_emit_mi_flush(batch);
381+ gen6_dwa_pipe_mode_select(ctx, gen6_mfd_context);
382+ gen6_dwa_surface_state(ctx, gen6_mfd_context);
383+ gen6_dwa_pipe_buf_addr_state(ctx, gen6_mfd_context);
384+ gen6_dwa_bsp_buf_base_addr_state(ctx, gen6_mfd_context);
385+ gen6_dwa_mpeg2_qm_state(ctx, gen6_mfd_context);
386+ gen6_dwa_mpeg2_pic_state(ctx, gen6_mfd_context);
387+ gen6_dwa_ind_obj_base_addr_state(ctx, gen6_mfd_context);
388+ gen6_dwa_mpeg2_bsd_object(ctx, gen6_mfd_context);
389+}
390+
391+/* end of workaround */
392+
393 static void
394 gen6_mfd_avc_frame_store_index(VADriverContextP ctx,
395 VAPictureParameterBufferH264 *pic_param,
396@@ -1055,7 +1426,8 @@ gen6_mfd_avc_decode_picture(VADriverContextP ctx,
397 }
398 }
399
400- gen6_mfd_avc_phantom_slice(ctx, pic_param, gen6_mfd_context);
401+ gen6_mfd_dwa(ctx, gen6_mfd_context);
402+
403 intel_batchbuffer_end_atomic(batch);
404 intel_batchbuffer_flush(batch);
405 }
406@@ -1944,6 +2316,8 @@ gen6_mfd_vc1_decode_picture(VADriverContextP ctx,
407 }
408 }
409
410+ gen6_mfd_dwa(ctx, gen6_mfd_context);
411+
412 intel_batchbuffer_end_atomic(batch);
413 intel_batchbuffer_flush(batch);
414 }
415@@ -2031,6 +2405,7 @@ gen6_dec_hw_context_init(VADriverContextP ctx, VAProfile profile)
416 }
417
418 gen6_mfd_context->wa_mpeg2_slice_vertical_position = -1;
419-
420+ gen6_mfd_context->dwa_surface_id = VA_INVALID_ID;
421+
422 return (struct hw_context *)gen6_mfd_context;
423 }
424diff --git a/src/gen6_mfd.h b/src/gen6_mfd.h
425index de131d6..7c4a619 100644
426--- a/src/gen6_mfd.h
427+++ b/src/gen6_mfd.h
428@@ -72,6 +72,9 @@ struct gen6_mfd_context
429 GenBuffer bitplane_read_buffer;
430
431 int wa_mpeg2_slice_vertical_position;
432+
433+ VASurfaceID dwa_surface_id;
434+ dri_bo *dwa_slice_data_bo;
435 };
436
437 #endif /* _GEN6_MFD_H_ */
438--
4391.7.9.5
440
diff --git a/common/recipes-multimedia/libva/libva-intel-driver_1.0.18.bb b/common/recipes-multimedia/libva/libva-intel-driver_1.0.18.bb
index fcd3b6f..d670b47 100644
--- a/common/recipes-multimedia/libva/libva-intel-driver_1.0.18.bb
+++ b/common/recipes-multimedia/libva/libva-intel-driver_1.0.18.bb
@@ -4,5 +4,7 @@ PR = "${INC_PR}.0"
4 4
5SRC_URI = "http://www.freedesktop.org/software/vaapi/releases/libva-intel-driver/libva-intel-driver-${PV}.tar.bz2" 5SRC_URI = "http://www.freedesktop.org/software/vaapi/releases/libva-intel-driver/libva-intel-driver-${PV}.tar.bz2"
6 6
7SRC_URI += "file://0001-Workaround-for-concurrently-playing-VC1-and-H264-vid.patch"
8
7SRC_URI[md5sum] = "13907085223d88d956cdfc282962b7a7" 9SRC_URI[md5sum] = "13907085223d88d956cdfc282962b7a7"
8SRC_URI[sha256sum] = "789fa2d6e22b9028ce12a89981eb33e57b04301431415149acfb61a49d3a63ee" 10SRC_URI[sha256sum] = "789fa2d6e22b9028ce12a89981eb33e57b04301431415149acfb61a49d3a63ee"