OSDN Git Service

Add the override flag to assure that HEVC video command always uses BSD ring0 for...
[android-x86/hardware-intel-common-vaapi.git] / src / gen9_mfd.c
1 /*
2  * Copyright © 2014 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
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:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
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.
23  *
24  * Authors:
25  *    Xiang Haihao <haihao.xiang@intel.com>
26  *
27  */
28
29 #include "sysdeps.h"
30
31 #include <va/va.h>
32 #include <va/va_dec_hevc.h>
33
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"
39
40 #include "gen9_mfd.h"
41 #include "intel_media.h"
42
43 #define OUT_BUFFER(buf_bo, is_target, ma)  do {                         \
44         if (buf_bo) {                                                   \
45             OUT_BCS_RELOC(batch,                                        \
46                           buf_bo,                                       \
47                           I915_GEM_DOMAIN_RENDER,                       \
48                           is_target ? I915_GEM_DOMAIN_RENDER : 0,       \
49                           0);                                           \
50         } else {                                                        \
51             OUT_BCS_BATCH(batch, 0);                                    \
52         }                                                               \
53         OUT_BCS_BATCH(batch, 0);                                        \
54         if (ma)                                                         \
55             OUT_BCS_BATCH(batch, 0);                                    \
56     } while (0)
57
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)
62
63 static void
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)
68 {
69     struct i965_driver_data *i965 = i965_driver_data(ctx);
70     GenHevcSurface *gen9_hevc_surface;
71
72     if (!obj_surface)
73         return;
74
75     obj_surface->free_private_data = gen_free_hevc_surface;
76     gen9_hevc_surface = obj_surface->private_data;
77
78     if (!gen9_hevc_surface) {
79         gen9_hevc_surface = calloc(sizeof(GenHevcSurface), 1);
80         gen9_hevc_surface->base.frame_store_id = -1;
81         obj_surface->private_data = gen9_hevc_surface;
82     }
83
84     if (gen9_hevc_surface->motion_vector_temporal_bo == NULL) {
85         uint32_t size;
86
87         if (gen9_hcpd_context->ctb_size == 16)
88             size = ((gen9_hcpd_context->picture_width_in_pixels + 63) >> 6) *
89                 ((gen9_hcpd_context->picture_height_in_pixels + 15) >> 4);
90         else
91             size = ((gen9_hcpd_context->picture_width_in_pixels + 31) >> 5) *
92                 ((gen9_hcpd_context->picture_height_in_pixels + 31) >> 5);
93
94         size <<= 6; /* in unit of 64bytes */
95         gen9_hevc_surface->motion_vector_temporal_bo = dri_bo_alloc(i965->intel.bufmgr,
96                                                                     "motion vector temporal buffer",
97                                                                     size,
98                                                                     0x1000);
99     }
100 }
101
102 static VAStatus
103 gen9_hcpd_hevc_decode_init(VADriverContextP ctx,
104                            struct decode_state *decode_state,
105                            struct gen9_hcpd_context *gen9_hcpd_context)
106 {
107     struct i965_driver_data *i965 = i965_driver_data(ctx);
108     VAPictureParameterBufferHEVC *pic_param;
109     VASliceParameterBufferHEVC *slice_param;
110     struct object_surface *obj_surface;
111     uint32_t size;
112     int i, j, has_inter = 0;
113
114     for (j = 0; j < decode_state->num_slice_params && !has_inter; j++) {
115         assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
116         slice_param = (VASliceParameterBufferHEVC *)decode_state->slice_params[j]->buffer;
117
118         for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
119             if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_B ||
120                 slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_P) {
121                 has_inter = 1;
122                 break;
123             }
124
125             slice_param++;
126         }
127     }
128
129     assert(decode_state->pic_param && decode_state->pic_param->buffer);
130     pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
131     intel_update_hevc_frame_store_index(ctx,
132                                         decode_state,
133                                         pic_param,
134                                         gen9_hcpd_context->reference_surfaces,
135                                         &gen9_hcpd_context->fs_ctx);
136
137     gen9_hcpd_context->picture_width_in_pixels = pic_param->pic_width_in_luma_samples;
138     gen9_hcpd_context->picture_height_in_pixels = pic_param->pic_height_in_luma_samples;
139     gen9_hcpd_context->ctb_size = (1 << (pic_param->log2_min_luma_coding_block_size_minus3 +
140                                          3 +
141                                          pic_param->log2_diff_max_min_luma_coding_block_size));
142     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;
143     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;
144     gen9_hcpd_context->min_cb_size = (1 << (pic_param->log2_min_luma_coding_block_size_minus3 + 3));
145     gen9_hcpd_context->picture_width_in_min_cb_minus1 = gen9_hcpd_context->picture_width_in_pixels / gen9_hcpd_context->min_cb_size - 1;
146     gen9_hcpd_context->picture_height_in_min_cb_minus1 = gen9_hcpd_context->picture_height_in_pixels / gen9_hcpd_context->min_cb_size - 1;
147
148     /* Current decoded picture */
149     obj_surface = decode_state->render_object;
150     hevc_ensure_surface_bo(ctx, decode_state, obj_surface, pic_param);
151     gen9_hcpd_init_hevc_surface(ctx, pic_param, obj_surface, gen9_hcpd_context);
152
153     size = ALIGN(gen9_hcpd_context->picture_width_in_pixels, 32) >> 3;
154     size <<= 6;
155     ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_line_buffer), "line buffer", size);
156     ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_line_buffer), "tile line buffer", size);
157
158     size = ALIGN(gen9_hcpd_context->picture_height_in_pixels + 6 * gen9_hcpd_context->picture_height_in_ctbs, 32) >> 3;
159     size <<= 6;
160     ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_column_buffer), "tile column buffer", size);
161
162     if (has_inter) {
163         size = (((gen9_hcpd_context->picture_width_in_pixels + 15) >> 4) * 188 + 9 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
164         size <<= 6;
165         ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer), "metadata line buffer", size);
166
167         size = (((gen9_hcpd_context->picture_width_in_pixels + 15) >> 4) * 172 + 9 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
168         size <<= 6;
169         ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer), "metadata tile line buffer", size);
170
171         size = (((gen9_hcpd_context->picture_height_in_pixels + 15) >> 4) * 176 + 89 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
172         size <<= 6;
173         ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer), "metadata tile column buffer", size);
174     } else {
175         size = (gen9_hcpd_context->picture_width_in_pixels + 8 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
176         size <<= 6;
177         ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer), "metadata line buffer", size);
178
179         size = (gen9_hcpd_context->picture_width_in_pixels + 16 * gen9_hcpd_context->picture_width_in_ctbs + 1023) >> 9;
180         size <<= 6;
181         ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer), "metadata tile line buffer", size);
182
183         size = (gen9_hcpd_context->picture_height_in_pixels + 8 * gen9_hcpd_context->picture_height_in_ctbs + 1023) >> 9;
184         size <<= 6;
185         ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer), "metadata tile column buffer", size);
186     }
187
188     size = ALIGN(((gen9_hcpd_context->picture_width_in_pixels >> 1) + 3 * gen9_hcpd_context->picture_width_in_ctbs), 16) >> 3;
189     size <<= 6;
190     ALLOC_GEN_BUFFER((&gen9_hcpd_context->sao_line_buffer), "sao line buffer", size);
191
192     size = ALIGN(((gen9_hcpd_context->picture_width_in_pixels >> 1) + 6 * gen9_hcpd_context->picture_width_in_ctbs), 16) >> 3;
193     size <<= 6;
194     ALLOC_GEN_BUFFER((&gen9_hcpd_context->sao_tile_line_buffer), "sao tile line buffer", size);
195
196     size = ALIGN(((gen9_hcpd_context->picture_height_in_pixels >> 1) + 6 * gen9_hcpd_context->picture_height_in_ctbs), 16) >> 3;
197     size <<= 6;
198     ALLOC_GEN_BUFFER((&gen9_hcpd_context->sao_tile_column_buffer), "sao tile column buffer", size);
199
200     return VA_STATUS_SUCCESS;
201 }
202
203 static void
204 gen9_hcpd_pipe_mode_select(VADriverContextP ctx,
205                            struct decode_state *decode_state,
206                            int codec,
207                            struct gen9_hcpd_context *gen9_hcpd_context)
208 {
209     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
210
211     assert(codec == HCP_CODEC_HEVC);
212
213     BEGIN_BCS_BATCH(batch, 4);
214
215     OUT_BCS_BATCH(batch, HCP_PIPE_MODE_SELECT | (4 - 2));
216     OUT_BCS_BATCH(batch,
217                   (codec << 5) |
218                   (0 << 3) | /* disable Pic Status / Error Report */
219                   HCP_CODEC_SELECT_DECODE);
220     OUT_BCS_BATCH(batch, 0);
221     OUT_BCS_BATCH(batch, 0);
222
223     ADVANCE_BCS_BATCH(batch);
224 }
225
226 static void
227 gen9_hcpd_surface_state(VADriverContextP ctx,
228                         struct decode_state *decode_state,
229                         struct gen9_hcpd_context *gen9_hcpd_context)
230 {
231     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
232     struct object_surface *obj_surface = decode_state->render_object;
233     unsigned int y_cb_offset;
234
235     assert(obj_surface);
236
237     y_cb_offset = obj_surface->y_cb_offset;
238
239     BEGIN_BCS_BATCH(batch, 3);
240
241     OUT_BCS_BATCH(batch, HCP_SURFACE_STATE | (3 - 2));
242     OUT_BCS_BATCH(batch,
243                   (0 << 28) |                   /* surface id */
244                   (obj_surface->width - 1));    /* pitch - 1 */
245     OUT_BCS_BATCH(batch,
246                   (SURFACE_FORMAT_PLANAR_420_8 << 28) |
247                   y_cb_offset);
248
249     ADVANCE_BCS_BATCH(batch);
250 }
251
252 static void
253 gen9_hcpd_pipe_buf_addr_state(VADriverContextP ctx,
254                               struct decode_state *decode_state,
255                               struct gen9_hcpd_context *gen9_hcpd_context)
256 {
257     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
258     struct object_surface *obj_surface;
259     GenHevcSurface *gen9_hevc_surface;
260     int i;
261
262     BEGIN_BCS_BATCH(batch, 95);
263
264     OUT_BCS_BATCH(batch, HCP_PIPE_BUF_ADDR_STATE | (95 - 2));
265
266     obj_surface = decode_state->render_object;
267     assert(obj_surface && obj_surface->bo);
268     gen9_hevc_surface = obj_surface->private_data;
269     assert(gen9_hevc_surface && gen9_hevc_surface->motion_vector_temporal_bo);
270
271     OUT_BUFFER_MA_TARGET(obj_surface->bo); /* DW 1..3 */
272     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_line_buffer.bo);/* DW 4..6 */
273     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_tile_line_buffer.bo); /* DW 7..9 */
274     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_tile_column_buffer.bo); /* DW 10..12 */
275     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_line_buffer.bo);         /* DW 13..15 */
276     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_tile_line_buffer.bo);    /* DW 16..18 */
277     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_tile_column_buffer.bo);  /* DW 19..21 */
278     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->sao_line_buffer.bo);              /* DW 22..24 */
279     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->sao_tile_line_buffer.bo);         /* DW 25..27 */
280     OUT_BUFFER_MA_TARGET(gen9_hcpd_context->sao_tile_column_buffer.bo);       /* DW 28..30 */
281     OUT_BUFFER_MA_TARGET(gen9_hevc_surface->motion_vector_temporal_bo); /* DW 31..33 */
282     OUT_BUFFER_MA_TARGET(NULL); /* DW 34..36, reserved */
283
284     for (i = 0; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++) {
285         obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface;
286
287         if (obj_surface)
288             OUT_BUFFER_NMA_REFERENCE(obj_surface->bo);
289         else
290             OUT_BUFFER_NMA_REFERENCE(NULL);
291     }
292     OUT_BCS_BATCH(batch, 0);    /* DW 53, memory address attributes */
293
294     OUT_BUFFER_MA_REFERENCE(NULL); /* DW 54..56, ignore for decoding mode */
295     OUT_BUFFER_MA_TARGET(NULL);
296     OUT_BUFFER_MA_TARGET(NULL);
297     OUT_BUFFER_MA_TARGET(NULL);
298
299     for (i = 0; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++) {
300         obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface;
301         gen9_hevc_surface = NULL;
302
303         if (obj_surface && obj_surface->private_data)
304             gen9_hevc_surface = obj_surface->private_data;
305
306         if (gen9_hevc_surface)
307             OUT_BUFFER_NMA_REFERENCE(gen9_hevc_surface->motion_vector_temporal_bo);
308         else
309             OUT_BUFFER_NMA_REFERENCE(NULL);
310     }
311     OUT_BCS_BATCH(batch, 0);    /* DW 82, memory address attributes */
312
313     OUT_BUFFER_MA_TARGET(NULL);    /* DW 83..85, ignore for HEVC */
314     OUT_BUFFER_MA_TARGET(NULL);    /* DW 86..88, ignore for HEVC */
315     OUT_BUFFER_MA_TARGET(NULL);    /* DW 89..91, ignore for HEVC */
316     OUT_BUFFER_MA_TARGET(NULL);    /* DW 92..94, ignore for HEVC */
317
318     ADVANCE_BCS_BATCH(batch);
319 }
320
321 static void
322 gen9_hcpd_ind_obj_base_addr_state(VADriverContextP ctx,
323                                   dri_bo *slice_data_bo,
324                                   struct gen9_hcpd_context *gen9_hcpd_context)
325 {
326     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
327
328     BEGIN_BCS_BATCH(batch, 14);
329
330     OUT_BCS_BATCH(batch, HCP_IND_OBJ_BASE_ADDR_STATE | (14 - 2));
331     OUT_BUFFER_MA_REFERENCE(slice_data_bo);        /* DW 1..3 */
332     OUT_BUFFER_NMA_REFERENCE(NULL);                /* DW 4..5, Upper Bound */
333     OUT_BUFFER_MA_REFERENCE(NULL);                 /* DW 6..8, CU, ignored */
334     OUT_BUFFER_MA_TARGET(NULL);                    /* DW 9..11, PAK-BSE, ignored */
335     OUT_BUFFER_NMA_TARGET(NULL);                   /* DW 12..13, Upper Bound  */
336
337     ADVANCE_BCS_BATCH(batch);
338 }
339
340 static void
341 gen9_hcpd_qm_state(VADriverContextP ctx,
342                    int size_id,
343                    int color_component,
344                    int pred_type,
345                    int dc,
346                    unsigned char *qm,
347                    int qm_length,
348                    struct gen9_hcpd_context *gen9_hcpd_context)
349 {
350     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
351     unsigned char qm_buffer[64];
352
353     assert(qm_length <= 64);
354     memset(qm_buffer, 0, sizeof(qm_buffer));
355     memcpy(qm_buffer, qm, qm_length);
356
357     BEGIN_BCS_BATCH(batch, 18);
358
359     OUT_BCS_BATCH(batch, HCP_QM_STATE | (18 - 2));
360     OUT_BCS_BATCH(batch,
361                   dc << 5 |
362                   color_component << 3 |
363                   size_id << 1 |
364                   pred_type);
365     intel_batchbuffer_data(batch, qm_buffer, 64);
366
367     ADVANCE_BCS_BATCH(batch);
368 }
369
370 static void
371 gen9_hcpd_hevc_qm_state(VADriverContextP ctx,
372                         struct decode_state *decode_state,
373                         struct gen9_hcpd_context *gen9_hcpd_context)
374 {
375     VAIQMatrixBufferHEVC *iq_matrix;
376     VAPictureParameterBufferHEVC *pic_param;
377     int i;
378
379     if (decode_state->iq_matrix && decode_state->iq_matrix->buffer)
380         iq_matrix = (VAIQMatrixBufferHEVC *)decode_state->iq_matrix->buffer;
381     else
382         iq_matrix = &gen9_hcpd_context->iq_matrix_hevc;
383
384     assert(decode_state->pic_param && decode_state->pic_param->buffer);
385     pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
386
387     if (!pic_param->pic_fields.bits.scaling_list_enabled_flag)
388         iq_matrix = &gen9_hcpd_context->iq_matrix_hevc;
389
390     for (i = 0; i < 6; i++) {
391         gen9_hcpd_qm_state(ctx,
392                            0, i % 3, i / 3, 0,
393                            iq_matrix->ScalingList4x4[i], 16,
394                            gen9_hcpd_context);
395     }
396
397     for (i = 0; i < 6; i++) {
398         gen9_hcpd_qm_state(ctx,
399                            1, i % 3, i / 3, 0,
400                            iq_matrix->ScalingList8x8[i], 64,
401                            gen9_hcpd_context);
402     }
403
404     for (i = 0; i < 6; i++) {
405         gen9_hcpd_qm_state(ctx,
406                            2, i % 3, i / 3, iq_matrix->ScalingListDC16x16[i],
407                            iq_matrix->ScalingList16x16[i], 64,
408                            gen9_hcpd_context);
409     }
410
411     for (i = 0; i < 2; i++) {
412         gen9_hcpd_qm_state(ctx,
413                            3, 0, i % 2, iq_matrix->ScalingListDC32x32[i],
414                            iq_matrix->ScalingList32x32[i], 64,
415                            gen9_hcpd_context);
416     }
417 }
418
419 static void
420 gen9_hcpd_pic_state(VADriverContextP ctx,
421                     struct decode_state *decode_state,
422                     struct gen9_hcpd_context *gen9_hcpd_context)
423 {
424     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
425     VAPictureParameterBufferHEVC *pic_param;
426     int max_pcm_size_minus3 = 0, min_pcm_size_minus3 = 0;
427     int pcm_sample_bit_depth_luma_minus1 = 7, pcm_sample_bit_depth_chroma_minus1 = 7;
428     /*
429      * 7.4.3.1
430      *
431      * When not present, the value of loop_filter_across_tiles_enabled_flag
432      * is inferred to be equal to 1.
433      */
434     int loop_filter_across_tiles_enabled_flag = 1;
435
436     assert(decode_state->pic_param && decode_state->pic_param->buffer);
437     pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
438
439     if (pic_param->pic_fields.bits.pcm_enabled_flag) {
440         max_pcm_size_minus3 = pic_param->log2_min_pcm_luma_coding_block_size_minus3 +
441             pic_param->log2_diff_max_min_pcm_luma_coding_block_size;
442         min_pcm_size_minus3 = pic_param->log2_min_pcm_luma_coding_block_size_minus3;
443         pcm_sample_bit_depth_luma_minus1 = (pic_param->pcm_sample_bit_depth_luma_minus1 & 0x0f);
444         pcm_sample_bit_depth_chroma_minus1 = (pic_param->pcm_sample_bit_depth_chroma_minus1 & 0x0f);
445     } else {
446         max_pcm_size_minus3 = MIN(pic_param->log2_min_luma_coding_block_size_minus3 + pic_param->log2_diff_max_min_luma_coding_block_size, 2);
447     }
448
449     if (pic_param->pic_fields.bits.tiles_enabled_flag)
450         loop_filter_across_tiles_enabled_flag = pic_param->pic_fields.bits.loop_filter_across_tiles_enabled_flag;
451
452     BEGIN_BCS_BATCH(batch, 19);
453
454     OUT_BCS_BATCH(batch, HCP_PIC_STATE | (19 - 2));
455
456     OUT_BCS_BATCH(batch,
457                   gen9_hcpd_context->picture_height_in_min_cb_minus1 << 16 |
458                   gen9_hcpd_context->picture_width_in_min_cb_minus1);
459     OUT_BCS_BATCH(batch,
460                   max_pcm_size_minus3 << 10 |
461                   min_pcm_size_minus3 << 8 |
462                   (pic_param->log2_min_transform_block_size_minus2 +
463                    pic_param->log2_diff_max_min_transform_block_size) << 6 |
464                   pic_param->log2_min_transform_block_size_minus2 << 4 |
465                   (pic_param->log2_min_luma_coding_block_size_minus3 +
466                    pic_param->log2_diff_max_min_luma_coding_block_size) << 2 |
467                   pic_param->log2_min_luma_coding_block_size_minus3);
468     OUT_BCS_BATCH(batch, 0); /* DW 3, ignored */
469     OUT_BCS_BATCH(batch,
470                   0 << 27 |
471                   pic_param->pic_fields.bits.strong_intra_smoothing_enabled_flag << 26 |
472                   pic_param->pic_fields.bits.transquant_bypass_enabled_flag << 25 |
473                   pic_param->pic_fields.bits.amp_enabled_flag << 23 |
474                   pic_param->pic_fields.bits.transform_skip_enabled_flag << 22 |
475                   !(pic_param->CurrPic.flags & VA_PICTURE_HEVC_BOTTOM_FIELD) << 21 |
476                   !!(pic_param->CurrPic.flags & VA_PICTURE_HEVC_FIELD_PIC) << 20 |
477                   pic_param->pic_fields.bits.weighted_pred_flag << 19 |
478                   pic_param->pic_fields.bits.weighted_bipred_flag << 18 |
479                   pic_param->pic_fields.bits.tiles_enabled_flag << 17 |
480                   pic_param->pic_fields.bits.entropy_coding_sync_enabled_flag << 16 |
481                   loop_filter_across_tiles_enabled_flag << 15 |
482                   pic_param->pic_fields.bits.sign_data_hiding_enabled_flag << 13 |
483                   pic_param->log2_parallel_merge_level_minus2 << 10 |
484                   pic_param->pic_fields.bits.constrained_intra_pred_flag << 9 |
485                   pic_param->pic_fields.bits.pcm_loop_filter_disabled_flag << 8 |
486                   (pic_param->diff_cu_qp_delta_depth & 0x03) << 6 |
487                   pic_param->pic_fields.bits.cu_qp_delta_enabled_flag << 5 |
488                   pic_param->pic_fields.bits.pcm_enabled_flag << 4 |
489                   pic_param->slice_parsing_fields.bits.sample_adaptive_offset_enabled_flag << 3 |
490                   0);
491     OUT_BCS_BATCH(batch,
492                   pcm_sample_bit_depth_luma_minus1 << 20 |
493                   pcm_sample_bit_depth_chroma_minus1 << 16 |
494                   pic_param->max_transform_hierarchy_depth_inter << 13 |
495                   pic_param->max_transform_hierarchy_depth_intra << 10 |
496                   (pic_param->pps_cr_qp_offset & 0x1f) << 5 |
497                   (pic_param->pps_cb_qp_offset & 0x1f));
498     OUT_BCS_BATCH(batch,
499                   0 << 29 |
500                   0);
501     OUT_BCS_BATCH(batch, 0);
502     OUT_BCS_BATCH(batch, 0);
503     OUT_BCS_BATCH(batch, 0);
504     OUT_BCS_BATCH(batch, 0); /* DW 10 */
505     OUT_BCS_BATCH(batch, 0);
506     OUT_BCS_BATCH(batch, 0);
507     OUT_BCS_BATCH(batch, 0);
508     OUT_BCS_BATCH(batch, 0);
509     OUT_BCS_BATCH(batch, 0); /* DW 15 */
510     OUT_BCS_BATCH(batch, 0);
511     OUT_BCS_BATCH(batch, 0);
512     OUT_BCS_BATCH(batch, 0);
513
514     ADVANCE_BCS_BATCH(batch);
515 }
516
517 static void
518 gen9_hcpd_tile_state(VADriverContextP ctx,
519                      struct decode_state *decode_state,
520                      struct gen9_hcpd_context *gen9_hcpd_context)
521 {
522     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
523     VAPictureParameterBufferHEVC *pic_param;
524     uint8_t pos_col[20], pos_row[24];
525     int i;
526
527     assert(decode_state->pic_param && decode_state->pic_param->buffer);
528     pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
529
530     memset(pos_col, 0, sizeof(pos_col));
531     memset(pos_row, 0, sizeof(pos_row));
532
533     for (i = 0; i <= MIN(pic_param->num_tile_columns_minus1, 18); i++)
534         pos_col[i + 1] = pos_col[i] + pic_param->column_width_minus1[i] + 1;
535
536     for (i = 0; i <= MIN(pic_param->num_tile_rows_minus1, 20); i++)
537         pos_row[i + 1] = pos_row[i] + pic_param->row_height_minus1[i] + 1;
538
539     BEGIN_BCS_BATCH(batch, 13);
540
541     OUT_BCS_BATCH(batch, HCP_TILE_STATE | (13 - 2));
542
543     OUT_BCS_BATCH(batch,
544                   pic_param->num_tile_columns_minus1 << 5 |
545                   pic_param->num_tile_rows_minus1);
546     intel_batchbuffer_data(batch, pos_col, 20);
547     intel_batchbuffer_data(batch, pos_row, 24);
548
549     ADVANCE_BCS_BATCH(batch);
550 }
551
552 static int
553 gen9_hcpd_get_reference_picture_frame_id(VAPictureHEVC *ref_pic,
554                                          GenFrameStore frame_store[MAX_GEN_HCP_REFERENCE_FRAMES])
555 {
556     int i;
557
558     if (ref_pic->picture_id == VA_INVALID_ID ||
559         (ref_pic->flags & VA_PICTURE_HEVC_INVALID))
560         return 0;
561
562     for (i = 0; i < MAX_GEN_HCP_REFERENCE_FRAMES; i++) {
563         if (ref_pic->picture_id == frame_store[i].surface_id) {
564             assert(frame_store[i].frame_store_id < MAX_GEN_HCP_REFERENCE_FRAMES);
565             return frame_store[i].frame_store_id;
566         }
567     }
568
569     /* Should never get here !!! */
570     assert(0);
571     return 0;
572 }
573
574 static void
575 gen9_hcpd_ref_idx_state_1(struct intel_batchbuffer *batch,
576                           int list,
577                           VAPictureParameterBufferHEVC *pic_param,
578                           VASliceParameterBufferHEVC *slice_param,
579                           GenFrameStore frame_store[MAX_GEN_HCP_REFERENCE_FRAMES])
580 {
581     int i;
582     uint8_t num_ref_minus1 = (list ? slice_param->num_ref_idx_l1_active_minus1 : slice_param->num_ref_idx_l0_active_minus1);
583     uint8_t *ref_list = slice_param->RefPicList[list];
584
585     BEGIN_BCS_BATCH(batch, 18);
586
587     OUT_BCS_BATCH(batch, HCP_REF_IDX_STATE | (18 - 2));
588     OUT_BCS_BATCH(batch,
589                   num_ref_minus1 << 1 |
590                   list);
591
592     for (i = 0; i < 16; i++) {
593         if (i < MIN((num_ref_minus1 + 1), 15)) {
594             VAPictureHEVC *ref_pic = &pic_param->ReferenceFrames[ref_list[i]];
595             VAPictureHEVC *curr_pic = &pic_param->CurrPic;
596
597             OUT_BCS_BATCH(batch,
598                           !(ref_pic->flags & VA_PICTURE_HEVC_BOTTOM_FIELD) << 15 |
599                           !!(ref_pic->flags & VA_PICTURE_HEVC_FIELD_PIC) << 14 |
600                           !!(ref_pic->flags & VA_PICTURE_HEVC_LONG_TERM_REFERENCE) << 13 |
601                           0 << 12 |
602                           0 << 11 |
603                           gen9_hcpd_get_reference_picture_frame_id(ref_pic, frame_store) << 8 |
604                           (CLAMP(-128, 127, curr_pic->pic_order_cnt - ref_pic->pic_order_cnt) & 0xff));
605         } else {
606             OUT_BCS_BATCH(batch, 0);
607         }
608     }
609
610     ADVANCE_BCS_BATCH(batch);
611 }
612
613 static void
614 gen9_hcpd_ref_idx_state(VADriverContextP ctx,
615                         VAPictureParameterBufferHEVC *pic_param,
616                         VASliceParameterBufferHEVC *slice_param,
617                         struct gen9_hcpd_context *gen9_hcpd_context)
618 {
619     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
620
621     if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_I)
622         return;
623
624     gen9_hcpd_ref_idx_state_1(batch, 0, pic_param, slice_param, gen9_hcpd_context->reference_surfaces);
625
626     if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_P)
627         return;
628
629     gen9_hcpd_ref_idx_state_1(batch, 1, pic_param, slice_param, gen9_hcpd_context->reference_surfaces);
630 }
631
632 static void
633 gen9_hcpd_weightoffset_state_1(struct intel_batchbuffer *batch,
634                                int list,
635                                VASliceParameterBufferHEVC *slice_param)
636 {
637     int i;
638     uint8_t num_ref_minus1 = (list == 1) ? slice_param->num_ref_idx_l1_active_minus1 : slice_param->num_ref_idx_l0_active_minus1;
639     int8_t *luma_offset = (list == 1) ? slice_param->luma_offset_l1 : slice_param->luma_offset_l0;
640     int8_t *delta_luma_weight = (list == 1) ? slice_param->delta_luma_weight_l1 : slice_param->delta_luma_weight_l0;
641     int8_t (* chroma_offset)[2] = (list == 1) ? slice_param->ChromaOffsetL1 : slice_param->ChromaOffsetL0;
642     int8_t (* delta_chroma_weight)[2] = (list == 1) ? slice_param->delta_chroma_weight_l1 : slice_param->delta_chroma_weight_l0;
643
644     BEGIN_BCS_BATCH(batch, 34);
645
646     OUT_BCS_BATCH(batch, HCP_WEIGHTOFFSET | (34 - 2));
647     OUT_BCS_BATCH(batch, list);
648
649     for (i = 0; i < 16; i++) {
650         if (i < MIN((num_ref_minus1 + 1), 15)) {
651             OUT_BCS_BATCH(batch,
652                           luma_offset[i] << 8 |
653                           delta_luma_weight[i]);
654         } else {
655             OUT_BCS_BATCH(batch, 0);
656         }
657     }
658     for (i = 0; i < 16; i++) {
659         if (i < MIN((num_ref_minus1 + 1), 15)) {
660             OUT_BCS_BATCH(batch,
661                           chroma_offset[i][1] << 24 |
662                           delta_chroma_weight[i][1] << 16 |
663                           chroma_offset[i][0] << 8 |
664                           delta_chroma_weight[i][0]);
665         } else {
666             OUT_BCS_BATCH(batch, 0);
667         }
668     }
669
670     ADVANCE_BCS_BATCH(batch);
671 }
672
673 static void
674 gen9_hcpd_weightoffset_state(VADriverContextP ctx,
675                              VAPictureParameterBufferHEVC *pic_param,
676                              VASliceParameterBufferHEVC *slice_param,
677                              struct gen9_hcpd_context *gen9_hcpd_context)
678 {
679     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
680
681     if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_I)
682         return;
683
684     if ((slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_P &&
685          !pic_param->pic_fields.bits.weighted_pred_flag) ||
686         (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_B &&
687          !pic_param->pic_fields.bits.weighted_bipred_flag))
688         return;
689
690     gen9_hcpd_weightoffset_state_1(batch, 0, slice_param);
691
692     if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_P)
693         return;
694
695     gen9_hcpd_weightoffset_state_1(batch, 1, slice_param);
696 }
697
698 static int
699 gen9_hcpd_get_collocated_ref_idx(VADriverContextP ctx,
700                                  VAPictureParameterBufferHEVC *pic_param,
701                                  VASliceParameterBufferHEVC *slice_param,
702                                  struct gen9_hcpd_context *gen9_hcpd_context)
703 {
704     uint8_t *ref_list;
705     VAPictureHEVC *ref_pic;
706
707     if (slice_param->collocated_ref_idx > 14)
708         return 0;
709
710     if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_I)
711         return 0;
712
713     if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_P ||
714         (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_B &&
715          slice_param->LongSliceFlags.fields.collocated_from_l0_flag))
716         ref_list = slice_param->RefPicList[0];
717     else {
718         assert(slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_B);
719         ref_list = slice_param->RefPicList[1];
720     }
721
722     ref_pic = &pic_param->ReferenceFrames[ref_list[slice_param->collocated_ref_idx]];
723
724     return gen9_hcpd_get_reference_picture_frame_id(ref_pic, gen9_hcpd_context->reference_surfaces);
725 }
726
727 static int
728 gen9_hcpd_is_list_low_delay(uint8_t ref_list_count,
729                             uint8_t ref_list[15],
730                             VAPictureHEVC *curr_pic,
731                             VAPictureHEVC ref_surfaces[15])
732 {
733     int i;
734
735     for (i = 0; i < MIN(ref_list_count, 15); i++) {
736         VAPictureHEVC *ref_pic;
737
738         if (ref_list[i] > 14)
739             continue;
740
741         ref_pic = &ref_surfaces[ref_list[i]];
742
743         if (ref_pic->pic_order_cnt > curr_pic->pic_order_cnt)
744             return 0;
745     }
746
747     return 1;
748 }
749
750 static int
751 gen9_hcpd_is_low_delay(VADriverContextP ctx,
752                        VAPictureParameterBufferHEVC *pic_param,
753                        VASliceParameterBufferHEVC *slice_param)
754 {
755     if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_I)
756         return 0;
757     else if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_P)
758         return gen9_hcpd_is_list_low_delay(slice_param->num_ref_idx_l0_active_minus1 + 1,
759                                            slice_param->RefPicList[0],
760                                            &pic_param->CurrPic,
761                                            pic_param->ReferenceFrames);
762     else
763         return gen9_hcpd_is_list_low_delay(slice_param->num_ref_idx_l0_active_minus1 + 1,
764                                            slice_param->RefPicList[0],
765                                            &pic_param->CurrPic,
766                                            pic_param->ReferenceFrames) &&
767             gen9_hcpd_is_list_low_delay(slice_param->num_ref_idx_l1_active_minus1 + 1,
768                                         slice_param->RefPicList[1],
769                                         &pic_param->CurrPic,
770                                         pic_param->ReferenceFrames);
771 }
772
773 static void
774 gen9_hcpd_slice_state(VADriverContextP ctx,
775                       VAPictureParameterBufferHEVC *pic_param,
776                       VASliceParameterBufferHEVC *slice_param,
777                       VASliceParameterBufferHEVC *next_slice_param,
778                       struct gen9_hcpd_context *gen9_hcpd_context)
779 {
780     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
781     int slice_hor_pos, slice_ver_pos, next_slice_hor_pos, next_slice_ver_pos;
782
783     slice_hor_pos = slice_param->slice_segment_address % gen9_hcpd_context->picture_width_in_ctbs;
784     slice_ver_pos = slice_param->slice_segment_address / gen9_hcpd_context->picture_width_in_ctbs;
785
786     if (next_slice_param) {
787         next_slice_hor_pos = next_slice_param->slice_segment_address % gen9_hcpd_context->picture_width_in_ctbs;
788         next_slice_ver_pos = next_slice_param->slice_segment_address / gen9_hcpd_context->picture_width_in_ctbs;
789     } else {
790         next_slice_hor_pos = 0;
791         next_slice_ver_pos = 0;
792     }
793
794     BEGIN_BCS_BATCH(batch, 9);
795
796     OUT_BCS_BATCH(batch, HCP_SLICE_STATE | (9 - 2));
797
798     OUT_BCS_BATCH(batch,
799                   slice_ver_pos << 16 |
800                   slice_hor_pos);
801     OUT_BCS_BATCH(batch,
802                   next_slice_ver_pos << 16 |
803                   next_slice_hor_pos);
804     OUT_BCS_BATCH(batch,
805                   (slice_param->slice_cr_qp_offset & 0x1f) << 17 |
806                   (slice_param->slice_cb_qp_offset & 0x1f) << 12 |
807                   (pic_param->init_qp_minus26 + 26 + slice_param->slice_qp_delta) << 6 |
808                   slice_param->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag << 5 |
809                   slice_param->LongSliceFlags.fields.dependent_slice_segment_flag << 4 |
810                   !next_slice_param << 2 |
811                   slice_param->LongSliceFlags.fields.slice_type);
812     OUT_BCS_BATCH(batch,
813                   gen9_hcpd_get_collocated_ref_idx(ctx, pic_param, slice_param, gen9_hcpd_context) << 26 |
814                   (5 - slice_param->five_minus_max_num_merge_cand - 1) << 23 |
815                   slice_param->LongSliceFlags.fields.cabac_init_flag << 22 |
816                   slice_param->luma_log2_weight_denom << 19 |
817                   (slice_param->luma_log2_weight_denom + slice_param->delta_chroma_log2_weight_denom) << 16 |
818                   slice_param->LongSliceFlags.fields.collocated_from_l0_flag << 15 |
819                   gen9_hcpd_is_low_delay(ctx, pic_param, slice_param) << 14 |
820                   slice_param->LongSliceFlags.fields.mvd_l1_zero_flag << 13 |
821                   slice_param->LongSliceFlags.fields.slice_sao_luma_flag << 12 |
822                   slice_param->LongSliceFlags.fields.slice_sao_chroma_flag << 11 |
823                   slice_param->LongSliceFlags.fields.slice_loop_filter_across_slices_enabled_flag << 10 |
824                   (slice_param->slice_beta_offset_div2 & 0xf) << 5 |
825                   (slice_param->slice_tc_offset_div2 & 0xf) << 1 |
826                   slice_param->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag);
827     OUT_BCS_BATCH(batch,
828                   slice_param->slice_data_byte_offset); /* DW 5 */
829     OUT_BCS_BATCH(batch,
830                   0 << 26 |
831                   0 << 20 |
832                   0);
833     OUT_BCS_BATCH(batch, 0);    /* Ignored for decoding */
834     OUT_BCS_BATCH(batch, 0);    /* Ignored for decoding */
835
836     ADVANCE_BCS_BATCH(batch);
837 }
838
839 static void
840 gen9_hcpd_bsd_object(VADriverContextP ctx,
841                      VASliceParameterBufferHEVC *slice_param,
842                      struct gen9_hcpd_context *gen9_hcpd_context)
843 {
844     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
845
846     BEGIN_BCS_BATCH(batch, 3);
847
848     OUT_BCS_BATCH(batch, HCP_BSD_OBJECT | (3 - 2));
849
850     OUT_BCS_BATCH(batch, slice_param->slice_data_size);
851     OUT_BCS_BATCH(batch, slice_param->slice_data_offset);
852
853     ADVANCE_BCS_BATCH(batch);
854 }
855
856 static VAStatus
857 gen9_hcpd_hevc_decode_picture(VADriverContextP ctx,
858                               struct decode_state *decode_state,
859                               struct gen9_hcpd_context *gen9_hcpd_context)
860 {
861     VAStatus vaStatus;
862     struct i965_driver_data *i965 = i965_driver_data(ctx);
863     struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
864     VAPictureParameterBufferHEVC *pic_param;
865     VASliceParameterBufferHEVC *slice_param, *next_slice_param, *next_slice_group_param;
866     dri_bo *slice_data_bo;
867     int i, j;
868
869     vaStatus = gen9_hcpd_hevc_decode_init(ctx, decode_state, gen9_hcpd_context);
870
871     if (vaStatus != VA_STATUS_SUCCESS)
872         goto out;
873
874     assert(decode_state->pic_param && decode_state->pic_param->buffer);
875     pic_param = (VAPictureParameterBufferHEVC *)decode_state->pic_param->buffer;
876
877     if (i965->intel.has_bsd2)
878         intel_batchbuffer_start_atomic_bcs_override(batch, 0x1000, BSD_RING0);
879     else
880         intel_batchbuffer_start_atomic_bcs(batch, 0x1000);
881     intel_batchbuffer_emit_mi_flush(batch);
882
883     gen9_hcpd_pipe_mode_select(ctx, decode_state, HCP_CODEC_HEVC, gen9_hcpd_context);
884     gen9_hcpd_surface_state(ctx, decode_state, gen9_hcpd_context);
885     gen9_hcpd_pipe_buf_addr_state(ctx, decode_state, gen9_hcpd_context);
886     gen9_hcpd_hevc_qm_state(ctx, decode_state, gen9_hcpd_context);
887     gen9_hcpd_pic_state(ctx, decode_state, gen9_hcpd_context);
888
889     if (pic_param->pic_fields.bits.tiles_enabled_flag)
890         gen9_hcpd_tile_state(ctx, decode_state, gen9_hcpd_context);
891
892     /* Need to double it works or not if the two slice groups have differenct slice data buffers */
893     for (j = 0; j < decode_state->num_slice_params; j++) {
894         assert(decode_state->slice_params && decode_state->slice_params[j]->buffer);
895         slice_param = (VASliceParameterBufferHEVC *)decode_state->slice_params[j]->buffer;
896         slice_data_bo = decode_state->slice_datas[j]->bo;
897
898         gen9_hcpd_ind_obj_base_addr_state(ctx, slice_data_bo, gen9_hcpd_context);
899
900         if (j == decode_state->num_slice_params - 1)
901             next_slice_group_param = NULL;
902         else
903             next_slice_group_param = (VASliceParameterBufferHEVC *)decode_state->slice_params[j + 1]->buffer;
904
905         for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
906             if (i < decode_state->slice_params[j]->num_elements - 1)
907                 next_slice_param = slice_param + 1;
908             else
909                 next_slice_param = next_slice_group_param;
910
911             gen9_hcpd_slice_state(ctx, pic_param, slice_param, next_slice_param, gen9_hcpd_context);
912             gen9_hcpd_ref_idx_state(ctx, pic_param, slice_param, gen9_hcpd_context);
913             gen9_hcpd_weightoffset_state(ctx, pic_param, slice_param, gen9_hcpd_context);
914             gen9_hcpd_bsd_object(ctx, slice_param, gen9_hcpd_context);
915             slice_param++;
916         }
917     }
918
919     intel_batchbuffer_end_atomic(batch);
920     intel_batchbuffer_flush(batch);
921
922 out:
923     return vaStatus;
924 }
925
926 static VAStatus
927 gen9_hcpd_decode_picture(VADriverContextP ctx,
928                          VAProfile profile,
929                          union codec_state *codec_state,
930                          struct hw_context *hw_context)
931 {
932     struct gen9_hcpd_context *gen9_hcpd_context = (struct gen9_hcpd_context *)hw_context;
933     struct decode_state *decode_state = &codec_state->decode;
934     VAStatus vaStatus;
935
936     assert(gen9_hcpd_context);
937
938     vaStatus = intel_decoder_sanity_check_input(ctx, profile, decode_state);
939
940     if (vaStatus != VA_STATUS_SUCCESS)
941         goto out;
942
943     switch (profile) {
944     case VAProfileHEVCMain:
945     case VAProfileHEVCMain10:
946         vaStatus = gen9_hcpd_hevc_decode_picture(ctx, decode_state, gen9_hcpd_context);
947         break;
948
949     default:
950         /* should never get here 1!! */
951         assert(0);
952         break;
953     }
954
955 out:
956     return vaStatus;
957 }
958
959 static void
960 gen9_hcpd_context_destroy(void *hw_context)
961 {
962     struct gen9_hcpd_context *gen9_hcpd_context = (struct gen9_hcpd_context *)hw_context;
963
964     FREE_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_line_buffer));
965     FREE_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_line_buffer));
966     FREE_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_column_buffer));
967     FREE_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer));
968     FREE_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer));
969     FREE_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer));
970     FREE_GEN_BUFFER((&gen9_hcpd_context->sao_line_buffer));
971     FREE_GEN_BUFFER((&gen9_hcpd_context->sao_tile_line_buffer));
972     FREE_GEN_BUFFER((&gen9_hcpd_context->sao_tile_column_buffer));
973
974     intel_batchbuffer_free(gen9_hcpd_context->base.batch);
975     free(gen9_hcpd_context);
976 }
977
978 static void
979 gen9_hcpd_hevc_context_init(VADriverContextP ctx,
980                             struct gen9_hcpd_context *gen9_hcpd_context)
981 {
982     hevc_gen_default_iq_matrix(&gen9_hcpd_context->iq_matrix_hevc);
983 }
984
985 static struct hw_context *
986 gen9_hcpd_context_init(VADriverContextP ctx, struct object_config *object_config)
987 {
988     struct intel_driver_data *intel = intel_driver_data(ctx);
989     struct gen9_hcpd_context *gen9_hcpd_context = calloc(1, sizeof(struct gen9_hcpd_context));
990     int i;
991
992     if (!gen9_hcpd_context)
993         return NULL;
994
995     gen9_hcpd_context->base.destroy = gen9_hcpd_context_destroy;
996     gen9_hcpd_context->base.run = gen9_hcpd_decode_picture;
997     gen9_hcpd_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_VEBOX, 0);
998
999     for (i = 0; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++) {
1000         gen9_hcpd_context->reference_surfaces[i].surface_id = VA_INVALID_ID;
1001         gen9_hcpd_context->reference_surfaces[i].frame_store_id = -1;
1002         gen9_hcpd_context->reference_surfaces[i].obj_surface = NULL;
1003     }
1004
1005     switch (object_config->profile) {
1006     case VAProfileHEVCMain:
1007     case VAProfileHEVCMain10:
1008         gen9_hcpd_hevc_context_init(ctx, gen9_hcpd_context);
1009         break;
1010
1011     default:
1012         break;
1013     }
1014
1015     return (struct hw_context *)gen9_hcpd_context;
1016 }
1017
1018 struct hw_context *
1019 gen9_dec_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
1020 {
1021     if (obj_config->profile == VAProfileHEVCMain ||
1022         obj_config->profile == VAProfileHEVCMain10) {
1023         return gen9_hcpd_context_init(ctx, obj_config);
1024     } else {
1025         return gen8_dec_hw_context_init(ctx, obj_config);
1026     }
1027 }