2 * Copyright © 2014 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * Xiang Haihao <haihao.xiang@intel.com>
32 #include <va/va_dec_hevc.h>
34 #include "intel_batchbuffer.h"
35 #include "intel_driver.h"
36 #include "i965_defines.h"
37 #include "i965_drv_video.h"
38 #include "i965_decoder_utils.h"
41 #include "intel_media.h"
43 #define OUT_BUFFER(buf_bo, is_target, ma) do { \
45 OUT_BCS_RELOC(batch, \
47 I915_GEM_DOMAIN_RENDER, \
48 is_target ? I915_GEM_DOMAIN_RENDER : 0, \
51 OUT_BCS_BATCH(batch, 0); \
53 OUT_BCS_BATCH(batch, 0); \
55 OUT_BCS_BATCH(batch, 0); \
58 #define OUT_BUFFER_MA_TARGET(buf_bo) OUT_BUFFER(buf_bo, 1, 1)
59 #define OUT_BUFFER_MA_REFERENCE(buf_bo) OUT_BUFFER(buf_bo, 0, 1)
60 #define OUT_BUFFER_NMA_TARGET(buf_bo) OUT_BUFFER(buf_bo, 1, 0)
61 #define OUT_BUFFER_NMA_REFERENCE(buf_bo) OUT_BUFFER(buf_bo, 0, 0)
64 gen9_hcpd_init_hevc_surface(VADriverContextP ctx,
65 VAPictureParameterBufferHEVC *pic_param,
66 struct object_surface *obj_surface,
67 struct gen9_hcpd_context *gen9_hcpd_context)
69 struct i965_driver_data *i965 = i965_driver_data(ctx);
70 GenHevcSurface *gen9_hevc_surface;
75 obj_surface->free_private_data = gen_free_hevc_surface;
76 gen9_hevc_surface = obj_surface->private_data;
78 if (!gen9_hevc_surface) {
79 gen9_hevc_surface = calloc(sizeof(GenHevcSurface), 1);
80 obj_surface->private_data = gen9_hevc_surface;
83 if (gen9_hevc_surface->motion_vector_temporal_bo == NULL) {
86 if (gen9_hcpd_context->ctb_size == 16)
87 size = ((gen9_hcpd_context->picture_width_in_pixels + 63) >> 6) *
88 ((gen9_hcpd_context->picture_height_in_pixels + 15) >> 4);
90 size = ((gen9_hcpd_context->picture_width_in_pixels + 31) >> 5) *
91 ((gen9_hcpd_context->picture_height_in_pixels + 31) >> 5);
93 size <<= 6; /* in unit of 64bytes */
94 gen9_hevc_surface->motion_vector_temporal_bo = dri_bo_alloc(i965->intel.bufmgr,
95 "motion vector temporal buffer",
102 gen9_hcpd_hevc_decode_init(VADriverContextP ctx,
103 struct decode_state *decode_state,
104 struct gen9_hcpd_context *gen9_hcpd_context)
106 struct i965_driver_data *i965 = i965_driver_data(ctx);
107 VAPictureParameterBufferHEVC *pic_param;
108 VASliceParameterBufferHEVC *slice_param;
109 struct object_surface *obj_surface;
111 int i, j, has_inter = 0;
113 for (j = 0; j < decode_state->num_slice_params && !has_inter; j++) {
114 assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
115 slice_param = (VASliceParameterBufferHEVC *)decode_state->slice_params[j]->buffer;
117 for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
118 if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_B ||
119 slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_P) {
128 assert(decode_state->pic_param && decode_state->pic_param->buffer);
129 pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
131 gen9_hcpd_context->picture_width_in_pixels = pic_param->pic_width_in_luma_samples;
132 gen9_hcpd_context->picture_height_in_pixels = pic_param->pic_height_in_luma_samples;
133 gen9_hcpd_context->ctb_size = (1 << (pic_param->log2_min_luma_coding_block_size_minus3 +
135 pic_param->log2_diff_max_min_luma_coding_block_size));
136 gen9_hcpd_context->picture_width_in_ctbs = ALIGN(gen9_hcpd_context->picture_width_in_pixels, gen9_hcpd_context->ctb_size) / gen9_hcpd_context->ctb_size;
137 gen9_hcpd_context->picture_height_in_ctbs = ALIGN(gen9_hcpd_context->picture_height_in_pixels, gen9_hcpd_context->ctb_size) / gen9_hcpd_context->ctb_size;
138 gen9_hcpd_context->min_cb_size = (1 << (pic_param->log2_min_luma_coding_block_size_minus3 + 3));
139 gen9_hcpd_context->picture_width_in_min_cb_minus1 = gen9_hcpd_context->picture_width_in_pixels / gen9_hcpd_context->min_cb_size - 1;
140 gen9_hcpd_context->picture_height_in_min_cb_minus1 = gen9_hcpd_context->picture_height_in_pixels / gen9_hcpd_context->min_cb_size - 1;
142 /* Current decoded picture */
143 obj_surface = decode_state->render_object;
144 gen9_hcpd_init_hevc_surface(ctx, pic_param, obj_surface, gen9_hcpd_context);
146 size = ALIGN(gen9_hcpd_context->picture_width_in_pixels, 32) >> 3;
148 ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_line_buffer), "line buffer", size);
149 ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_line_buffer), "tile line buffer", size);
151 size = ALIGN(gen9_hcpd_context->picture_height_in_pixels + 6 * gen9_hcpd_context->picture_height_in_ctbs, 32) >> 3;
153 ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_column_buffer), "tile column buffer", size);
156 size = (((gen9_hcpd_context->picture_width_in_pixels + 15) >> 4) * 188 + 9 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
158 ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer), "metadata line buffer", size);
160 size = (((gen9_hcpd_context->picture_width_in_pixels + 15) >> 4) * 172 + 9 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
162 ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer), "metadata tile line buffer", size);
164 size = (((gen9_hcpd_context->picture_height_in_pixels + 15) >> 4) * 176 + 89 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
166 ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer), "metadata tile column buffer", size);
168 size = (gen9_hcpd_context->picture_width_in_pixels + 8 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
170 ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer), "metadata line buffer", size);
172 size = (gen9_hcpd_context->picture_width_in_pixels + 16 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
174 ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer), "metadata tile line buffer", size);
176 size = (gen9_hcpd_context->picture_height_in_pixels + 8 * gen9_hcpd_context->picture_height_in_ctbs + 1023) >> 9;
178 ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer), "metadata tile column buffer", size);
181 size = ALIGN(((gen9_hcpd_context->picture_width_in_pixels >> 1) + 3 * gen9_hcpd_context->picture_width_in_ctbs), 16) >> 3;
183 ALLOC_GEN_BUFFER((&gen9_hcpd_context->sao_line_buffer), "sao line buffer", size);
185 size = ALIGN(((gen9_hcpd_context->picture_width_in_pixels >> 1) + 6 * gen9_hcpd_context->picture_width_in_ctbs), 16) >> 3;
187 ALLOC_GEN_BUFFER((&gen9_hcpd_context->sao_tile_line_buffer), "sao tile line buffer", size);
189 size = ALIGN(((gen9_hcpd_context->picture_height_in_pixels >> 1) + 6 * gen9_hcpd_context->picture_height_in_ctbs), 16) >> 3;
191 ALLOC_GEN_BUFFER((&gen9_hcpd_context->sao_tile_column_buffer), "sao tile column buffer", size);
193 return VA_STATUS_SUCCESS;
197 gen9_hcpd_pipe_mode_select(VADriverContextP ctx,
198 struct decode_state *decode_state,
200 struct gen9_hcpd_context *gen9_hcpd_context)
202 struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
204 assert(codec == HCP_CODEC_HEVC);
206 BEGIN_BCS_BATCH(batch, 4);
208 OUT_BCS_BATCH(batch, HCP_PIPE_MODE_SELECT | (4 - 2));
211 (0 << 3) | /* disable Pic Status / Error Report */
212 HCP_CODEC_SELECT_DECODE);
213 OUT_BCS_BATCH(batch, 0);
214 OUT_BCS_BATCH(batch, 0);
216 ADVANCE_BCS_BATCH(batch);
220 gen9_hcpd_surface_state(VADriverContextP ctx,
221 struct decode_state *decode_state,
222 struct gen9_hcpd_context *gen9_hcpd_context)
224 struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
225 struct object_surface *obj_surface = decode_state->render_object;
226 unsigned int y_cb_offset;
230 y_cb_offset = obj_surface->y_cb_offset;
232 BEGIN_BCS_BATCH(batch, 3);
234 OUT_BCS_BATCH(batch, HCP_SURFACE_STATE | (3 - 2));
236 (0 << 28) | /* surface id */
237 (obj_surface->width - 1)); /* pitch - 1 */
239 (SURFACE_FORMAT_PLANAR_420_8 << 28) |
242 ADVANCE_BCS_BATCH(batch);
246 gen9_hcpd_pipe_buf_addr_state(VADriverContextP ctx,
247 struct decode_state *decode_state,
248 struct gen9_hcpd_context *gen9_hcpd_context)
250 struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
251 struct object_surface *obj_surface;
252 GenHevcSurface *gen9_hevc_surface;
255 BEGIN_BCS_BATCH(batch, 95);
257 OUT_BCS_BATCH(batch, HCP_PIPE_BUF_ADDR_STATE | (95 - 2));
259 obj_surface = decode_state->render_object;
260 assert(obj_surface && obj_surface->bo);
261 gen9_hevc_surface = obj_surface->private_data;
262 assert(gen9_hevc_surface && gen9_hevc_surface->motion_vector_temporal_bo);
264 OUT_BUFFER_MA_TARGET(obj_surface->bo); /* DW 1..3 */
265 OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_line_buffer.bo);/* DW 4..6 */
266 OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_tile_line_buffer.bo); /* DW 7..9 */
267 OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_tile_column_buffer.bo); /* DW 10..12 */
268 OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_line_buffer.bo); /* DW 13..15 */
269 OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_tile_line_buffer.bo); /* DW 16..18 */
270 OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_tile_column_buffer.bo); /* DW 19..21 */
271 OUT_BUFFER_MA_TARGET(gen9_hcpd_context->sao_line_buffer.bo); /* DW 22..24 */
272 OUT_BUFFER_MA_TARGET(gen9_hcpd_context->sao_tile_line_buffer.bo); /* DW 25..27 */
273 OUT_BUFFER_MA_TARGET(gen9_hcpd_context->sao_tile_column_buffer.bo); /* DW 28..30 */
274 OUT_BUFFER_MA_TARGET(gen9_hevc_surface->motion_vector_temporal_bo); /* DW 31..33 */
275 OUT_BUFFER_MA_TARGET(NULL); /* DW 34..36, reserved */
277 for (i = 0; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++) {
278 obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface;
281 OUT_BUFFER_NMA_REFERENCE(obj_surface->bo);
283 OUT_BUFFER_NMA_REFERENCE(NULL);
285 OUT_BCS_BATCH(batch, 0); /* DW 53, memory address attributes */
287 OUT_BUFFER_MA_REFERENCE(NULL); /* DW 54..56, ignore for decoding mode */
288 OUT_BUFFER_MA_TARGET(NULL);
289 OUT_BUFFER_MA_TARGET(NULL);
290 OUT_BUFFER_MA_TARGET(NULL);
292 for (i = 0; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++) {
293 obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface;
294 gen9_hevc_surface = NULL;
296 if (obj_surface && obj_surface->private_data)
297 gen9_hevc_surface = obj_surface->private_data;
299 if (gen9_hevc_surface)
300 OUT_BUFFER_NMA_REFERENCE(gen9_hevc_surface->motion_vector_temporal_bo);
302 OUT_BUFFER_NMA_REFERENCE(NULL);
304 OUT_BCS_BATCH(batch, 0); /* DW 82, memory address attributes */
306 OUT_BUFFER_MA_TARGET(NULL); /* DW 83..85, ignore for HEVC */
307 OUT_BUFFER_MA_TARGET(NULL); /* DW 86..88, ignore for HEVC */
308 OUT_BUFFER_MA_TARGET(NULL); /* DW 89..91, ignore for HEVC */
309 OUT_BUFFER_MA_TARGET(NULL); /* DW 92..94, ignore for HEVC */
311 ADVANCE_BCS_BATCH(batch);
315 gen9_hcpd_ind_obj_base_addr_state(VADriverContextP ctx,
316 dri_bo *slice_data_bo,
317 struct gen9_hcpd_context *gen9_hcpd_context)
319 struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
321 BEGIN_BCS_BATCH(batch, 14);
323 OUT_BCS_BATCH(batch, HCP_IND_OBJ_BASE_ADDR_STATE | (14 - 2));
324 OUT_BUFFER_MA_REFERENCE(slice_data_bo); /* DW 1..3 */
325 OUT_BUFFER_NMA_REFERENCE(NULL); /* DW 4..5, Upper Bound */
326 OUT_BUFFER_MA_REFERENCE(NULL); /* DW 6..8, CU, ignored */
327 OUT_BUFFER_MA_TARGET(NULL); /* DW 9..11, PAK-BSE, ignored */
328 OUT_BUFFER_NMA_TARGET(NULL); /* DW 12..13, Upper Bound */
330 ADVANCE_BCS_BATCH(batch);
334 gen9_hcpd_qm_state(VADriverContextP ctx,
341 struct gen9_hcpd_context *gen9_hcpd_context)
343 struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
344 unsigned char qm_buffer[64];
346 assert(qm_length <= 64);
347 memset(qm_buffer, 0, sizeof(qm_buffer));
348 memcpy(qm_buffer, qm, qm_length);
350 BEGIN_BCS_BATCH(batch, 18);
352 OUT_BCS_BATCH(batch, HCP_QM_STATE | (18 - 2));
355 color_component << 3 |
358 intel_batchbuffer_data(batch, qm_buffer, 64);
360 ADVANCE_BCS_BATCH(batch);
364 gen9_hcpd_hevc_qm_state(VADriverContextP ctx,
365 struct decode_state *decode_state,
366 struct gen9_hcpd_context *gen9_hcpd_context)
368 VAIQMatrixBufferHEVC *iq_matrix;
369 VAPictureParameterBufferHEVC *pic_param;
372 if (decode_state->iq_matrix && decode_state->iq_matrix->buffer)
373 iq_matrix = (VAIQMatrixBufferHEVC *)decode_state->iq_matrix->buffer;
375 iq_matrix = &gen9_hcpd_context->iq_matrix_hevc;
377 assert(decode_state->pic_param && decode_state->pic_param->buffer);
378 pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
380 if (!pic_param->pic_fields.bits.scaling_list_enabled_flag)
381 iq_matrix = &gen9_hcpd_context->iq_matrix_hevc;
383 for (i = 0; i < 6; i++) {
384 gen9_hcpd_qm_state(ctx,
386 iq_matrix->ScalingList4x4[i], 16,
390 for (i = 0; i < 6; i++) {
391 gen9_hcpd_qm_state(ctx,
393 iq_matrix->ScalingList8x8[i], 64,
397 for (i = 0; i < 6; i++) {
398 gen9_hcpd_qm_state(ctx,
399 2, i % 3, i / 3, iq_matrix->ScalingListDC16x16[i],
400 iq_matrix->ScalingList16x16[i], 64,
404 for (i = 0; i < 2; i++) {
405 gen9_hcpd_qm_state(ctx,
406 3, 0, i % 2, iq_matrix->ScalingListDC32x32[i],
407 iq_matrix->ScalingList32x32[i], 64,
413 gen9_hcpd_hevc_decode_picture(VADriverContextP ctx,
414 struct decode_state *decode_state,
415 struct gen9_hcpd_context *gen9_hcpd_context)
418 struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
419 dri_bo *slice_data_bo;
422 vaStatus = gen9_hcpd_hevc_decode_init(ctx, decode_state, gen9_hcpd_context);
424 if (vaStatus != VA_STATUS_SUCCESS)
427 intel_batchbuffer_start_atomic_bcs(batch, 0x1000);
428 intel_batchbuffer_emit_mi_flush(batch);
430 gen9_hcpd_pipe_mode_select(ctx, decode_state, HCP_CODEC_HEVC, gen9_hcpd_context);
431 gen9_hcpd_surface_state(ctx, decode_state, gen9_hcpd_context);
432 gen9_hcpd_pipe_buf_addr_state(ctx, decode_state, gen9_hcpd_context);
433 gen9_hcpd_hevc_qm_state(ctx, decode_state, gen9_hcpd_context);
435 /* Need to double it works or not if the two slice groups have differenct slice data buffers */
436 for (j = 0; j < decode_state->num_slice_params; j++) {
437 slice_data_bo = decode_state->slice_datas[j]->bo;
439 gen9_hcpd_ind_obj_base_addr_state(ctx, slice_data_bo, gen9_hcpd_context);
442 intel_batchbuffer_end_atomic(batch);
443 intel_batchbuffer_flush(batch);
450 gen9_hcpd_decode_picture(VADriverContextP ctx,
452 union codec_state *codec_state,
453 struct hw_context *hw_context)
455 struct gen9_hcpd_context *gen9_hcpd_context = (struct gen9_hcpd_context *)hw_context;
456 struct decode_state *decode_state = &codec_state->decode;
459 assert(gen9_hcpd_context);
461 vaStatus = intel_decoder_sanity_check_input(ctx, profile, decode_state);
463 if (vaStatus != VA_STATUS_SUCCESS)
467 case VAProfileHEVCMain:
468 case VAProfileHEVCMain10:
469 vaStatus = gen9_hcpd_hevc_decode_picture(ctx, decode_state, gen9_hcpd_context);
473 /* should never get here 1!! */
483 gen9_hcpd_context_destroy(void *hw_context)
485 struct gen9_hcpd_context *gen9_hcpd_context = (struct gen9_hcpd_context *)hw_context;
487 FREE_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_line_buffer));
488 FREE_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_line_buffer));
489 FREE_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_column_buffer));
490 FREE_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer));
491 FREE_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer));
492 FREE_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer));
493 FREE_GEN_BUFFER((&gen9_hcpd_context->sao_line_buffer));
494 FREE_GEN_BUFFER((&gen9_hcpd_context->sao_tile_line_buffer));
495 FREE_GEN_BUFFER((&gen9_hcpd_context->sao_tile_column_buffer));
497 intel_batchbuffer_free(gen9_hcpd_context->base.batch);
498 free(gen9_hcpd_context);
502 gen9_hcpd_hevc_context_init(VADriverContextP ctx,
503 struct gen9_hcpd_context *gen9_hcpd_context)
505 hevc_gen_default_iq_matrix(&gen9_hcpd_context->iq_matrix_hevc);
508 static struct hw_context *
509 gen9_hcpd_context_init(VADriverContextP ctx, struct object_config *object_config)
511 struct intel_driver_data *intel = intel_driver_data(ctx);
512 struct gen9_hcpd_context *gen9_hcpd_context = calloc(1, sizeof(struct gen9_hcpd_context));
515 if (!gen9_hcpd_context)
518 gen9_hcpd_context->base.destroy = gen9_hcpd_context_destroy;
519 gen9_hcpd_context->base.run = gen9_hcpd_decode_picture;
520 gen9_hcpd_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
522 for (i = 0; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++) {
523 gen9_hcpd_context->reference_surfaces[i].surface_id = VA_INVALID_ID;
524 gen9_hcpd_context->reference_surfaces[i].frame_store_id = -1;
525 gen9_hcpd_context->reference_surfaces[i].obj_surface = NULL;
528 switch (object_config->profile) {
529 case VAProfileHEVCMain:
530 case VAProfileHEVCMain10:
531 gen9_hcpd_hevc_context_init(ctx, gen9_hcpd_context);
538 return (struct hw_context *)gen9_hcpd_context;
542 gen9_dec_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
544 if (obj_config->profile == VAProfileHEVCMain ||
545 obj_config->profile == VAProfileHEVCMain10) {
546 return gen9_hcpd_context_init(ctx, obj_config);
548 return gen8_dec_hw_context_init(ctx, obj_config);