• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2024 Igalia
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
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "anv_private.h"
25 
26 #include "genxml/gen_macros.h"
27 #include "genxml/genX_pack.h"
28 #include "genX_mi_builder.h"
29 
30 static int
anv_get_max_vmv_range(StdVideoH264LevelIdc level)31 anv_get_max_vmv_range(StdVideoH264LevelIdc level)
32 {
33    int max_vmv_range;
34 
35    switch(level) {
36    case STD_VIDEO_H264_LEVEL_IDC_1_0:
37       max_vmv_range = 256;
38       break;
39    case STD_VIDEO_H264_LEVEL_IDC_1_1:
40    case STD_VIDEO_H264_LEVEL_IDC_1_2:
41    case STD_VIDEO_H264_LEVEL_IDC_1_3:
42    case STD_VIDEO_H264_LEVEL_IDC_2_0:
43       max_vmv_range = 512;
44       break;
45    case STD_VIDEO_H264_LEVEL_IDC_2_1:
46    case STD_VIDEO_H264_LEVEL_IDC_2_2:
47    case STD_VIDEO_H264_LEVEL_IDC_3_0:
48       max_vmv_range = 1024;
49       break;
50 
51    case STD_VIDEO_H264_LEVEL_IDC_3_1:
52    case STD_VIDEO_H264_LEVEL_IDC_3_2:
53    case STD_VIDEO_H264_LEVEL_IDC_4_0:
54    case STD_VIDEO_H264_LEVEL_IDC_4_1:
55    case STD_VIDEO_H264_LEVEL_IDC_4_2:
56    case STD_VIDEO_H264_LEVEL_IDC_5_0:
57    case STD_VIDEO_H264_LEVEL_IDC_5_1:
58    case STD_VIDEO_H264_LEVEL_IDC_5_2:
59    case STD_VIDEO_H264_LEVEL_IDC_6_0:
60    case STD_VIDEO_H264_LEVEL_IDC_6_1:
61    case STD_VIDEO_H264_LEVEL_IDC_6_2:
62    default:
63       max_vmv_range = 2048;
64       break;
65    }
66 
67    return max_vmv_range;
68 }
69 
70 static bool
anv_post_deblock_enable(const StdVideoH264PictureParameterSet * pps,const VkVideoEncodeH264PictureInfoKHR * frame_info)71 anv_post_deblock_enable(const StdVideoH264PictureParameterSet *pps, const VkVideoEncodeH264PictureInfoKHR *frame_info)
72 {
73 
74    if (!pps->flags.deblocking_filter_control_present_flag)
75       return true;
76 
77    for (uint32_t slice_id = 0; slice_id < frame_info->naluSliceEntryCount; slice_id++) {
78       const VkVideoEncodeH264NaluSliceInfoKHR *nalu = &frame_info->pNaluSliceEntries[slice_id];
79       const StdVideoEncodeH264SliceHeader *slice_header = nalu->pStdSliceHeader;
80 
81       if (slice_header->disable_deblocking_filter_idc != 1)
82          return true;
83    }
84 
85    return false;
86 }
87 
88 static uint8_t
anv_vdenc_h264_picture_type(StdVideoH264PictureType pic_type)89 anv_vdenc_h264_picture_type(StdVideoH264PictureType pic_type)
90 {
91    if (pic_type == STD_VIDEO_H264_PICTURE_TYPE_I || pic_type == STD_VIDEO_H264_PICTURE_TYPE_IDR) {
92       return 0;
93    } else {
94       return 1;
95    }
96 }
97 
98 static uint8_t
anv_vdenc_h265_picture_type(StdVideoH265PictureType pic_type)99 anv_vdenc_h265_picture_type(StdVideoH265PictureType pic_type)
100 {
101    if (pic_type == STD_VIDEO_H265_PICTURE_TYPE_I || pic_type == STD_VIDEO_H265_PICTURE_TYPE_IDR) {
102       return 0;
103    } else {
104       return 2;
105    }
106 }
107 
108 static const uint8_t vdenc_const_qp_lambda[42] = {
109    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
110    0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07,
111    0x07, 0x08, 0x09, 0x0a, 0x0c, 0x0d, 0x0f, 0x11, 0x13, 0x15,
112    0x17, 0x1a, 0x1e, 0x21, 0x25, 0x2a, 0x2f, 0x35, 0x3b, 0x42,
113    0x4a, 0x53,
114 };
115 
116 /* P frame */
117 static const uint8_t vdenc_const_qp_lambda_p[42] = {
118    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
119    0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07,
120    0x07, 0x08, 0x09, 0x0a, 0x0c, 0x0d, 0x0f, 0x11, 0x13, 0x15,
121    0x17, 0x1a, 0x1e, 0x21, 0x25, 0x2a, 0x2f, 0x35, 0x3b, 0x42,
122    0x4a, 0x53,
123 };
124 
125 static const uint16_t vdenc_const_skip_threshold_p[27] = {
126    0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0004, 0x0007, 0x000b,
127    0x0011, 0x0019, 0x0023, 0x0032, 0x0044, 0x005b, 0x0077, 0x0099,
128    0x00c2, 0x00f1, 0x0128, 0x0168, 0x01b0, 0x0201, 0x025c, 0x02c2,
129    0x0333, 0x03b0, 0x0000,
130 };
131 
132 static const uint16_t vdenc_const_sic_forward_transform_coeff_threshold_0_p[27] = {
133    0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0e,
134    0x12, 0x14, 0x18, 0x1d, 0x20, 0x25, 0x2a, 0x34, 0x39, 0x3f,
135    0x4e, 0x51, 0x5b, 0x63, 0x6f, 0x7f, 0x00,
136 };
137 
138 static const uint8_t vdenc_const_sic_forward_transform_coeff_threshold_1_p[27] = {
139    0x03, 0x04, 0x05, 0x05, 0x07, 0x09, 0x0b, 0x0e, 0x12, 0x17,
140    0x1c, 0x21, 0x27, 0x2c, 0x33, 0x3b, 0x41, 0x51, 0x5c, 0x1a,
141    0x1e, 0x21, 0x22, 0x26, 0x2c, 0x30, 0x00,
142 };
143 
144 static const uint8_t vdenc_const_sic_forward_transform_coeff_threshold_2_p[27] = {
145    0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x0e,
146    0x12, 0x14, 0x18, 0x1d, 0x20, 0x25, 0x2a, 0x34, 0x39, 0x0f,
147    0x13, 0x14, 0x16, 0x18, 0x1b, 0x1f, 0x00,
148 };
149 
150 static const uint8_t vdenc_const_sic_forward_transform_coeff_threshold_3_p[27] = {
151    0x04, 0x05, 0x06, 0x09, 0x0b, 0x0d, 0x12, 0x16, 0x1b, 0x23,
152    0x2c, 0x33, 0x3d, 0x45, 0x4f, 0x5b, 0x66, 0x7f, 0x8e, 0x2a,
153    0x2f, 0x32, 0x37, 0x3c, 0x45, 0x4c, 0x00,
154 };
155 
156 static const int vdenc_mode_const[2][12][52] = {
157     //INTRASLICE
158     {
159         //LUTMODE_INTRA_NONPRED
160         {
161             14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,         //QP=[0 ~12]
162             16, 18, 22, 24, 13, 15, 16, 18, 13, 15, 15, 12, 14,         //QP=[13~25]
163             12, 12, 10, 10, 11, 10, 10, 10, 9, 9, 8, 8, 8,              //QP=[26~38]
164             8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7,                      //QP=[39~51]
165         },
166 
167         //LUTMODE_INTRA_16x16, LUTMODE_INTRA
168         {
169             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[0 ~12]
170             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[13~25]
171             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[26~38]
172             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[39~51]
173         },
174 
175         //LUTMODE_INTRA_8x8
176         {
177             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  //QP=[0 ~12]
178             0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,  //QP=[13~25]
179             1, 1, 1, 1, 1, 4, 4, 4, 4, 6, 6, 6, 6,  //QP=[26~38]
180             6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7,  //QP=[39~51]
181         },
182 
183         //LUTMODE_INTRA_4x4
184         {
185             56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,   //QP=[0 ~12]
186             64, 72, 80, 88, 48, 56, 64, 72, 53, 59, 64, 56, 64,   //QP=[13~25]
187             57, 64, 58, 55, 64, 64, 64, 64, 59, 59, 60, 57, 50,   //QP=[26~38]
188             46, 42, 38, 34, 31, 27, 23, 22, 19, 18, 16, 14, 13,   //QP=[39~51]
189         },
190 
191         //LUTMODE_INTER_16x8, LUTMODE_INTER_8x16
192         { 0, },
193 
194         //LUTMODE_INTER_8X8Q
195         { 0, },
196 
197         //LUTMODE_INTER_8X4Q, LUTMODE_INTER_4X8Q, LUTMODE_INTER_16x8_FIELD
198         { 0, },
199 
200         //LUTMODE_INTER_4X4Q, LUTMODE_INTER_8X8_FIELD
201         { 0, },
202 
203         //LUTMODE_INTER_16x16, LUTMODE_INTER
204         { 0, },
205 
206         //LUTMODE_INTER_BWD
207         { 0, },
208 
209         //LUTMODE_REF_ID
210         { 0, },
211 
212         //LUTMODE_INTRA_CHROMA
213         { 0, },
214     },
215 
216     //PREDSLICE
217     {
218         //LUTMODE_INTRA_NONPRED
219         {
220             6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,     //QP=[0 ~12]
221             7, 8, 9, 10, 5, 6, 7, 8, 6, 7, 7, 7, 7,    //QP=[13~25]
222             6, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7,     //QP=[26~38]
223             7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,     //QP=[39~51]
224         },
225 
226         //LUTMODE_INTRA_16x16, LUTMODE_INTRA
227         {
228             21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
229             24, 28, 31, 35, 19, 21, 24, 28, 20, 24, 25, 21, 24,
230             24, 24, 24, 21, 24, 24, 26, 24, 24, 24, 24, 24, 24,
231             24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
232 
233         },
234 
235         //LUTMODE_INTRA_8x8
236         {
237             26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,   //QP=[0 ~12]
238             28, 32, 36, 40, 22, 26, 28, 32, 24, 26, 30, 26, 28,   //QP=[13~25]
239             26, 28, 26, 26, 30, 28, 28, 28, 26, 28, 28, 26, 28,   //QP=[26~38]
240             28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,   //QP=[39~51]
241         },
242 
243         //LUTMODE_INTRA_4x4
244         {
245             64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,   //QP=[0 ~12]
246             72, 80, 88, 104, 56, 64, 72, 80, 58, 68, 76, 64, 68,  //QP=[13~25]
247             64, 68, 68, 64, 70, 70, 70, 70, 68, 68, 68, 68, 68,   //QP=[26~38]
248             68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,   //QP=[39~51]
249         },
250 
251         //LUTMODE_INTER_16x8, LUTMODE_INTER_8x16
252         {
253             7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,      //QP=[0 ~12]
254             8, 9, 11, 12, 6, 7, 9, 10, 7, 8, 9, 8, 9,   //QP=[13~25]
255             8, 9, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8,      //QP=[26~38]
256             8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,      //QP=[39~51]
257         },
258 
259         //LUTMODE_INTER_8X8Q
260         {
261             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,   //QP=[0 ~12]
262             2, 3, 3, 3, 2, 2, 2, 3, 2, 2, 2, 2, 3,   //QP=[13~25]
263             2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,   //QP=[26~38]
264             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,   //QP=[39~51]
265         },
266 
267         //LUTMODE_INTER_8X4Q, LUTMODE_INTER_4X8Q, LUTMODE_INTER_16X8_FIELD
268         {
269             5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,   //QP=[0 ~12]
270             5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,   //QP=[13~25]
271             5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,   //QP=[26~38]
272             5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,   //QP=[39~51]
273         },
274 
275         //LUTMODE_INTER_4X4Q, LUTMODE_INTER_8x8_FIELD
276         {
277             7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,   //QP=[0 ~12]
278             7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,   //QP=[13~25]
279             7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,   //QP=[26~38]
280             7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,   //QP=[39~51]
281         },
282 
283         //LUTMODE_INTER_16x16, LUTMODE_INTER
284         {
285             5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,   //QP=[0 ~12]
286             6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,   //QP=[13~25]
287             6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,   //QP=[26~38]
288             6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,   //QP=[39~51]
289         },
290 
291         //LUTMODE_INTER_BWD
292         {
293             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[0 ~12]
294             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[13~25]
295             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[26~38]
296             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[39~51]
297         },
298 
299         //LUTMODE_REF_ID
300         {
301             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,    //QP=[0 ~12]
302             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,    //QP=[13~25]
303             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,    //QP=[26~38]
304             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,    //QP=[39~51]
305         },
306 
307         //LUTMODE_INTRA_CHROMA
308         {
309             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[0 ~12]
310             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[13~25]
311             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[26~38]
312             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    //QP=[39~51]
313         },
314     },
315 };
316 
317 
318 #define VDENC_LUTMODE_INTRA_NONPRED             0x00
319 #define VDENC_LUTMODE_INTRA                     0x01
320 #define VDENC_LUTMODE_INTRA_16x16               0x01
321 #define VDENC_LUTMODE_INTRA_8x8                 0x02
322 #define VDENC_LUTMODE_INTRA_4x4                 0x03
323 #define VDENC_LUTMODE_INTER_16x8                0x04
324 #define VDENC_LUTMODE_INTER_8x16                0x04
325 #define VDENC_LUTMODE_INTER_8X8Q                0x05
326 #define VDENC_LUTMODE_INTER_8X4Q                0x06
327 #define VDENC_LUTMODE_INTER_4X8Q                0x06
328 #define VDENC_LUTMODE_INTER_16x8_FIELD          0x06
329 #define VDENC_LUTMODE_INTER_4X4Q                0x07
330 #define VDENC_LUTMODE_INTER_8x8_FIELD           0x07
331 #define VDENC_LUTMODE_INTER                     0x08
332 #define VDENC_LUTMODE_INTER_16x16               0x08
333 #define VDENC_LUTMODE_INTER_BWD                 0x09
334 #define VDENC_LUTMODE_REF_ID                    0x0A
335 #define VDENC_LUTMODE_INTRA_CHROMA              0x0B
336 
337 static unsigned char
map_44_lut_value(unsigned int v,unsigned char max)338 map_44_lut_value(unsigned int v, unsigned char max)
339 {
340     unsigned int maxcost;
341     int d;
342     unsigned char ret;
343 
344     if (v == 0) {
345         return 0;
346     }
347 
348     maxcost = ((max & 15) << (max >> 4));
349 
350     if (v >= maxcost) {
351         return max;
352     }
353 
354     d = (int)(log((double)v) / log(2.0)) - 3;
355 
356     if (d < 0) {
357         d = 0;
358     }
359 
360     ret = (unsigned char)((d << 4) + (int)((v + (d == 0 ? 0 : (1 << (d - 1)))) >> d));
361     ret = (ret & 0xf) == 0 ? (ret | 8) : ret;
362 
363     return ret;
364 }
365 
update_costs(uint8_t * mode_cost,uint8_t * mv_cost,uint8_t * hme_mv_cost,int qp,StdVideoH264PictureType pic_type)366 static void update_costs(uint8_t *mode_cost, uint8_t *mv_cost, uint8_t *hme_mv_cost, int qp, StdVideoH264PictureType pic_type)
367 {
368    int frame_type = anv_vdenc_h264_picture_type(pic_type);
369 
370    memset(mode_cost, 0, 12 * sizeof(uint8_t));
371    memset(mv_cost, 0, 8 * sizeof(uint8_t));
372    memset(hme_mv_cost, 0, 8 * sizeof(uint8_t));
373 
374    mode_cost[VDENC_LUTMODE_INTRA_NONPRED] = map_44_lut_value((uint32_t)(vdenc_mode_const[frame_type][VDENC_LUTMODE_INTRA_NONPRED][qp]), 0x6f);
375    mode_cost[VDENC_LUTMODE_INTRA_16x16] = map_44_lut_value((uint32_t)(vdenc_mode_const[frame_type][VDENC_LUTMODE_INTRA_16x16][qp]), 0x8f);
376    mode_cost[VDENC_LUTMODE_INTRA_8x8] = map_44_lut_value((uint32_t)(vdenc_mode_const[frame_type][VDENC_LUTMODE_INTRA_8x8][qp]), 0x8f);
377    mode_cost[VDENC_LUTMODE_INTRA_4x4] = map_44_lut_value((uint32_t)(vdenc_mode_const[frame_type][VDENC_LUTMODE_INTRA_4x4][qp]), 0x8f);
378 }
379 
380 static void
anv_h264_encode_video(struct anv_cmd_buffer * cmd,const VkVideoEncodeInfoKHR * enc_info)381 anv_h264_encode_video(struct anv_cmd_buffer *cmd, const VkVideoEncodeInfoKHR *enc_info)
382 {
383    ANV_FROM_HANDLE(anv_buffer, dst_buffer, enc_info->dstBuffer);
384 
385    struct anv_video_session *vid = cmd->video.vid;
386    struct anv_video_session_params *params = cmd->video.params;
387 
388    const struct VkVideoEncodeH264PictureInfoKHR *frame_info =
389       vk_find_struct_const(enc_info->pNext, VIDEO_ENCODE_H264_PICTURE_INFO_KHR);
390 
391    const StdVideoH264SequenceParameterSet *sps = vk_video_find_h264_enc_std_sps(&params->vk, frame_info->pStdPictureInfo->seq_parameter_set_id);
392    const StdVideoH264PictureParameterSet *pps = vk_video_find_h264_enc_std_pps(&params->vk, frame_info->pStdPictureInfo->pic_parameter_set_id);
393    const StdVideoEncodeH264ReferenceListsInfo *ref_list_info = frame_info->pStdPictureInfo->pRefLists;
394 
395    const struct anv_image_view *iv = anv_image_view_from_handle(enc_info->srcPictureResource.imageViewBinding);
396    const struct anv_image *src_img = iv->image;
397    bool post_deblock_enable = anv_post_deblock_enable(pps, frame_info);
398    bool rc_disable = cmd->video.params->rc_mode == VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
399    uint8_t dpb_idx[ANV_VIDEO_H264_MAX_NUM_REF_FRAME] = { 0,};
400 
401    const struct anv_image_view *base_ref_iv;
402    if (enc_info->pSetupReferenceSlot) {
403       base_ref_iv = anv_image_view_from_handle(enc_info->pSetupReferenceSlot->pPictureResource->imageViewBinding);
404    } else {
405       base_ref_iv = iv;
406    }
407 
408    const struct anv_image *base_ref_img = base_ref_iv->image;
409 
410    anv_batch_emit(&cmd->batch, GENX(MI_FLUSH_DW), flush) {
411       flush.VideoPipelineCacheInvalidate = 1;
412    };
413 
414 #if GFX_VER >= 12
415    anv_batch_emit(&cmd->batch, GENX(MI_FORCE_WAKEUP), wake) {
416       wake.MFXPowerWellControl = 1;
417       wake.MaskBits = 768;
418    }
419 
420    anv_batch_emit(&cmd->batch, GENX(MFX_WAIT), mfx) {
421       mfx.MFXSyncControlFlag = 1;
422    }
423 #endif
424 
425    anv_batch_emit(&cmd->batch, GENX(MFX_PIPE_MODE_SELECT), pipe_mode) {
426       pipe_mode.StandardSelect = SS_AVC;
427       pipe_mode.CodecSelect = Encode;
428       pipe_mode.FrameStatisticsStreamOutEnable = true;
429       pipe_mode.ScaledSurfaceEnable = false;
430       pipe_mode.PreDeblockingOutputEnable = !post_deblock_enable;
431       pipe_mode.PostDeblockingOutputEnable = post_deblock_enable;
432       pipe_mode.StreamOutEnable = false;
433       pipe_mode.VDEncMode = VM_VDEncMode;
434       pipe_mode.DecoderShortFormatMode = LongFormatDriverInterface;
435    }
436 
437 #if GFX_VER >= 12
438    anv_batch_emit(&cmd->batch, GENX(MFX_WAIT), mfx) {
439       mfx.MFXSyncControlFlag = 1;
440    }
441 #endif
442 
443    for (uint32_t i = 0; i < 2; i++) {
444       anv_batch_emit(&cmd->batch, GENX(MFX_SURFACE_STATE), surface) {
445          const struct anv_image *img_ = i == 0 ? base_ref_img : src_img;
446 
447          surface.Width = img_->vk.extent.width - 1;
448          surface.Height = img_->vk.extent.height - 1;
449          /* TODO. add a surface for MFX_ReconstructedScaledReferencePicture */
450          surface.SurfaceID = i == 0 ? MFX_ReferencePicture : MFX_SourceInputPicture;
451          surface.TileWalk = TW_YMAJOR;
452          surface.TiledSurface = img_->planes[0].primary_surface.isl.tiling != ISL_TILING_LINEAR;
453          surface.SurfacePitch = img_->planes[0].primary_surface.isl.row_pitch_B - 1;
454          surface.InterleaveChroma = true;
455          surface.SurfaceFormat = MFX_PLANAR_420_8;
456 
457          surface.YOffsetforUCb = img_->planes[1].primary_surface.memory_range.offset /
458             img_->planes[0].primary_surface.isl.row_pitch_B;
459          surface.YOffsetforVCr = img_->planes[1].primary_surface.memory_range.offset /
460             img_->planes[0].primary_surface.isl.row_pitch_B;
461       }
462    }
463 
464    anv_batch_emit(&cmd->batch, GENX(MFX_PIPE_BUF_ADDR_STATE), buf) {
465       if (post_deblock_enable) {
466          buf.PostDeblockingDestinationAddress =
467             anv_image_address(base_ref_img, &base_ref_img->planes[0].primary_surface.memory_range);
468       } else {
469          buf.PreDeblockingDestinationAddress =
470             anv_image_address(base_ref_img, &base_ref_img->planes[0].primary_surface.memory_range);
471       }
472       buf.PreDeblockingDestinationAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
473          .MOCS = anv_mocs(cmd->device, buf.PreDeblockingDestinationAddress.bo, 0),
474       };
475       buf.PostDeblockingDestinationAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
476          .MOCS = anv_mocs(cmd->device, buf.PostDeblockingDestinationAddress.bo, 0),
477       };
478 
479       buf.OriginalUncompressedPictureSourceAddress =
480          anv_image_address(src_img, &src_img->planes[0].primary_surface.memory_range);
481       buf.OriginalUncompressedPictureSourceAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
482          .MOCS = anv_mocs(cmd->device, buf.OriginalUncompressedPictureSourceAddress.bo, 0),
483       };
484 
485       buf.StreamOutDataDestinationAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
486          .MOCS = anv_mocs(cmd->device, NULL, 0),
487       };
488 
489       buf.IntraRowStoreScratchBufferAddress = (struct anv_address) {
490          vid->vid_mem[ANV_VID_MEM_H264_INTRA_ROW_STORE].mem->bo,
491          vid->vid_mem[ANV_VID_MEM_H264_INTRA_ROW_STORE].offset
492       };
493       buf.IntraRowStoreScratchBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
494          .MOCS = anv_mocs(cmd->device, buf.IntraRowStoreScratchBufferAddress.bo, 0),
495       };
496 
497       buf.DeblockingFilterRowStoreScratchAddress = (struct anv_address) {
498          vid->vid_mem[ANV_VID_MEM_H264_DEBLOCK_FILTER_ROW_STORE].mem->bo,
499          vid->vid_mem[ANV_VID_MEM_H264_DEBLOCK_FILTER_ROW_STORE].offset
500       };
501       buf.DeblockingFilterRowStoreScratchAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
502          .MOCS = anv_mocs(cmd->device, buf.DeblockingFilterRowStoreScratchAddress.bo, 0),
503       };
504 
505       struct anv_bo *ref_bo = NULL;
506 
507       for (unsigned i = 0; i < enc_info->referenceSlotCount; i++) {
508          const struct anv_image_view *ref_iv =
509             anv_image_view_from_handle(enc_info->pReferenceSlots[i].pPictureResource->imageViewBinding);
510          int slot_idx = enc_info->pReferenceSlots[i].slotIndex;
511          assert(slot_idx < ANV_VIDEO_H264_MAX_NUM_REF_FRAME);
512 
513          dpb_idx[slot_idx] = i;
514 
515          buf.ReferencePictureAddress[i] =
516             anv_image_address(ref_iv->image, &ref_iv->image->planes[0].primary_surface.memory_range);
517 
518          if (i == 0)
519             ref_bo = ref_iv->image->bindings[0].address.bo;
520       }
521 
522       buf.ReferencePictureAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
523          .MOCS = anv_mocs(cmd->device, ref_bo, 0),
524       };
525 
526       buf.MBStatusBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
527          .MOCS = anv_mocs(cmd->device, NULL, 0),
528       };
529 
530       buf.MBILDBStreamOutBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
531          .MOCS = anv_mocs(cmd->device, NULL, 0),
532       };
533       buf.SecondMBILDBStreamOutBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
534          .MOCS = anv_mocs(cmd->device, NULL, 0),
535       };
536 
537       /* TODO. Add for scaled reference surface */
538       buf.ScaledReferenceSurfaceAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
539          .MOCS = anv_mocs(cmd->device, buf.ScaledReferenceSurfaceAddress.bo, 0),
540       };
541    }
542 
543    anv_batch_emit(&cmd->batch, GENX(MFX_IND_OBJ_BASE_ADDR_STATE), index_obj) {
544       index_obj.MFXIndirectBitstreamObjectAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
545          .MOCS = anv_mocs(cmd->device, NULL, 0),
546       };
547       index_obj.MFXIndirectMVObjectAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
548          .MOCS = anv_mocs(cmd->device, NULL, 0),
549       };
550       index_obj.MFDIndirectITCOEFFObjectAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
551          .MOCS = anv_mocs(cmd->device, NULL, 0),
552       };
553       index_obj.MFDIndirectITDBLKObjectAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
554          .MOCS = anv_mocs(cmd->device, NULL, 0),
555       };
556 
557       index_obj.MFCIndirectPAKBSEObjectAddress = anv_address_add(dst_buffer->address, 0);
558 
559       index_obj.MFCIndirectPAKBSEObjectAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
560          .MOCS = anv_mocs(cmd->device, index_obj.MFCIndirectPAKBSEObjectAddress.bo, 0),
561       };
562    }
563 
564    anv_batch_emit(&cmd->batch, GENX(MFX_BSP_BUF_BASE_ADDR_STATE), bsp) {
565       bsp.BSDMPCRowStoreScratchBufferAddress = (struct anv_address) {
566          vid->vid_mem[ANV_VID_MEM_H264_BSD_MPC_ROW_SCRATCH].mem->bo,
567          vid->vid_mem[ANV_VID_MEM_H264_BSD_MPC_ROW_SCRATCH].offset
568       };
569 
570       bsp.BSDMPCRowStoreScratchBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
571          .MOCS = anv_mocs(cmd->device, bsp.BSDMPCRowStoreScratchBufferAddress.bo, 0),
572       };
573 
574       bsp.MPRRowStoreScratchBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
575          .MOCS = anv_mocs(cmd->device, NULL, 0),
576       };
577 
578       bsp.BitplaneReadBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
579          .MOCS = anv_mocs(cmd->device, NULL, 0),
580       };
581    }
582 
583    anv_batch_emit(&cmd->batch, GENX(VDENC_PIPE_MODE_SELECT), vdenc_pipe_mode) {
584       vdenc_pipe_mode.StandardSelect = SS_AVC;
585       vdenc_pipe_mode.PAKChromaSubSamplingType = _420;
586 #if GFX_VER >= 12
587       //vdenc_pipe_mode.HMERegionPrefetchEnable = !vdenc_pipe_mode.TLBPrefetchEnable;
588       vdenc_pipe_mode.SourceLumaPackedDataTLBPrefetchEnable = true;
589       vdenc_pipe_mode.SourceChromaTLBPrefetchEnable = true;
590       vdenc_pipe_mode.HzShift32Minus1Src = 3;
591       vdenc_pipe_mode.PrefetchOffsetforSource = 4;
592 #endif
593    }
594 
595    anv_batch_emit(&cmd->batch, GENX(VDENC_SRC_SURFACE_STATE), vdenc_surface) {
596       vdenc_surface.SurfaceState.Width = src_img->vk.extent.width - 1;
597       vdenc_surface.SurfaceState.Height = src_img->vk.extent.height - 1;
598       vdenc_surface.SurfaceState.SurfaceFormat = VDENC_PLANAR_420_8;
599       vdenc_surface.SurfaceState.SurfacePitch = src_img->planes[0].primary_surface.isl.row_pitch_B - 1;
600 
601 #if GFX_VER == 9
602       vdenc_surface.SurfaceState.InterleaveChroma = true;
603 #endif
604 
605       vdenc_surface.SurfaceState.TileWalk = TW_YMAJOR;
606       vdenc_surface.SurfaceState.TiledSurface = src_img->planes[0].primary_surface.isl.tiling != ISL_TILING_LINEAR;
607       vdenc_surface.SurfaceState.YOffsetforUCb = src_img->planes[1].primary_surface.memory_range.offset /
608          src_img->planes[0].primary_surface.isl.row_pitch_B;
609       vdenc_surface.SurfaceState.YOffsetforVCr = src_img->planes[1].primary_surface.memory_range.offset /
610          src_img->planes[0].primary_surface.isl.row_pitch_B;
611       vdenc_surface.SurfaceState.Colorspaceselection = 1;
612    }
613 
614    anv_batch_emit(&cmd->batch, GENX(VDENC_REF_SURFACE_STATE), vdenc_surface) {
615       vdenc_surface.SurfaceState.Width = base_ref_img->vk.extent.width - 1;
616       vdenc_surface.SurfaceState.Height = base_ref_img->vk.extent.height - 1;
617       vdenc_surface.SurfaceState.SurfaceFormat = VDENC_PLANAR_420_8;
618 #if GFX_VER == 9
619       vdenc_surface.SurfaceState.InterleaveChroma = true;
620 #endif
621       vdenc_surface.SurfaceState.SurfacePitch = base_ref_img->planes[0].primary_surface.isl.row_pitch_B - 1;
622 
623       vdenc_surface.SurfaceState.TileWalk = TW_YMAJOR;
624       vdenc_surface.SurfaceState.TiledSurface = base_ref_img->planes[0].primary_surface.isl.tiling != ISL_TILING_LINEAR;
625       vdenc_surface.SurfaceState.YOffsetforUCb = base_ref_img->planes[1].primary_surface.memory_range.offset /
626          base_ref_img->planes[0].primary_surface.isl.row_pitch_B;
627       vdenc_surface.SurfaceState.YOffsetforVCr = base_ref_img->planes[1].primary_surface.memory_range.offset /
628          base_ref_img->planes[0].primary_surface.isl.row_pitch_B;
629    }
630 
631    /* TODO. add a cmd for VDENC_DS_REF_SURFACE_STATE */
632 
633    anv_batch_emit(&cmd->batch, GENX(VDENC_PIPE_BUF_ADDR_STATE), vdenc_buf) {
634       /* TODO. add DSFWDREF and FWDREF */
635       vdenc_buf.DSFWDREF0.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
636          .MOCS = anv_mocs(cmd->device, NULL, 0),
637       };
638 
639       vdenc_buf.DSFWDREF1.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
640          .MOCS = anv_mocs(cmd->device, NULL, 0),
641       };
642 
643       vdenc_buf.OriginalUncompressedPicture.Address =
644          anv_image_address(src_img, &src_img->planes[0].primary_surface.memory_range);
645       vdenc_buf.OriginalUncompressedPicture.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
646          .MOCS = anv_mocs(cmd->device, vdenc_buf.OriginalUncompressedPicture.Address.bo, 0),
647       };
648 
649       vdenc_buf.StreamInDataPicture.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
650          .MOCS = anv_mocs(cmd->device, NULL, 0),
651       };
652 
653       vdenc_buf.RowStoreScratchBuffer.Address = (struct anv_address) {
654          vid->vid_mem[ANV_VID_MEM_H264_MPR_ROW_SCRATCH].mem->bo,
655          vid->vid_mem[ANV_VID_MEM_H264_MPR_ROW_SCRATCH].offset
656       };
657 
658       vdenc_buf.RowStoreScratchBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
659          .MOCS = anv_mocs(cmd->device, vdenc_buf.RowStoreScratchBuffer.Address.bo, 0),
660       };
661 
662       const struct anv_image_view *ref_iv[2] = { 0, };
663       for (unsigned i = 0; i < enc_info->referenceSlotCount && i < 2; i++)
664          ref_iv[i] = anv_image_view_from_handle(enc_info->pReferenceSlots[i].pPictureResource->imageViewBinding);
665 
666       if (ref_iv[0]) {
667          vdenc_buf.ColocatedMVReadBuffer.Address =
668                anv_image_address(ref_iv[0]->image, &ref_iv[0]->image->vid_dmv_top_surface);
669          vdenc_buf.FWDREF0.Address =
670                anv_image_address(ref_iv[0]->image, &ref_iv[0]->image->planes[0].primary_surface.memory_range);
671       }
672 
673       vdenc_buf.ColocatedMVReadBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
674          .MOCS = anv_mocs(cmd->device, vdenc_buf.ColocatedMVReadBuffer.Address.bo, 0),
675       };
676 
677       vdenc_buf.FWDREF0.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
678          .MOCS = anv_mocs(cmd->device, vdenc_buf.FWDREF0.Address.bo, 0),
679       };
680 
681       if (ref_iv[1])
682          vdenc_buf.FWDREF1.Address =
683                anv_image_address(ref_iv[1]->image, &ref_iv[1]->image->planes[0].primary_surface.memory_range);
684 
685       vdenc_buf.FWDREF1.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
686          .MOCS = anv_mocs(cmd->device, vdenc_buf.FWDREF1.Address.bo, 0),
687       };
688 
689       vdenc_buf.FWDREF2.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
690          .MOCS = anv_mocs(cmd->device, NULL, 0),
691       };
692 
693       vdenc_buf.BWDREF0.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
694          .MOCS = anv_mocs(cmd->device, NULL, 0),
695       };
696 
697       vdenc_buf.VDEncStatisticsStreamOut.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
698          .MOCS = anv_mocs(cmd->device, NULL, 0),
699       };
700 
701 #if GFX_VER >= 11
702       vdenc_buf.DSFWDREF04X.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
703          .MOCS = anv_mocs(cmd->device, NULL, 0),
704       };
705       vdenc_buf.DSFWDREF14X.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
706          .MOCS = anv_mocs(cmd->device, NULL, 0),
707       };
708       vdenc_buf.VDEncCURecordStreamOutBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
709          .MOCS = anv_mocs(cmd->device, NULL, 0),
710       };
711       vdenc_buf.VDEncLCUPAK_OBJ_CMDBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
712          .MOCS = anv_mocs(cmd->device, NULL, 0),
713       };
714       vdenc_buf.ScaledReferenceSurface8X.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
715          .MOCS = anv_mocs(cmd->device, NULL, 0),
716       };
717       vdenc_buf.ScaledReferenceSurface4X.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
718          .MOCS = anv_mocs(cmd->device, NULL, 0),
719       };
720       vdenc_buf.VP9SegmentationMapStreamInBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
721          .MOCS = anv_mocs(cmd->device, NULL, 0),
722       };
723       vdenc_buf.VP9SegmentationMapStreamOutBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
724          .MOCS = anv_mocs(cmd->device, NULL, 0),
725       };
726 #endif
727 #if GFX_VER >= 12
728       vdenc_buf.VDEncTileRowStoreBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
729          .MOCS = anv_mocs(cmd->device, NULL, 0),
730       };
731       vdenc_buf.VDEncCumulativeCUCountStreamOutSurface.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
732          .MOCS = anv_mocs(cmd->device, NULL, 0),
733       };
734       vdenc_buf.VDEncPaletteModeStreamOutSurface.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
735          .MOCS = anv_mocs(cmd->device, NULL, 0),
736       };
737 #endif
738    }
739 
740    StdVideoH264PictureType pic_type;
741 
742    pic_type = frame_info->pStdPictureInfo->primary_pic_type;
743 
744    anv_batch_emit(&cmd->batch, GENX(VDENC_CONST_QPT_STATE), qpt) {
745       if (pic_type == STD_VIDEO_H264_PICTURE_TYPE_IDR || pic_type == STD_VIDEO_H264_PICTURE_TYPE_I) {
746          for (uint32_t i = 0; i < 42; i++) {
747             qpt.QPLambdaArrayIndex[i] = vdenc_const_qp_lambda[i];
748          }
749       } else {
750          for (uint32_t i = 0; i < 42; i++) {
751             qpt.QPLambdaArrayIndex[i] = vdenc_const_qp_lambda_p[i];
752          }
753 
754          for (uint32_t i = 0; i < 27; i++) {
755             qpt.SkipThresholdArrayIndex[i] = vdenc_const_skip_threshold_p[i];
756             qpt.SICForwardTransformCoeffThresholdMatrix0ArrayIndex[i] = vdenc_const_sic_forward_transform_coeff_threshold_0_p[i];
757             qpt.SICForwardTransformCoeffThresholdMatrix135ArrayIndex[i] = vdenc_const_sic_forward_transform_coeff_threshold_1_p[i];
758             qpt.SICForwardTransformCoeffThresholdMatrix2ArrayIndex[i] = vdenc_const_sic_forward_transform_coeff_threshold_2_p[i];
759             qpt.SICForwardTransformCoeffThresholdMatrix46ArrayIndex[i] = vdenc_const_sic_forward_transform_coeff_threshold_3_p[i];
760          }
761 
762          if (!pps->flags.transform_8x8_mode_flag) {
763             for (uint32_t i = 0; i < 27; i++) {
764                qpt.SkipThresholdArrayIndex[i] /= 2;
765             }
766          }
767       }
768    }
769 
770    anv_batch_emit(&cmd->batch, GENX(MFX_AVC_IMG_STATE), avc_img) {
771       avc_img.FrameWidth = sps->pic_width_in_mbs_minus1;
772       avc_img.FrameHeight = sps->pic_height_in_map_units_minus1;
773       avc_img.FrameSize = (avc_img.FrameWidth + 1) * (avc_img.FrameHeight + 1);
774       avc_img.ImageStructure = FramePicture;
775 
776       avc_img.WeightedBiPredictionIDC = pps->weighted_bipred_idc;
777       avc_img.WeightedPredictionEnable = pps->flags.weighted_pred_flag;
778       avc_img.RhoDomainRateControlEnable = false;
779       avc_img.FirstChromaQPOffset = pps->chroma_qp_index_offset;
780       avc_img.SecondChromaQPOffset = pps->second_chroma_qp_index_offset;
781 
782       avc_img.FieldPicture = false;
783       avc_img.MBAFFMode = sps->flags.mb_adaptive_frame_field_flag;
784       avc_img.FrameMBOnly = sps->flags.frame_mbs_only_flag;
785       avc_img._8x8IDCTTransformMode = pps->flags.transform_8x8_mode_flag;
786       avc_img.Direct8x8Inference = sps->flags.direct_8x8_inference_flag;
787       avc_img.ConstrainedIntraPrediction = pps->flags.constrained_intra_pred_flag;
788       avc_img.NonReferencePicture = false;
789       avc_img.EntropyCodingSyncEnable = pps->flags.entropy_coding_mode_flag;
790       avc_img.MBMVFormat = FOLLOW;
791       avc_img.ChromaFormatIDC = sps->chroma_format_idc;
792       avc_img.MVUnpackedEnable = true;
793 
794       avc_img.IntraMBMaxBitControl = true;
795       avc_img.InterMBMaxBitControl = true;
796       avc_img.FrameBitrateMaxReport = true;
797       avc_img.FrameBitrateMinReport = true;
798       avc_img.ForceIPCMControl = true;
799       avc_img.TrellisQuantizationChromaDisable = true;
800 
801       avc_img.IntraMBConformanceMaxSize = 2700;
802       avc_img.InterMBConformanceMaxSize = 4095;
803 
804       avc_img.FrameBitrateMin = 0;
805       avc_img.FrameBitrateMinUnitMode = 1;
806       avc_img.FrameBitrateMinUnit = 1;
807       avc_img.FrameBitrateMax = (1 << 14) - 1;
808       avc_img.FrameBitrateMaxUnitMode = 1;
809       avc_img.FrameBitrateMaxUnit = 1;
810 
811       avc_img.NumberofReferenceFrames = enc_info->referenceSlotCount;
812       if (pic_type != STD_VIDEO_H264_PICTURE_TYPE_IDR && pic_type != STD_VIDEO_H264_PICTURE_TYPE_I) {
813          avc_img.NumberofActiveReferencePicturesfromL0 = pps->num_ref_idx_l0_default_active_minus1 + 1;
814          avc_img.NumberofActiveReferencePicturesfromL1 = pps->num_ref_idx_l1_default_active_minus1 + 1;
815       }
816       avc_img.PicOrderPresent = pps->flags.bottom_field_pic_order_in_frame_present_flag;
817       avc_img.DeltaPicOrderAlwaysZero = sps->flags.delta_pic_order_always_zero_flag;
818       avc_img.PicOrderCountType = sps->pic_order_cnt_type;
819       avc_img.DeblockingFilterControlPresent = pps->flags.deblocking_filter_control_present_flag;
820       avc_img.RedundantPicCountPresent = pps->flags.redundant_pic_cnt_present_flag;
821       avc_img.Log2MaxFrameNumber = sps->log2_max_frame_num_minus4;
822       avc_img.Log2MaxPicOrderCountLSB = sps->log2_max_pic_order_cnt_lsb_minus4;
823    }
824 
825    uint8_t     mode_cost[12];
826    uint8_t     mv_cost[8];
827    uint8_t     hme_mv_cost[8];
828 
829    anv_batch_emit(&cmd->batch, GENX(VDENC_IMG_STATE), vdenc_img) {
830       uint32_t slice_qp = 0;
831       for (uint32_t slice_id = 0; slice_id < frame_info->naluSliceEntryCount; slice_id++) {
832          const VkVideoEncodeH264NaluSliceInfoKHR *nalu = &frame_info->pNaluSliceEntries[slice_id];
833          slice_qp = rc_disable ? nalu->constantQp : pps->pic_init_qp_minus26 + 26;
834       }
835 
836       update_costs(mode_cost, mv_cost, hme_mv_cost, slice_qp, pic_type);
837 
838       if (pic_type == STD_VIDEO_H264_PICTURE_TYPE_IDR || pic_type == STD_VIDEO_H264_PICTURE_TYPE_I) {
839          vdenc_img.IntraSADMeasureAdjustment = 2;
840          vdenc_img.SubMBSubPartitionMask = 0x70;
841          vdenc_img.CREPrefetchEnable = true;
842          vdenc_img.Mode0Cost = 10;
843          vdenc_img.Mode1Cost = 0;
844          vdenc_img.Mode2Cost = 3;
845          vdenc_img.Mode3Cost = 30;
846 
847       } else {
848          vdenc_img.BidirectionalWeight = 0x20;
849          vdenc_img.SubPelMode = 3;
850          vdenc_img.BmeDisableForFbrMessage = true;
851          vdenc_img.InterSADMeasureAdjustment = 2;
852          vdenc_img.IntraSADMeasureAdjustment = 2;
853          vdenc_img.SubMBSubPartitionMask = 0x70;
854          vdenc_img.CREPrefetchEnable = true;
855 
856          vdenc_img.NonSkipZeroMVCostAdded = 1;
857          vdenc_img.NonSkipMBModeCostAdded = 1;
858          vdenc_img.RefIDCostModeSelect = 1;
859 
860          vdenc_img.Mode0Cost = 7;
861          vdenc_img.Mode1Cost = 26;
862          vdenc_img.Mode2Cost = 30;
863          vdenc_img.Mode3Cost = 57;
864          vdenc_img.Mode4Cost = 8;
865          vdenc_img.Mode5Cost = 2;
866          vdenc_img.Mode6Cost = 4;
867          vdenc_img.Mode7Cost = 6;
868          vdenc_img.Mode8Cost = 5;
869          vdenc_img.Mode9Cost = 0;
870          vdenc_img.RefIDCost = 4;
871          vdenc_img.ChromaIntraModeCost = 0;
872 
873          vdenc_img.MVCost.MV0Cost = 0;
874          vdenc_img.MVCost.MV1Cost = 6;
875          vdenc_img.MVCost.MV2Cost = 6;
876          vdenc_img.MVCost.MV3Cost = 9;
877          vdenc_img.MVCost.MV4Cost = 10;
878          vdenc_img.MVCost.MV5Cost = 13;
879          vdenc_img.MVCost.MV6Cost = 14;
880          vdenc_img.MVCost.MV7Cost = 24;
881 
882          vdenc_img.SadHaarThreshold0 = 800;
883          vdenc_img.SadHaarThreshold1 = 1600;
884          vdenc_img.SadHaarThreshold2 = 2400;
885       }
886 
887       vdenc_img.PenaltyforIntra16x16NonDCPrediction = 36;
888       vdenc_img.PenaltyforIntra8x8NonDCPrediction = 12;
889       vdenc_img.PenaltyforIntra4x4NonDCPrediction = 4;
890       vdenc_img.MaxQP = 0x33;
891       vdenc_img.MinQP = 0x0a;
892       vdenc_img.MaxDeltaQP = 0x0f;
893       vdenc_img.MaxHorizontalMVRange = 0x2000;
894       vdenc_img.MaxVerticalMVRange = 0x200;
895       vdenc_img.SmallMbSizeInWord = 0xff;
896       vdenc_img.LargeMbSizeInWord = 0xff;
897 
898       vdenc_img.Transform8x8 = pps->flags.transform_8x8_mode_flag;
899       vdenc_img.VDEncExtendedPAK_OBJ_CMDEnable = true;
900       vdenc_img.PictureWidth = sps->pic_width_in_mbs_minus1 + 1;
901       vdenc_img.ForwardTransformSkipCheckEnable = true;
902       vdenc_img.BlockBasedSkipEnable = true;
903       vdenc_img.PictureHeight = sps->pic_height_in_map_units_minus1;
904       vdenc_img.PictureType = anv_vdenc_h264_picture_type(pic_type);
905       vdenc_img.ConstrainedIntraPrediction = pps->flags.constrained_intra_pred_flag;
906 
907       if (pic_type == STD_VIDEO_H264_PICTURE_TYPE_P) {
908          vdenc_img.HMERef1Disable =
909             (ref_list_info->num_ref_idx_l1_active_minus1 + 1) == 1 ? true : false;
910       }
911 
912       vdenc_img.SliceMBHeight = sps->pic_height_in_map_units_minus1;
913 
914       if (vdenc_img.Transform8x8) {
915          vdenc_img.LumaIntraPartitionMask = 0;
916       } else {
917          vdenc_img.LumaIntraPartitionMask = (1 << 1);
918       }
919 
920       vdenc_img.QpPrimeY = slice_qp;
921       vdenc_img.MaxVerticalMVRange = anv_get_max_vmv_range(sps->level_idc);
922 
923       /* TODO. Update Mode/MV cost conditinally. */
924       if (1) {
925          vdenc_img.Mode0Cost = mode_cost[0];
926          vdenc_img.Mode1Cost = mode_cost[1];
927          vdenc_img.Mode2Cost = mode_cost[2];
928          vdenc_img.Mode3Cost = mode_cost[3];
929          vdenc_img.Mode4Cost = mode_cost[4];
930          vdenc_img.Mode5Cost = mode_cost[5];
931          vdenc_img.Mode6Cost = mode_cost[6];
932          vdenc_img.Mode7Cost = mode_cost[7];
933          vdenc_img.Mode8Cost = mode_cost[8];
934          vdenc_img.Mode9Cost = mode_cost[9];
935          vdenc_img.RefIDCost = mode_cost[10];
936          vdenc_img.ChromaIntraModeCost = mode_cost[11];
937       }
938    }
939 
940    if (pps->flags.pic_scaling_matrix_present_flag) {
941       /* TODO. */
942       assert(0);
943       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
944          qm.DWordLength = 16;
945          qm.AVC = AVC_4x4_Intra_MATRIX;
946          for (unsigned m = 0; m < 3; m++)
947             for (unsigned q = 0; q < 16; q++)
948                qm.ForwardQuantizerMatrix[m * 16 + q] = pps->pScalingLists->ScalingList4x4[m][q];
949       }
950       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
951          qm.DWordLength = 16;
952          qm.AVC = AVC_4x4_Inter_MATRIX;
953          for (unsigned m = 0; m < 3; m++)
954             for (unsigned q = 0; q < 16; q++)
955                qm.ForwardQuantizerMatrix[m * 16 + q] = pps->pScalingLists->ScalingList4x4[m + 3][q];
956       }
957       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
958          qm.DWordLength = 16;
959          qm.AVC = AVC_8x8_Intra_MATRIX;
960          for (unsigned q = 0; q < 64; q++)
961             qm.ForwardQuantizerMatrix[q] = pps->pScalingLists->ScalingList8x8[0][q];
962       }
963       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
964          qm.DWordLength = 16;
965          qm.AVC = AVC_8x8_Inter_MATRIX;
966          for (unsigned q = 0; q < 64; q++)
967             qm.ForwardQuantizerMatrix[q] = pps->pScalingLists->ScalingList8x8[3][q];
968       }
969    } else if (sps->flags.seq_scaling_matrix_present_flag) {
970       /* TODO. */
971       assert(0);
972       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
973          qm.DWordLength = 16;
974          qm.AVC = AVC_4x4_Intra_MATRIX;
975          for (unsigned m = 0; m < 3; m++)
976             for (unsigned q = 0; q < 16; q++)
977                qm.ForwardQuantizerMatrix[m * 16 + q] = sps->pScalingLists->ScalingList4x4[m][q];
978       }
979       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
980          qm.DWordLength = 16;
981          qm.AVC = AVC_4x4_Inter_MATRIX;
982          for (unsigned m = 0; m < 3; m++)
983             for (unsigned q = 0; q < 16; q++)
984                qm.ForwardQuantizerMatrix[m * 16 + q] = sps->pScalingLists->ScalingList4x4[m + 3][q];
985       }
986       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
987          qm.DWordLength = 16;
988          qm.AVC = AVC_8x8_Intra_MATRIX;
989          for (unsigned q = 0; q < 64; q++)
990             qm.ForwardQuantizerMatrix[q] = sps->pScalingLists->ScalingList8x8[0][q];
991       }
992       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
993          qm.DWordLength = 16;
994          qm.AVC = AVC_8x8_Inter_MATRIX;
995          for (unsigned q = 0; q < 64; q++)
996             qm.ForwardQuantizerMatrix[q] = sps->pScalingLists->ScalingList8x8[3][q];
997       }
998    } else {
999       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
1000          qm.AVC = AVC_4x4_Intra_MATRIX;
1001          for (unsigned q = 0; q < 3 * 16; q++)
1002             qm.ForwardQuantizerMatrix[q] = 0x10;
1003       }
1004       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
1005          qm.AVC = AVC_4x4_Inter_MATRIX;
1006          for (unsigned q = 0; q < 3 * 16; q++)
1007             qm.ForwardQuantizerMatrix[q] = 0x10;
1008       }
1009       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
1010          qm.AVC = AVC_8x8_Intra_MATRIX;
1011          for (unsigned q = 0; q < 64; q++)
1012             qm.ForwardQuantizerMatrix[q] = 0x10;
1013       }
1014       anv_batch_emit(&cmd->batch, GENX(MFX_QM_STATE), qm) {
1015          qm.AVC = AVC_8x8_Inter_MATRIX;
1016          for (unsigned q = 0; q < 64; q++)
1017             qm.ForwardQuantizerMatrix[q] = 0x10;
1018       }
1019    }
1020 
1021    if (pps->flags.pic_scaling_matrix_present_flag) {
1022       /* TODO. */
1023       assert(0);
1024       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1025          fqm.AVC = AVC_4x4_Intra_MATRIX;
1026          for (unsigned m = 0; m < 3; m++)
1027             for (unsigned q = 0; q < 16; q++)
1028                fqm.QuantizerMatrix8x8[m * 16 + q] = pps->pScalingLists->ScalingList4x4[m][q];
1029       }
1030       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1031          fqm.AVC = AVC_4x4_Inter_MATRIX;
1032          for (unsigned m = 0; m < 3; m++)
1033             for (unsigned q = 0; q < 16; q++)
1034                fqm.QuantizerMatrix8x8[m * 16 + q] = pps->pScalingLists->ScalingList4x4[m + 3][q];
1035       }
1036       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1037          fqm.AVC = AVC_8x8_Intra_MATRIX;
1038          for (unsigned q = 0; q < 64; q++)
1039             fqm.QuantizerMatrix8x8[q] = pps->pScalingLists->ScalingList8x8[0][q];
1040       }
1041       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1042          fqm.AVC = AVC_8x8_Inter_MATRIX;
1043          for (unsigned q = 0; q < 64; q++)
1044             fqm.QuantizerMatrix8x8[q] = pps->pScalingLists->ScalingList8x8[3][q];
1045       }
1046    } else if (sps->flags.seq_scaling_matrix_present_flag) {
1047       /* TODO. */
1048       assert(0);
1049       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1050          fqm.AVC = AVC_4x4_Intra_MATRIX;
1051          for (unsigned m = 0; m < 3; m++)
1052             for (unsigned q = 0; q < 16; q++)
1053                fqm.QuantizerMatrix8x8[m * 16 + q] = sps->pScalingLists->ScalingList4x4[m][q];
1054       }
1055       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1056          fqm.AVC = AVC_4x4_Inter_MATRIX;
1057          for (unsigned m = 0; m < 3; m++)
1058             for (unsigned q = 0; q < 16; q++)
1059                fqm.QuantizerMatrix8x8[m * 16 + q] = sps->pScalingLists->ScalingList4x4[m + 3][q];
1060       }
1061       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1062          fqm.AVC = AVC_8x8_Intra_MATRIX;
1063          for (unsigned q = 0; q < 64; q++)
1064             fqm.QuantizerMatrix8x8[q] = sps->pScalingLists->ScalingList8x8[0][q];
1065       }
1066       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1067          fqm.AVC = AVC_8x8_Inter_MATRIX;
1068          for (unsigned q = 0; q < 64; q++)
1069             fqm.QuantizerMatrix8x8[q] = sps->pScalingLists->ScalingList8x8[3][q];
1070       }
1071    } else {
1072       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1073          fqm.AVC = AVC_4x4_Intra_MATRIX;
1074          for (unsigned q = 0; q < 64; q++)
1075             if (q % 2 == 1)
1076               fqm.QuantizerMatrix8x8[q] = 0x10;
1077       }
1078       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1079          fqm.AVC = AVC_4x4_Inter_MATRIX;
1080          for (unsigned q = 0; q < 64; q++)
1081             if (q % 2 == 1)
1082               fqm.QuantizerMatrix8x8[q] = 0x10;
1083       }
1084       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1085          fqm.AVC = AVC_8x8_Intra_MATRIX;
1086          for (unsigned q = 0; q < 64; q++)
1087             if (q % 2 == 1)
1088                fqm.QuantizerMatrix8x8[q] = 0x10;
1089       }
1090       anv_batch_emit(&cmd->batch, GENX(MFX_FQM_STATE), fqm) {
1091          fqm.AVC = AVC_8x8_Inter_MATRIX;
1092          for (unsigned q = 0; q < 64; q++)
1093             if (q % 2 == 1)
1094                fqm.QuantizerMatrix8x8[q] = 0x10;
1095       }
1096    }
1097 
1098    for (uint32_t slice_id = 0; slice_id < frame_info->naluSliceEntryCount; slice_id++) {
1099       const VkVideoEncodeH264NaluSliceInfoKHR *nalu = &frame_info->pNaluSliceEntries[slice_id];
1100       const StdVideoEncodeH264SliceHeader *slice_header = nalu->pStdSliceHeader;
1101       const StdVideoEncodeH264SliceHeader *next_slice_header = NULL;
1102 
1103       bool is_last = (slice_id == frame_info->naluSliceEntryCount - 1);
1104       uint32_t slice_type = slice_header->slice_type % 5;
1105       uint32_t slice_qp = rc_disable ? nalu->constantQp : pps->pic_init_qp_minus26 + 26;
1106 
1107       if (!is_last)
1108          next_slice_header = slice_header + 1;
1109 
1110       if (slice_type != STD_VIDEO_H264_SLICE_TYPE_I) {
1111          anv_batch_emit(&cmd->batch, GENX(MFX_AVC_REF_IDX_STATE), ref) {
1112             ref.ReferencePictureListSelect = 0;
1113 
1114             for (uint32_t i = 0; i < ref_list_info->num_ref_idx_l0_active_minus1 + 1; i++) {
1115                const VkVideoReferenceSlotInfoKHR ref_slot = enc_info->pReferenceSlots[i];
1116                ref.ReferenceListEntry[i] = dpb_idx[ref_slot.slotIndex];
1117             }
1118          }
1119       }
1120 
1121       if (slice_type == STD_VIDEO_H264_SLICE_TYPE_B) {
1122          anv_batch_emit(&cmd->batch, GENX(MFX_AVC_REF_IDX_STATE), ref) {
1123             ref.ReferencePictureListSelect = 1;
1124 
1125             for (uint32_t i = 0; i < ref_list_info->num_ref_idx_l1_active_minus1 + 1; i++) {
1126                const VkVideoReferenceSlotInfoKHR ref_slot = enc_info->pReferenceSlots[i];
1127                ref.ReferenceListEntry[i] = dpb_idx[ref_slot.slotIndex];
1128             }
1129          }
1130       }
1131 
1132       if (pps->flags.weighted_pred_flag && slice_type == STD_VIDEO_H265_SLICE_TYPE_P) {
1133          /* TODO. */
1134          assert(0);
1135          anv_batch_emit(&cmd->batch, GENX(MFX_AVC_WEIGHTOFFSET_STATE), w) {
1136          }
1137       }
1138 
1139       if (pps->flags.weighted_pred_flag && slice_type == STD_VIDEO_H265_SLICE_TYPE_B) {
1140          /* TODO. */
1141          assert(0);
1142          anv_batch_emit(&cmd->batch, GENX(MFX_AVC_WEIGHTOFFSET_STATE), w) {
1143          }
1144       }
1145 
1146       const StdVideoEncodeH264WeightTable*      weight_table =  slice_header->pWeightTable;
1147 
1148       unsigned w_in_mb = align(src_img->vk.extent.width, ANV_MB_WIDTH) / ANV_MB_WIDTH;
1149       unsigned h_in_mb = align(src_img->vk.extent.height, ANV_MB_HEIGHT) / ANV_MB_HEIGHT;
1150 
1151       uint8_t slice_header_data[256] = { 0, };
1152       size_t slice_header_data_len_in_bytes = 0;
1153       vk_video_encode_h264_slice_header(frame_info->pStdPictureInfo,
1154                                         sps,
1155                                         pps,
1156                                         slice_header,
1157                                         slice_qp - (pps->pic_init_qp_minus26 + 26),
1158                                         &slice_header_data_len_in_bytes,
1159                                         &slice_header_data);
1160       uint32_t slice_header_data_len_in_bits = slice_header_data_len_in_bytes * 8;
1161 
1162       anv_batch_emit(&cmd->batch, GENX(MFX_AVC_SLICE_STATE), avc_slice) {
1163          avc_slice.SliceType = slice_type;
1164 
1165          if (slice_type != STD_VIDEO_H264_SLICE_TYPE_I && weight_table) {
1166             avc_slice.Log2WeightDenominatorLuma = weight_table->luma_log2_weight_denom;
1167             avc_slice.Log2WeightDenominatorChroma = weight_table->chroma_log2_weight_denom;
1168          }
1169 
1170          avc_slice.NumberofReferencePicturesinInterpredictionList0 =
1171             slice_type == STD_VIDEO_H264_SLICE_TYPE_I ? 0 : ref_list_info->num_ref_idx_l0_active_minus1 + 1;
1172          avc_slice.NumberofReferencePicturesinInterpredictionList1 =
1173             (slice_type == STD_VIDEO_H264_SLICE_TYPE_I ||
1174              slice_type == STD_VIDEO_H264_SLICE_TYPE_P) ? 0 : ref_list_info->num_ref_idx_l1_active_minus1 + 1;
1175 
1176          avc_slice.SliceAlphaC0OffsetDiv2 = slice_header->slice_alpha_c0_offset_div2 & 0x7;
1177          avc_slice.SliceBetaOffsetDiv2 = slice_header->slice_beta_offset_div2 & 0x7;
1178          avc_slice.SliceQuantizationParameter = slice_qp;
1179          avc_slice.CABACInitIDC = slice_header->cabac_init_idc;
1180          avc_slice.DisableDeblockingFilterIndicator =
1181             pps->flags.deblocking_filter_control_present_flag ? slice_header->disable_deblocking_filter_idc : 0;
1182          avc_slice.DirectPredictionType = slice_header->flags.direct_spatial_mv_pred_flag;
1183 
1184          avc_slice.SliceStartMBNumber = slice_header->first_mb_in_slice;
1185          avc_slice.SliceHorizontalPosition =
1186             slice_header->first_mb_in_slice % (w_in_mb);
1187          avc_slice.SliceVerticalPosition =
1188             slice_header->first_mb_in_slice / (w_in_mb);
1189 
1190          if (is_last) {
1191             avc_slice.NextSliceHorizontalPosition = 0;
1192             avc_slice.NextSliceVerticalPosition = h_in_mb;
1193          } else {
1194             avc_slice.NextSliceHorizontalPosition = next_slice_header->first_mb_in_slice % w_in_mb;
1195             avc_slice.NextSliceVerticalPosition = next_slice_header->first_mb_in_slice / w_in_mb;
1196          }
1197 
1198          avc_slice.SliceID = slice_id;
1199          avc_slice.CABACZeroWordInsertionEnable = 1;
1200          avc_slice.EmulationByteSliceInsertEnable = 1;
1201          avc_slice.SliceDataInsertionPresent = 1;
1202          avc_slice.HeaderInsertionPresent = 1;
1203          avc_slice.LastSliceGroup = is_last;
1204          avc_slice.RateControlCounterEnable = false;
1205 
1206          /* TODO. Available only when RateControlCounterEnable is true. */
1207          avc_slice.RateControlPanicType = CBPPanic;
1208          avc_slice.RateControlPanicEnable = false;
1209          avc_slice.RateControlTriggleMode = LooseRateControl;
1210          avc_slice.ResetRateControlCounter = true;
1211          avc_slice.IndirectPAKBSEDataStartAddress = enc_info->dstBufferOffset;
1212 
1213          avc_slice.RoundIntra = 5;
1214          avc_slice.RoundIntraEnable = true;
1215          /* TODO. Needs to get a different value of rounding inter under various conditions. */
1216          avc_slice.RoundInter = 2;
1217          avc_slice.RoundInterEnable = false;
1218 
1219          if (slice_type == STD_VIDEO_H264_SLICE_TYPE_P) {
1220             avc_slice.WeightedPredictionIndicator = pps->flags.weighted_pred_flag;
1221             avc_slice.NumberofReferencePicturesinInterpredictionList0 = ref_list_info->num_ref_idx_l0_active_minus1 + 1;
1222          } else if (slice_type == STD_VIDEO_H264_SLICE_TYPE_B) {
1223             avc_slice.WeightedPredictionIndicator = pps->weighted_bipred_idc;
1224             avc_slice.NumberofReferencePicturesinInterpredictionList0 = ref_list_info->num_ref_idx_l0_active_minus1 + 1;
1225             avc_slice.NumberofReferencePicturesinInterpredictionList1 = ref_list_info->num_ref_idx_l1_active_minus1 + 1;
1226          }
1227       }
1228 
1229       uint32_t length_in_dw, data_bits_in_last_dw;
1230       uint32_t *dw;
1231 
1232       /* Insert zero slice data */
1233       unsigned int insert_zero[] = { 0, };
1234       length_in_dw = 1;
1235       data_bits_in_last_dw = 8;
1236 
1237       dw = anv_batch_emitn(&cmd->batch, length_in_dw + 2, GENX(MFX_PAK_INSERT_OBJECT),
1238             .DataBitsInLastDW = data_bits_in_last_dw > 0 ? data_bits_in_last_dw : 32,
1239             .HeaderLengthExcludedFromSize =  ACCUMULATE);
1240 
1241       memcpy(dw + 2, insert_zero, length_in_dw * 4);
1242 
1243       slice_header_data_len_in_bits -= 8;
1244 
1245       length_in_dw = ALIGN(slice_header_data_len_in_bits, 32) >> 5;
1246       data_bits_in_last_dw = slice_header_data_len_in_bits & 0x1f;
1247 
1248       dw = anv_batch_emitn(&cmd->batch, length_in_dw + 2, GENX(MFX_PAK_INSERT_OBJECT),
1249                .LastHeader = true,
1250                .DataBitsInLastDW = data_bits_in_last_dw > 0 ? data_bits_in_last_dw : 32,
1251                .SliceHeaderIndicator = true,
1252                .HeaderLengthExcludedFromSize =  ACCUMULATE);
1253 
1254       memcpy(dw + 2, slice_header_data + 1, length_in_dw * 4);
1255 
1256       anv_batch_emit(&cmd->batch, GENX(VDENC_WEIGHTSOFFSETS_STATE), vdenc_offsets) {
1257          vdenc_offsets.WeightsForwardReference0 = 1;
1258          vdenc_offsets.WeightsForwardReference1 = 1;
1259          vdenc_offsets.WeightsForwardReference2 = 1;
1260 
1261       }
1262 
1263       anv_batch_emit(&cmd->batch, GENX(VDENC_WALKER_STATE), vdenc_walker) {
1264          vdenc_walker.NextSliceMBStartYPosition = h_in_mb;
1265          vdenc_walker.Log2WeightDenominatorLuma = weight_table ? weight_table->luma_log2_weight_denom : 0;
1266 #if GFX_VER >= 12
1267          vdenc_walker.TileWidth = src_img->vk.extent.width - 1;
1268 #endif
1269       }
1270 
1271       anv_batch_emit(&cmd->batch, GENX(VD_PIPELINE_FLUSH), flush) {
1272          flush.MFXPipelineDone = true;
1273          flush.VDENCPipelineDone = true;
1274          flush.VDCommandMessageParserDone = true;
1275          flush.VDENCPipelineCommandFlush = true;
1276       }
1277    }
1278 
1279    anv_batch_emit(&cmd->batch, GENX(MI_FLUSH_DW), flush) {
1280       flush.DWordLength = 2;
1281       flush.VideoPipelineCacheInvalidate = 1;
1282    };
1283 
1284 }
1285 
1286 static uint8_t
anv_h265_get_ref_poc(const VkVideoEncodeInfoKHR * enc_info,const StdVideoEncodeH265ReferenceListsInfo * ref_lists,const bool l0,const uint8_t slot_num,bool * long_term)1287 anv_h265_get_ref_poc(const VkVideoEncodeInfoKHR *enc_info,
1288                      const StdVideoEncodeH265ReferenceListsInfo* ref_lists,
1289                      const bool l0,
1290                      const uint8_t slot_num,
1291                      bool *long_term)
1292 {
1293    uint8_t ref_poc = 0xff;
1294    unsigned ref_cnt = l0 ? ref_lists->num_ref_idx_l0_active_minus1 + 1 :
1295                            ref_lists->num_ref_idx_l1_active_minus1 + 1;
1296 
1297    for (unsigned i = 0; i < ref_cnt; i++) {
1298       const VkVideoReferenceSlotInfoKHR ref_slot_info = enc_info->pReferenceSlots[i];
1299       const VkVideoEncodeH265DpbSlotInfoKHR *dpb =
1300             vk_find_struct_const(ref_slot_info.pNext, VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR);
1301 
1302       if (!dpb)
1303          return ref_poc;
1304 
1305       if (ref_slot_info.slotIndex == slot_num) {
1306          ref_poc = dpb->pStdReferenceInfo->PicOrderCntVal;
1307          *long_term |= dpb->pStdReferenceInfo->flags.used_for_long_term_reference;
1308          break;
1309       }
1310    }
1311 
1312    return ref_poc;
1313 }
1314 
1315 static void
scaling_list(struct anv_cmd_buffer * cmd_buffer,const StdVideoH265ScalingLists * scaling_list)1316 scaling_list(struct anv_cmd_buffer *cmd_buffer,
1317              const StdVideoH265ScalingLists *scaling_list)
1318 {
1319    /* 4x4, 8x8, 16x16, 32x32 */
1320    for (uint8_t size = 0; size < 4; size++) {
1321       /* Intra, Inter */
1322       for (uint8_t pred = 0; pred < 2; pred++) {
1323          /* Y, Cb, Cr */
1324          for (uint8_t color = 0; color < 3; color++) {
1325             if (size == 3 && color > 0)
1326                continue;
1327 
1328             anv_batch_emit(&cmd_buffer->batch, GENX(HCP_QM_STATE), qm) {
1329                qm.SizeID = size;
1330                qm.PredictionType = pred;
1331                qm.ColorComponent = color;
1332 
1333                qm.DCCoefficient = size > 1 ?
1334                   (size == 2 ? scaling_list->ScalingListDCCoef16x16[3 * pred + color] :
1335                                scaling_list->ScalingListDCCoef32x32[pred]) : 0;
1336 
1337                if (size == 0) {
1338                   for (uint8_t i = 0; i < 4; i++)
1339                      for (uint8_t j = 0; j < 4; j++)
1340                         qm.QuantizerMatrix8x8[4 * i + j] =
1341                            scaling_list->ScalingList4x4[3 * pred + color][4 * i + j];
1342                } else if (size == 1) {
1343                   for (uint8_t i = 0; i < 8; i++)
1344                      for (uint8_t j = 0; j < 8; j++)
1345                         qm.QuantizerMatrix8x8[8 * i + j] =
1346                            scaling_list->ScalingList8x8[3 * pred + color][8 * i + j];
1347                } else if (size == 2) {
1348                   for (uint8_t i = 0; i < 8; i++)
1349                      for (uint8_t j = 0; j < 8; j++)
1350                         qm.QuantizerMatrix8x8[8 * i + j] =
1351                            scaling_list->ScalingList16x16[3 * pred + color][8 * i + j];
1352                } else if (size == 3) {
1353                   for (uint8_t i = 0; i < 8; i++)
1354                      for (uint8_t j = 0; j < 8; j++)
1355                         qm.QuantizerMatrix8x8[8 * i + j] =
1356                            scaling_list->ScalingList32x32[pred][8 * i + j];
1357                }
1358             }
1359          }
1360       }
1361    }
1362 }
1363 
1364 static uint16_t
lcu_max_bits_size_allowed(const StdVideoH265SequenceParameterSet * sps)1365 lcu_max_bits_size_allowed(const StdVideoH265SequenceParameterSet *sps)
1366 {
1367    uint16_t log2_max_coding_block_size =
1368          sps->log2_diff_max_min_luma_coding_block_size +
1369          sps->log2_min_luma_coding_block_size_minus3 + 3;
1370    uint32_t raw_ctu_bits = (1 << (2 * log2_max_coding_block_size));
1371 
1372    switch (sps->chroma_format_idc)
1373    {
1374    case 1:
1375        raw_ctu_bits = raw_ctu_bits * 3 / 2;
1376        break;
1377    case 2:
1378        raw_ctu_bits = raw_ctu_bits * 2;
1379        break;
1380    case 3:
1381        raw_ctu_bits = raw_ctu_bits * 3;
1382        break;
1383    default:
1384        break;
1385    };
1386 
1387    raw_ctu_bits = raw_ctu_bits * (sps->bit_depth_luma_minus8 + 8);
1388    raw_ctu_bits = (5 * raw_ctu_bits / 3);
1389 
1390    return raw_ctu_bits & 0xffff;
1391 }
1392 
1393 static void
anv_h265_encode_video(struct anv_cmd_buffer * cmd,const VkVideoEncodeInfoKHR * enc_info)1394 anv_h265_encode_video(struct anv_cmd_buffer *cmd, const VkVideoEncodeInfoKHR *enc_info)
1395 {
1396    /* Supported on Gen12(+) for using VDEnc Mode */
1397 #if GFX_VER >= 12
1398    ANV_FROM_HANDLE(anv_buffer, dst_buffer, enc_info->dstBuffer);
1399    struct anv_video_session *vid = cmd->video.vid;
1400    struct anv_video_session_params *params = cmd->video.params;
1401 
1402    const struct VkVideoEncodeH265PictureInfoKHR *frame_info =
1403       vk_find_struct_const(enc_info->pNext, VIDEO_ENCODE_H265_PICTURE_INFO_KHR);
1404 
1405    const StdVideoH265VideoParameterSet *vps = vk_video_find_h265_enc_std_vps(&params->vk, frame_info->pStdPictureInfo->sps_video_parameter_set_id);
1406    const StdVideoH265SequenceParameterSet *sps = vk_video_find_h265_enc_std_sps(&params->vk, frame_info->pStdPictureInfo->pps_seq_parameter_set_id);
1407    const StdVideoH265PictureParameterSet *pps = vk_video_find_h265_enc_std_pps(&params->vk, frame_info->pStdPictureInfo->pps_pic_parameter_set_id);
1408    const StdVideoEncodeH265ReferenceListsInfo *ref_list_info = frame_info->pStdPictureInfo->pRefLists;
1409 
1410    const struct anv_image_view *iv = anv_image_view_from_handle(enc_info->srcPictureResource.imageViewBinding);
1411    const struct anv_image *src_img = iv->image;
1412 
1413    const struct anv_image_view *base_ref_iv;
1414 
1415    bool rc_disable = cmd->video.params->rc_mode == VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
1416 
1417    if (enc_info->pSetupReferenceSlot) {
1418       base_ref_iv = anv_image_view_from_handle(enc_info->pSetupReferenceSlot->pPictureResource->imageViewBinding);
1419    } else {
1420       base_ref_iv = iv;
1421    }
1422 
1423    const struct anv_image *base_ref_img = base_ref_iv->image;
1424    uint8_t dpb_idx[ANV_VIDEO_H265_MAX_NUM_REF_FRAME] = { 0,};
1425 
1426    anv_batch_emit(&cmd->batch, GENX(MI_FLUSH_DW), flush) {
1427       flush.VideoPipelineCacheInvalidate = 1;
1428    };
1429 
1430 
1431    anv_batch_emit(&cmd->batch, GENX(MI_FORCE_WAKEUP), wake) {
1432       wake.MFXPowerWellControl = 1;
1433       wake.HEVCPowerWellControl = 1;
1434       wake.MaskBits = 768;
1435    }
1436 
1437    anv_batch_emit(&cmd->batch, GENX(VDENC_CONTROL_STATE), v) {
1438       v.VdencInitialization = true;
1439    }
1440 
1441    anv_batch_emit(&cmd->batch, GENX(VD_CONTROL_STATE), v) {
1442       v.PipelineInitialization = true;
1443    }
1444 
1445    anv_batch_emit(&cmd->batch, GENX(MFX_WAIT), mfx) {
1446       mfx.MFXSyncControlFlag = 1;
1447    }
1448 
1449    anv_batch_emit(&cmd->batch, GENX(HCP_PIPE_MODE_SELECT), sel) {
1450       sel.CodecSelect = Encode;
1451       sel.CodecStandardSelect = HEVC;
1452       sel.VDEncMode = VM_VDEncMode;
1453    }
1454 
1455    anv_batch_emit(&cmd->batch, GENX(MFX_WAIT), mfx) {
1456       mfx.MFXSyncControlFlag = 1;
1457    }
1458 
1459 
1460    for (uint32_t i = 0; i < 3; i++) {
1461       anv_batch_emit(&cmd->batch, GENX(HCP_SURFACE_STATE), ss) {
1462          struct anv_image *img_ = NULL;
1463 
1464          switch(i) {
1465             case 0:
1466                img_ = (struct anv_image *) src_img;
1467                ss.SurfaceID = HCP_SourceInputPicture;
1468                break;
1469             case 1:
1470                //img_ = (struct anv_image *) src_img;
1471                img_ = (struct anv_image *) base_ref_img;
1472                ss.SurfaceID = HCP_CurrentDecodedPicture;
1473                break;
1474             case 2:
1475                img_ = (struct anv_image *) base_ref_img;
1476                ss.SurfaceID = HCP_ReferencePicture;
1477                break;
1478             default:
1479                assert(0);
1480          }
1481 
1482          ss.SurfacePitch = img_->planes[0].primary_surface.isl.row_pitch_B - 1;
1483          ss.SurfaceFormat = PLANAR_420_8;
1484 
1485          ss.YOffsetforUCb = img_->planes[1].primary_surface.memory_range.offset /
1486                             img_->planes[0].primary_surface.isl.row_pitch_B;
1487          ss.YOffsetforVCr = ss.YOffsetforUCb;
1488       }
1489    }
1490 
1491    anv_batch_emit(&cmd->batch, GENX(HCP_PIPE_BUF_ADDR_STATE), buf) {
1492       buf.DecodedPictureAddress =
1493          anv_image_address(base_ref_img, &base_ref_img->planes[0].primary_surface.memory_range);
1494 
1495       buf.DecodedPictureMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1496          .MOCS = anv_mocs(cmd->device, buf.DecodedPictureAddress.bo, 0),
1497       };
1498 
1499       buf.DeblockingFilterLineBufferAddress = (struct anv_address) {
1500          vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_LINE].mem->bo,
1501          vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_LINE].offset
1502       };
1503 
1504       buf.DeblockingFilterLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1505          .MOCS = anv_mocs(cmd->device, buf.DeblockingFilterLineBufferAddress.bo, 0),
1506       };
1507 
1508       buf.DeblockingFilterTileLineBufferAddress = (struct anv_address) {
1509          vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_TILE_LINE].mem->bo,
1510          vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_TILE_LINE].offset
1511       };
1512 
1513       buf.DeblockingFilterTileLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1514          .MOCS = anv_mocs(cmd->device, buf.DeblockingFilterTileLineBufferAddress.bo, 0),
1515       };
1516 
1517       buf.DeblockingFilterTileColumnBufferAddress = (struct anv_address) {
1518          vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_TILE_COLUMN].mem->bo,
1519          vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_TILE_COLUMN].offset
1520       };
1521 
1522       buf.DeblockingFilterTileColumnBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1523          .MOCS = anv_mocs(cmd->device, buf.DeblockingFilterTileColumnBufferAddress.bo, 0),
1524       };
1525 
1526       buf.MetadataLineBufferAddress = (struct anv_address) {
1527          vid->vid_mem[ANV_VID_MEM_H265_METADATA_LINE].mem->bo,
1528          vid->vid_mem[ANV_VID_MEM_H265_METADATA_LINE].offset
1529       };
1530 
1531       buf.MetadataLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1532          .MOCS = anv_mocs(cmd->device, buf.MetadataLineBufferAddress.bo, 0),
1533       };
1534 
1535       buf.MetadataTileLineBufferAddress = (struct anv_address) {
1536          vid->vid_mem[ANV_VID_MEM_H265_METADATA_TILE_LINE].mem->bo,
1537          vid->vid_mem[ANV_VID_MEM_H265_METADATA_TILE_LINE].offset
1538       };
1539 
1540       buf.MetadataTileLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1541          .MOCS = anv_mocs(cmd->device, buf.MetadataTileLineBufferAddress.bo, 0),
1542       };
1543 
1544       buf.MetadataTileColumnBufferAddress = (struct anv_address) {
1545          vid->vid_mem[ANV_VID_MEM_H265_METADATA_TILE_COLUMN].mem->bo,
1546          vid->vid_mem[ANV_VID_MEM_H265_METADATA_TILE_COLUMN].offset
1547       };
1548 
1549       buf.MetadataTileColumnBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1550          .MOCS = anv_mocs(cmd->device, buf.MetadataTileColumnBufferAddress.bo, 0),
1551       };
1552 
1553       buf.SAOLineBufferAddress = (struct anv_address) {
1554          vid->vid_mem[ANV_VID_MEM_H265_SAO_LINE].mem->bo,
1555          vid->vid_mem[ANV_VID_MEM_H265_SAO_LINE].offset
1556       };
1557 
1558       buf.SAOLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1559          .MOCS = anv_mocs(cmd->device, buf.SAOLineBufferAddress.bo, 0),
1560       };
1561 
1562       buf.SAOTileLineBufferAddress = (struct anv_address) {
1563          vid->vid_mem[ANV_VID_MEM_H265_SAO_TILE_LINE].mem->bo,
1564          vid->vid_mem[ANV_VID_MEM_H265_SAO_TILE_LINE].offset
1565       };
1566 
1567       buf.SAOTileLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1568          .MOCS = anv_mocs(cmd->device, buf.SAOTileLineBufferAddress.bo, 0),
1569       };
1570 
1571       buf.SAOTileColumnBufferAddress = (struct anv_address) {
1572          vid->vid_mem[ANV_VID_MEM_H265_SAO_TILE_COLUMN].mem->bo,
1573          vid->vid_mem[ANV_VID_MEM_H265_SAO_TILE_COLUMN].offset
1574       };
1575 
1576       buf.SAOTileColumnBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1577          .MOCS = anv_mocs(cmd->device, buf.SAOTileColumnBufferAddress.bo, 0),
1578       };
1579 
1580       buf.CurrentMVTemporalBufferAddress = anv_image_address(src_img, &src_img->vid_dmv_top_surface);
1581 
1582       buf.CurrentMVTemporalBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1583          .MOCS = anv_mocs(cmd->device, buf.CurrentMVTemporalBufferAddress.bo, 0),
1584       };
1585 
1586       for (unsigned i = 0; i < enc_info->referenceSlotCount; i++) {
1587          const struct anv_image_view *ref_iv =
1588             anv_image_view_from_handle(enc_info->pReferenceSlots[i].pPictureResource->imageViewBinding);
1589          int slot_idx = enc_info->pReferenceSlots[i].slotIndex;
1590 
1591          assert(slot_idx < ANV_VIDEO_H265_MAX_NUM_REF_FRAME);
1592          dpb_idx[slot_idx] = i;
1593 
1594          buf.ReferencePictureAddress[i] =
1595             anv_image_address(ref_iv->image, &ref_iv->image->planes[0].primary_surface.memory_range);
1596       }
1597 
1598       buf.ReferencePictureMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1599          .MOCS = anv_mocs(cmd->device, NULL, 0),
1600       };
1601 
1602       buf.OriginalUncompressedPictureSourceAddress =
1603          anv_image_address(src_img, &src_img->planes[0].primary_surface.memory_range);
1604       buf.OriginalUncompressedPictureSourceMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1605          .MOCS = anv_mocs(cmd->device, buf.OriginalUncompressedPictureSourceAddress.bo, 0),
1606       };
1607 
1608       buf.StreamOutDataDestinationMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1609          .MOCS = anv_mocs(cmd->device, NULL, 0),
1610       };
1611 
1612       buf.DecodedPictureStatusBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1613          .MOCS = anv_mocs(cmd->device, NULL, 0),
1614       };
1615 
1616       buf.LCUILDBStreamOutBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1617          .MOCS = anv_mocs(cmd->device, NULL, 0),
1618       };
1619 
1620       for (unsigned i = 0; i < enc_info->referenceSlotCount; i++) {
1621          const struct anv_image_view *ref_iv =
1622             anv_image_view_from_handle(enc_info->pReferenceSlots[i].pPictureResource->imageViewBinding);
1623 
1624          buf.CollocatedMVTemporalBufferAddress[i] =
1625             anv_image_address(ref_iv->image, &ref_iv->image->vid_dmv_top_surface);
1626       }
1627 
1628       buf.CollocatedMVTemporalBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1629          .MOCS = anv_mocs(cmd->device, buf.CollocatedMVTemporalBufferAddress[0].bo, 0),
1630       };
1631 
1632       buf.VP9ProbabilityBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1633          .MOCS = anv_mocs(cmd->device, NULL, 0),
1634       };
1635 
1636       buf.VP9SegmentIDBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1637          .MOCS = anv_mocs(cmd->device, NULL, 0),
1638       };
1639 
1640       buf.VP9HVDLineRowStoreBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1641          .MOCS = anv_mocs(cmd->device, NULL, 0),
1642       };
1643 
1644       buf.VP9HVDTileRowStoreBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1645          .MOCS = anv_mocs(cmd->device, NULL, 0),
1646       };
1647 
1648       buf.SAOStreamOutDataDestinationBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1649          .MOCS = anv_mocs(cmd->device, NULL, 0),
1650       };
1651       buf.FrameStatisticsStreamOutDataDestinationBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1652          .MOCS = anv_mocs(cmd->device, NULL, 0),
1653       };
1654 
1655       buf.SSESourcePixelRowStoreBufferBaseAddress = (struct anv_address) {
1656          vid->vid_mem[ANV_VID_MEM_H265_SSE_SRC_PIX_ROW_STORE].mem->bo,
1657          vid->vid_mem[ANV_VID_MEM_H265_SSE_SRC_PIX_ROW_STORE].offset
1658       };
1659 
1660       buf.SSESourcePixelRowStoreBufferMemoryAddressAttributesReadWrite = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1661          .MOCS = anv_mocs(cmd->device, buf.SSESourcePixelRowStoreBufferBaseAddress.bo, 0),
1662       };
1663 
1664       buf.HCPScalabilitySliceStateBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1665          .MOCS = anv_mocs(cmd->device, NULL, 0),
1666       };
1667       buf.HCPScalabilityCABACDecodedSyntaxElementsBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1668          .MOCS = anv_mocs(cmd->device, NULL, 0),
1669       };
1670       buf.MVUpperRightColumnStoreBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1671          .MOCS = anv_mocs(cmd->device, NULL, 0),
1672       };
1673       buf.IntraPredictionUpperRightColumnStoreBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1674          .MOCS = anv_mocs(cmd->device, NULL, 0),
1675       };
1676       buf.IntraPredictionLeftReconColumnStoreBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1677          .MOCS = anv_mocs(cmd->device, NULL, 0),
1678       };
1679    }
1680 
1681    anv_batch_emit(&cmd->batch, GENX(HCP_IND_OBJ_BASE_ADDR_STATE), indirect) {
1682       indirect.HCPIndirectBitstreamObjectMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1683          .MOCS = anv_mocs(cmd->device, NULL, 0),
1684       };
1685 
1686       indirect.HCPIndirectCUObjectMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1687          .MOCS = anv_mocs(cmd->device, NULL, 0),
1688       };
1689 
1690       indirect.HCPPAKBSEObjectBaseAddress =
1691             anv_address_add(dst_buffer->address,  align(enc_info->dstBufferOffset, 4096));
1692       indirect.HCPPAKBSEObjectMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1693          .MOCS = anv_mocs(cmd->device, indirect.HCPPAKBSEObjectBaseAddress.bo, 0),
1694       };
1695 
1696       indirect.HCPVP9PAKCompressedHeaderSyntaxStreamInMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1697          .MOCS = anv_mocs(cmd->device, NULL, 0),
1698       };
1699       indirect.HCPVP9PAKProbabilityCounterStreamOutMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1700          .MOCS = anv_mocs(cmd->device, NULL, 0),
1701       };
1702       indirect.HCPVP9PAKProbabilityDeltasStreamInMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1703          .MOCS = anv_mocs(cmd->device, NULL, 0),
1704       };
1705       indirect.HCPVP9PAKTileRecordStreamOutMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1706          .MOCS = anv_mocs(cmd->device, NULL, 0),
1707       };
1708       indirect.HCPVP9PAKCULevelStatisticStreamOutMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1709          .MOCS = anv_mocs(cmd->device, NULL, 0),
1710       };
1711    }
1712 
1713    if (sps->flags.scaling_list_enabled_flag) {
1714       assert(0);
1715       /* FIXME */
1716       if (pps->flags.pps_scaling_list_data_present_flag) {
1717          scaling_list(cmd, pps->pScalingLists);
1718       } else if (sps->flags.sps_scaling_list_data_present_flag) {
1719          scaling_list(cmd, sps->pScalingLists);
1720       }
1721    } else {
1722       for (uint8_t size = 0; size < 4; size++) {
1723          for (uint8_t pred = 0; pred < 2; pred++) {
1724             anv_batch_emit(&cmd->batch, GENX(HCP_FQM_STATE), fqm) {
1725                fqm.SizeID = size;
1726                fqm.IntraInter = pred;
1727                fqm.ColorComponent = 0;
1728                fqm.FQMDCValue = size < 2 ? 0 : 0x1000;
1729 
1730                unsigned len = (size == 0) ? 32 : 128;
1731 
1732                for (uint8_t q = 0; q < len; q++) {
1733                   fqm.QuantizerMatrix8x8[q] = q % 2 == 0 ? 0 : 0x10;
1734                }
1735             }
1736          }
1737       }
1738    }
1739 
1740    if (sps->flags.scaling_list_enabled_flag) {
1741       assert(0);
1742       /* FIXME */
1743       if (pps->flags.pps_scaling_list_data_present_flag) {
1744          scaling_list(cmd, pps->pScalingLists);
1745       } else if (sps->flags.sps_scaling_list_data_present_flag) {
1746          scaling_list(cmd, sps->pScalingLists);
1747       }
1748    } else {
1749       for (uint8_t size = 0; size < 4; size++) {
1750          for (uint8_t pred = 0; pred < 2; pred++) {
1751             for (uint8_t color = 0; color < 3; color++) {
1752 
1753                if (size == 3 && color > 0)
1754                   continue;
1755 
1756                anv_batch_emit(&cmd->batch, GENX(HCP_QM_STATE), qm) {
1757                   qm.SizeID = size;
1758                   qm.PredictionType = pred;
1759                   qm.ColorComponent = color;
1760                   qm.DCCoefficient = (size > 1) ? 16 : 0;
1761                   unsigned len = (size == 0) ? 16 : 64;
1762 
1763                   for (uint8_t q = 0; q < len; q++)
1764                      qm.QuantizerMatrix8x8[q] = 0x10;
1765                }
1766             }
1767          }
1768       }
1769    }
1770 
1771 
1772    anv_batch_emit(&cmd->batch, GENX(VDENC_PIPE_MODE_SELECT), vdenc_pipe_mode) {
1773       vdenc_pipe_mode.StandardSelect = SS_HEVC;
1774       vdenc_pipe_mode.PAKChromaSubSamplingType = _420;
1775       vdenc_pipe_mode.HMERegionPrefetchEnable = !vdenc_pipe_mode.TLBPrefetchEnable;
1776       vdenc_pipe_mode.TopPrefetchEnableMode = 1;
1777       vdenc_pipe_mode.LeftPrefetchAtWrapAround = true;
1778       vdenc_pipe_mode.HzShift32Minus1 = 3;
1779       vdenc_pipe_mode.NumberofVerticalRequests = 11;
1780       vdenc_pipe_mode.NumberofHorizontalRequests = 2;
1781 
1782       vdenc_pipe_mode.SourceLumaPackedDataTLBPrefetchEnable = true;
1783       vdenc_pipe_mode.SourceChromaTLBPrefetchEnable = true;
1784       vdenc_pipe_mode.HzShift32Minus1Src = 3;
1785       vdenc_pipe_mode.PrefetchOffsetforSource = 4;
1786    }
1787 
1788    anv_batch_emit(&cmd->batch, GENX(VDENC_SRC_SURFACE_STATE), vdenc_surface) {
1789       vdenc_surface.SurfaceState.Width = src_img->vk.extent.width - 1;
1790       vdenc_surface.SurfaceState.Height = src_img->vk.extent.height - 1;
1791       vdenc_surface.SurfaceState.SurfaceFormat = VDENC_PLANAR_420_8;
1792 
1793       vdenc_surface.SurfaceState.TileWalk = TW_YMAJOR;
1794       vdenc_surface.SurfaceState.TiledSurface = src_img->planes[0].primary_surface.isl.tiling != ISL_TILING_LINEAR;
1795       vdenc_surface.SurfaceState.SurfacePitch = src_img->planes[0].primary_surface.isl.row_pitch_B - 1;
1796       vdenc_surface.SurfaceState.YOffsetforUCb = src_img->planes[1].primary_surface.memory_range.offset /
1797          src_img->planes[0].primary_surface.isl.row_pitch_B;
1798       vdenc_surface.SurfaceState.YOffsetforVCr = src_img->planes[1].primary_surface.memory_range.offset /
1799          src_img->planes[0].primary_surface.isl.row_pitch_B;
1800    }
1801 
1802    anv_batch_emit(&cmd->batch, GENX(VDENC_REF_SURFACE_STATE), vdenc_surface) {
1803       vdenc_surface.SurfaceState.Width = base_ref_img->vk.extent.width - 1;
1804       vdenc_surface.SurfaceState.Height = base_ref_img->vk.extent.height - 1;
1805       vdenc_surface.SurfaceState.SurfaceFormat = VDENC_PLANAR_420_8;
1806       vdenc_surface.SurfaceState.SurfacePitch = base_ref_img->planes[0].primary_surface.isl.row_pitch_B - 1;
1807 
1808       vdenc_surface.SurfaceState.TileWalk = TW_YMAJOR;
1809       vdenc_surface.SurfaceState.TiledSurface = base_ref_img->planes[0].primary_surface.isl.tiling != ISL_TILING_LINEAR;
1810       vdenc_surface.SurfaceState.YOffsetforUCb = base_ref_img->planes[1].primary_surface.memory_range.offset /
1811          base_ref_img->planes[0].primary_surface.isl.row_pitch_B;
1812       vdenc_surface.SurfaceState.YOffsetforVCr = base_ref_img->planes[1].primary_surface.memory_range.offset /
1813          base_ref_img->planes[0].primary_surface.isl.row_pitch_B;
1814    }
1815 
1816    /* TODO. add a cmd for VDENC_DS_REF_SURFACE_STATE */
1817 
1818    anv_batch_emit(&cmd->batch, GENX(VDENC_PIPE_BUF_ADDR_STATE), vdenc_buf) {
1819       /* TODO. add DSFWDREF and FWDREF */
1820       vdenc_buf.DSFWDREF0.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1821          .MOCS = anv_mocs(cmd->device, NULL, 0),
1822       };
1823 
1824       vdenc_buf.DSFWDREF1.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1825          .MOCS = anv_mocs(cmd->device, NULL, 0),
1826       };
1827 
1828       vdenc_buf.OriginalUncompressedPicture.Address =
1829          anv_image_address(src_img, &src_img->planes[0].primary_surface.memory_range);
1830       vdenc_buf.OriginalUncompressedPicture.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1831          .MOCS = anv_mocs(cmd->device, vdenc_buf.OriginalUncompressedPicture.Address.bo, 0),
1832       };
1833 
1834       vdenc_buf.StreamInDataPicture.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1835          .MOCS = anv_mocs(cmd->device, NULL, 0),
1836       };
1837 
1838       vdenc_buf.RowStoreScratchBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1839          .MOCS = anv_mocs(cmd->device, NULL, 0),
1840       };
1841 
1842       const struct anv_image_view *ref_iv[3] = { 0, };
1843 
1844       for (unsigned i = 0; i < enc_info->referenceSlotCount && i < 3; i++)
1845          ref_iv[i] = anv_image_view_from_handle(enc_info->pReferenceSlots[i].pPictureResource->imageViewBinding);
1846 
1847       if (ref_iv[0]) {
1848          vdenc_buf.ColocatedMVReadBuffer.Address =
1849                anv_image_address(ref_iv[0]->image, &ref_iv[0]->image->vid_dmv_top_surface);
1850          vdenc_buf.FWDREF0.Address =
1851                anv_image_address(ref_iv[0]->image, &ref_iv[0]->image->planes[0].primary_surface.memory_range);
1852       }
1853 
1854       vdenc_buf.ColocatedMVReadBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1855          .MOCS = anv_mocs(cmd->device, vdenc_buf.ColocatedMVReadBuffer.Address.bo, 0),
1856       };
1857 
1858       vdenc_buf.FWDREF0.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1859          .MOCS = anv_mocs(cmd->device, vdenc_buf.FWDREF0.Address.bo, 0),
1860       };
1861 
1862       if (ref_iv[1])
1863          vdenc_buf.FWDREF1.Address =
1864                anv_image_address(ref_iv[1]->image, &ref_iv[1]->image->planes[0].primary_surface.memory_range);
1865 
1866       vdenc_buf.FWDREF1.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1867          .MOCS = anv_mocs(cmd->device, vdenc_buf.FWDREF1.Address.bo, 0),
1868       };
1869 
1870       if (ref_iv[2])
1871          vdenc_buf.FWDREF2.Address =
1872                anv_image_address(ref_iv[2]->image, &ref_iv[2]->image->planes[0].primary_surface.memory_range);
1873 
1874       vdenc_buf.FWDREF2.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1875          .MOCS = anv_mocs(cmd->device, vdenc_buf.FWDREF2.Address.bo, 0),
1876       };
1877 
1878       vdenc_buf.BWDREF0.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1879          .MOCS = anv_mocs(cmd->device, NULL, 0),
1880       };
1881 
1882       vdenc_buf.VDEncStatisticsStreamOut.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1883          .MOCS = anv_mocs(cmd->device, NULL, 0),
1884       };
1885 
1886       vdenc_buf.DSFWDREF04X.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1887          .MOCS = anv_mocs(cmd->device, NULL, 0),
1888       };
1889       vdenc_buf.DSFWDREF14X.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1890          .MOCS = anv_mocs(cmd->device, NULL, 0),
1891       };
1892       vdenc_buf.VDEncCURecordStreamOutBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1893          .MOCS = anv_mocs(cmd->device, NULL, 0),
1894       };
1895       vdenc_buf.VDEncLCUPAK_OBJ_CMDBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1896          .MOCS = anv_mocs(cmd->device, NULL, 0),
1897       };
1898       vdenc_buf.ScaledReferenceSurface8X.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1899          .MOCS = anv_mocs(cmd->device, NULL, 0),
1900       };
1901       vdenc_buf.ScaledReferenceSurface4X.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1902          .MOCS = anv_mocs(cmd->device, NULL, 0),
1903       };
1904       vdenc_buf.VP9SegmentationMapStreamInBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1905          .MOCS = anv_mocs(cmd->device, NULL, 0),
1906       };
1907       vdenc_buf.VP9SegmentationMapStreamOutBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1908          .MOCS = anv_mocs(cmd->device, NULL, 0),
1909       };
1910       vdenc_buf.VDEncTileRowStoreBuffer.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1911          .MOCS = anv_mocs(cmd->device, NULL, 0),
1912       };
1913       vdenc_buf.VDEncCumulativeCUCountStreamOutSurface.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1914          .MOCS = anv_mocs(cmd->device, NULL, 0),
1915       };
1916       vdenc_buf.VDEncPaletteModeStreamOutSurface.PictureFields = (struct GENX(VDENC_SURFACE_CONTROL_BITS)) {
1917          .MOCS = anv_mocs(cmd->device, NULL, 0),
1918       };
1919    }
1920 
1921    anv_batch_emit(&cmd->batch, GENX(VDENC_CMD1), cmd1) {
1922       /* Magic numbers taken from media-driver */
1923       cmd1.Values[0] = 0x5030200;
1924       cmd1.Values[1] = 0xb090806;
1925       cmd1.Values[2] = 0x1c140c04;
1926       cmd1.Values[3] = 0x3c342c24;
1927       cmd1.Values[4] = 0x5c544c44;
1928       cmd1.Values[5] = 0x1c140c04;
1929       cmd1.Values[6] = 0x3c342c24;
1930       cmd1.Values[7] = 0x5c544c44;
1931       cmd1.Values[13] = 0x0;
1932       cmd1.Values[14] = 0x0;
1933       cmd1.Values[15] &= 0xffff0000;
1934 
1935       cmd1.Values[18] = (cmd1.Values[18] & 0xff0000ff) | 0x140400;
1936       cmd1.Values[19] = 0x14141414;
1937       cmd1.Values[20] = 0x14141414;
1938 
1939       cmd1.Values[21] = 0x10101010;
1940       cmd1.Values[22] = 0x10101010;
1941       cmd1.Values[23] = 0x10101010;
1942       cmd1.Values[24] = 0x10101010;
1943       cmd1.Values[25] = 0x10101010;
1944       cmd1.Values[26] = 0x10101010;
1945       cmd1.Values[27] = 0x10101010;
1946       cmd1.Values[28] = 0x10101010;
1947 
1948       if (anv_vdenc_h265_picture_type(frame_info->pStdPictureInfo->pic_type) == 0) {
1949          cmd1.Values[9] = 0x23131f0f;
1950          cmd1.Values[10] = (cmd1.Values[10] & 0xffff0000) | 0x2313;
1951          cmd1.Values[11] = 0x3e5c445c;
1952          cmd1.Values[12] = (cmd1.Values[12] & 0xff00) | 0x1e040044;
1953          cmd1.Values[15] = (cmd1.Values[15] & 0xffff) | 0x70000;
1954          cmd1.Values[16] = 0xd0e1007;
1955          cmd1.Values[17] = (cmd1.Values[17] & 0xffffff00) | 0x32;
1956          /* Handle Number of ROI */
1957          cmd1.Values[17] = (cmd1.Values[17] & 0xffff00ff) | 0x1e00;
1958          cmd1.Values[29] = (cmd1.Values[29] & 0xff000000) | 0x101010;
1959       } else {
1960          cmd1.Values[9] = 0x23131f0f;
1961          cmd1.Values[10] = 0x331b2313;
1962          cmd1.Values[11] = 0x476e4d6e;
1963          cmd1.Values[12] = 0x3604004d;
1964          cmd1.Values[15] = (cmd1.Values[15] & 0xffff) | 0x4150000;
1965          cmd1.Values[16] = 0x23231415;
1966          cmd1.Values[17] = (cmd1.Values[17] & 0xffffff00) | 0x3f;
1967          /* Handle Number of ROI */
1968          cmd1.Values[17] = (cmd1.Values[17] & 0xffff00ff) | 0x4400;
1969          cmd1.Values[29] = (cmd1.Values[29] & 0xff000000) | 0x232323;
1970       }
1971    }
1972 
1973    uint32_t frame_width_in_min_cb = sps->pic_width_in_luma_samples >> (sps->log2_min_luma_coding_block_size_minus3 + 3);
1974    uint32_t frame_height_in_min_cb = sps->pic_height_in_luma_samples >> (sps->log2_min_luma_coding_block_size_minus3 + 3);
1975    uint32_t width_in_pix = frame_width_in_min_cb << (sps->log2_min_luma_coding_block_size_minus3 + 3);
1976    uint32_t height_in_pix = frame_height_in_min_cb << (sps->log2_min_luma_coding_block_size_minus3 + 3);
1977 
1978    anv_batch_emit(&cmd->batch, GENX(HCP_PIC_STATE), pic) {
1979       pic.FrameWidthInMinimumCodingBlockSize = frame_width_in_min_cb - 1;
1980       pic.FrameHeightInMinimumCodingBlockSize = frame_height_in_min_cb - 1;
1981       pic.TransformSkipEnable = pps->flags.transform_skip_enabled_flag;
1982       pic.TransformSkipEnable = true;
1983 
1984       pic.MinCUSize = sps->log2_min_luma_coding_block_size_minus3;
1985       pic.LCUSize = sps->log2_diff_max_min_luma_coding_block_size + sps->log2_min_luma_coding_block_size_minus3;
1986 
1987       pic.MinTUSize = sps->log2_min_luma_transform_block_size_minus2;
1988       pic.MaxTUSize = sps->log2_diff_max_min_luma_transform_block_size + sps->log2_min_luma_transform_block_size_minus2;
1989 
1990       pic.MinPCMSize = 0;
1991       pic.MaxPCMSize = 0;
1992 
1993       pic.ChromaSubsampling = sps->chroma_format_idc;
1994 
1995       const StdVideoEncodeH265SliceSegmentHeader *slice_header = NULL;
1996       for (uint32_t slice_id = 0; slice_id < frame_info->naluSliceSegmentEntryCount; slice_id++) {
1997          const VkVideoEncodeH265NaluSliceSegmentInfoKHR *nalu = &frame_info->pNaluSliceSegmentEntries[slice_id];
1998          if (nalu) {
1999             slice_header = nalu->pStdSliceSegmentHeader;
2000             break;
2001         }
2002       }
2003 
2004       pic.CollocatedPictureIsISlice = false;
2005       pic.CurrentPictureIsISlice = false;
2006 
2007       pic.SampleAdaptiveOffsetEnable = sps->flags.sample_adaptive_offset_enabled_flag ? slice_header->flags.slice_sao_chroma_flag ||
2008          slice_header->flags.slice_sao_luma_flag : 0;
2009       pic.PCMEnable = sps->flags.pcm_enabled_flag;
2010       pic.CUQPDeltaEnable = pps->flags.cu_qp_delta_enabled_flag;
2011       pic.MaxDQPDepth = pps->diff_cu_qp_delta_depth;
2012       pic.PCMLoopFilterDisable = sps->flags.pcm_loop_filter_disabled_flag;
2013       pic.ConstrainedIntraPrediction = pps->flags.constrained_intra_pred_flag;
2014       pic.TilingEnable = pps->flags.tiles_enabled_flag;
2015       pic.WeightedBiPredicationEnable = pps->flags.weighted_bipred_flag;
2016       pic.WeightedPredicationEnable = pps->flags.weighted_pred_flag;
2017       pic.FieldPic = 0;
2018       pic.TopField = false;
2019       pic.TransformSkipEnable = pps->flags.transform_skip_enabled_flag;
2020       pic.AMPEnable = sps->flags.amp_enabled_flag;
2021       pic.TransquantBypassEnable = pps->flags.transquant_bypass_enabled_flag;
2022       pic.StrongIntraSmoothingEnable = sps->flags.strong_intra_smoothing_enabled_flag;
2023       pic.CUPacketStructure = 0;
2024 
2025       pic.PictureCbQPOffset = pps->pps_cb_qp_offset & 0x1f;
2026       pic.PictureCrQPOffset = pps->pps_cr_qp_offset & 0x1f;
2027       pic.IntraMaxTransformHierarchyDepth = 2;
2028       pic.InterMaxTransformHierarchyDepth = 2;
2029       pic.ChromaPCMSampleBitDepth = sps->pcm_sample_bit_depth_chroma_minus1 & 0xf;
2030       pic.LumaPCMSampleBitDepth = sps->pcm_sample_bit_depth_luma_minus1 & 0xf;
2031 
2032       pic.ChromaBitDepth = sps->bit_depth_chroma_minus8;
2033       pic.LumaBitDepth = sps->bit_depth_luma_minus8;
2034 
2035       pic.LCUMaxBitSizeAllowed = lcu_max_bits_size_allowed(sps);
2036       pic.CbQPOffsetList0 = pps->cb_qp_offset_list[0];
2037       pic.CbQPOffsetList1 = pps->cb_qp_offset_list[1];
2038       pic.CbQPOffsetList2 = pps->cb_qp_offset_list[2];
2039       pic.CbQPOffsetList3 = pps->cb_qp_offset_list[3];
2040       pic.CbQPOffsetList4 = pps->cb_qp_offset_list[4];
2041       pic.CbQPOffsetList5 = pps->cb_qp_offset_list[5];
2042 
2043       pic.CrQPOffsetList0 = pps->cr_qp_offset_list[0];
2044       pic.CrQPOffsetList1 = pps->cr_qp_offset_list[1];
2045       pic.CrQPOffsetList2 = pps->cr_qp_offset_list[2];
2046       pic.CrQPOffsetList3 = pps->cr_qp_offset_list[3];
2047       pic.CrQPOffsetList4 = pps->cr_qp_offset_list[4];
2048       pic.CrQPOffsetList5 = pps->cr_qp_offset_list[5];
2049       pic.FirstSliceSegmentInPic = true;
2050       pic.SSEEnable = true;
2051    }
2052 
2053    anv_batch_emit(&cmd->batch, GENX(VDENC_CMD2), cmd2) {
2054       /* Magic numbers taken from media-driver */
2055       cmd2.Values9 = (cmd2.Values9 & 0xffff) | 0x43840000;
2056       cmd2.Values12 = 0xffffffff;
2057       cmd2.Values15 = 0x4e201f40;
2058       cmd2.Values16 = (cmd2.Values16 & 0xf0ff0000) | 0xf003300;
2059       cmd2.Values17 = (cmd2.Values17 & 0xfff00000) | 0x2710;
2060       cmd2.Values19 = (cmd2.Values19 & 0x80ffffff) | 0x18000000;
2061       cmd2.Values19 = (cmd2.Values19 & 0x80ffffff) | 0x18000000;
2062       cmd2.Values21 &= 0xfffffff;
2063       cmd2.Values22 = 0x1f001102;
2064       cmd2.Values23 = 0xaaaa1f00;
2065       cmd2.Values27 = (cmd2.Values27 & 0xffff0000) | 0x1a1a;
2066 
2067       cmd2.FrameWidthInPixelsMinusOne = width_in_pix - 1;
2068       cmd2.FrameHeightInPixelsMinusOne = height_in_pix - 1;
2069       cmd2.PictureType = anv_vdenc_h265_picture_type(frame_info->pStdPictureInfo->pic_type);
2070       cmd2.TemporalMVPEnableFlag =
2071             anv_vdenc_h265_picture_type(frame_info->pStdPictureInfo->pic_type) == 0 ?
2072             0 : sps->flags.sps_temporal_mvp_enabled_flag;
2073       cmd2.TransformSkip = pps->flags.transform_skip_enabled_flag;
2074 
2075       if (anv_vdenc_h265_picture_type(frame_info->pStdPictureInfo->pic_type) != 0) {
2076          cmd2.NumRefIdxL0MinusOne = ref_list_info->num_ref_idx_l0_active_minus1;
2077          cmd2.NumRefIdxL1MinusOne = ref_list_info->num_ref_idx_l1_active_minus1;
2078       }
2079 
2080       cmd2.Values5 = (cmd2.Values5 & 0xff83ffff) | 0x400000;
2081       cmd2.Values14 = (cmd2.Values14 & 0xffff) | 0x7d00000;
2082       cmd2.Values15 = 0x4e201f40;
2083       cmd2.Values17 = (cmd2.Values17 & 0xfff00000) | 0x2710;
2084       cmd2.Values18 = (cmd2.Values18 & 0xffff) | 0x600000;
2085       cmd2.Values19 = (cmd2.Values19 & 0xffff0000) | 0xc0;
2086       cmd2.Values20 &= 0xfffeffff;
2087       cmd2.TilingEnable = pps->flags.tiles_enabled_flag;
2088 
2089       if (anv_vdenc_h265_picture_type(frame_info->pStdPictureInfo->pic_type) != 0) {
2090          const StdVideoEncodeH265ReferenceListsInfo* ref_lists = frame_info->pStdPictureInfo->pRefLists;
2091 
2092          bool long_term = false;
2093          uint8_t ref_slot = ref_lists->RefPicList0[0];
2094          uint8_t cur_poc = frame_info->pStdPictureInfo->PicOrderCntVal;
2095          uint8_t ref_poc = anv_h265_get_ref_poc(enc_info, ref_lists, true, ref_slot, &long_term);
2096          int8_t diff_poc = cur_poc - ref_poc;
2097 
2098          cmd2.POCNumberForRefid0InL0 = CLAMP(diff_poc, -16, 16);
2099          cmd2.LongTermReferenceFlagsL0 |= long_term;
2100 
2101          ref_slot = ref_lists->RefPicList0[1];
2102          ref_poc = anv_h265_get_ref_poc(enc_info, ref_lists, true, ref_slot, &long_term);
2103          diff_poc = ref_poc == 0xff ? 0 : cur_poc - ref_poc;
2104 
2105          cmd2.POCNumberForRefid1InL0 = CLAMP(diff_poc, -16, 16);
2106          cmd2.LongTermReferenceFlagsL0 |= long_term;
2107 
2108          ref_slot = ref_lists->RefPicList0[2];
2109          ref_poc = anv_h265_get_ref_poc(enc_info, ref_lists, true, ref_slot, &long_term);
2110          diff_poc = ref_poc == 0xff ? 0 : cur_poc - ref_poc;
2111 
2112          cmd2.POCNumberForRefid2InL0 = CLAMP(diff_poc, -16, 16);
2113          cmd2.LongTermReferenceFlagsL0 |= long_term;
2114 
2115 
2116          ref_slot = ref_lists->RefPicList1[0];
2117          ref_poc = anv_h265_get_ref_poc(enc_info, ref_lists, false, ref_slot, &long_term);
2118          diff_poc = ref_poc == 0xff ? 0 : cur_poc - ref_poc;
2119 
2120          cmd2.POCNumberForRefid0InL1 = CLAMP(diff_poc, -16, 16);
2121          cmd2.LongTermReferenceFlagsL1 |= long_term;
2122 
2123          cmd2.POCNumberForRefid1InL1 = cmd2.POCNumberForRefid2InL1 = cmd2.POCNumberForRefid0InL1;
2124          cmd2.SubPelMode = 3;
2125       }
2126    }
2127 
2128    for (uint32_t slice_id = 0; slice_id < frame_info->naluSliceSegmentEntryCount; slice_id++) {
2129       const VkVideoEncodeH265NaluSliceSegmentInfoKHR *nalu = &frame_info->pNaluSliceSegmentEntries[slice_id];
2130       const StdVideoEncodeH265SliceSegmentHeader *next_slice_header = NULL;
2131       StdVideoEncodeH265SliceSegmentHeader *slice_header =
2132             (StdVideoEncodeH265SliceSegmentHeader *)nalu->pStdSliceSegmentHeader;
2133 
2134       bool is_last = (slice_id == frame_info->naluSliceSegmentEntryCount - 1);
2135       uint32_t slice_type = slice_header->slice_type % 5;
2136       uint32_t slice_qp = rc_disable ? nalu->constantQp : pps->init_qp_minus26 + 26;
2137       uint32_t slice_qp_delta = slice_qp - (pps->init_qp_minus26 + 26);
2138 
2139       if (slice_type == STD_VIDEO_H265_SLICE_TYPE_P)
2140          slice_header->slice_type = slice_type = STD_VIDEO_H265_SLICE_TYPE_B;
2141 
2142       assert(slice_qp >= 10 && slice_qp <= 51);
2143 
2144       uint32_t ctb_size = 1 << (sps->log2_diff_max_min_luma_coding_block_size +
2145           sps->log2_min_luma_coding_block_size_minus3 + 3);
2146       uint32_t ctb_w = DIV_ROUND_UP(width_in_pix, ctb_size);
2147       uint32_t ctb_h = DIV_ROUND_UP(height_in_pix, ctb_size);
2148 
2149       if (!is_last)
2150          next_slice_header = slice_header + 1;
2151 
2152       if (slice_type != STD_VIDEO_H265_SLICE_TYPE_I) {
2153          anv_batch_emit(&cmd->batch, GENX(HCP_REF_IDX_STATE), ref) {
2154             ref.ReferencePictureListSelect = 0;
2155             ref.NumberofReferenceIndexesActive = ref_list_info->num_ref_idx_l0_active_minus1;
2156 
2157             for (uint32_t i = 0; i < ref_list_info->num_ref_idx_l0_active_minus1 + 1; i++) {
2158                const VkVideoReferenceSlotInfoKHR ref_slot = enc_info->pReferenceSlots[i];
2159                const VkVideoEncodeH265DpbSlotInfoKHR *dpb =
2160                      vk_find_struct_const(ref_slot.pNext, VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR);
2161 
2162                ref.ReferenceListEntry[i].ListEntry = dpb_idx[ref_slot.slotIndex];
2163 
2164                unsigned ref_poc = dpb->pStdReferenceInfo->PicOrderCntVal;
2165                int32_t diff_poc = frame_info->pStdPictureInfo->PicOrderCntVal - ref_poc;
2166 
2167 
2168                ref.ReferenceListEntry[i].ReferencePicturetbValue = CLAMP(diff_poc, -128, 127) & 0xff;
2169                ref.ReferenceListEntry[i].TopField = true;
2170             }
2171          }
2172       }
2173 
2174       if (slice_type == STD_VIDEO_H265_SLICE_TYPE_B) {
2175          anv_batch_emit(&cmd->batch, GENX(HCP_REF_IDX_STATE), ref) {
2176             ref.ReferencePictureListSelect = 1;
2177             ref.NumberofReferenceIndexesActive = ref_list_info->num_ref_idx_l1_active_minus1;
2178 
2179             for (uint32_t i = 0; i < ref_list_info->num_ref_idx_l1_active_minus1 + 1; i++) {
2180                const VkVideoReferenceSlotInfoKHR ref_slot = enc_info->pReferenceSlots[i];
2181 
2182                const VkVideoEncodeH265DpbSlotInfoKHR *dpb =
2183                      vk_find_struct_const(ref_slot.pNext, VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR);
2184 
2185                ref.ReferenceListEntry[i].ListEntry = dpb_idx[ref_slot.slotIndex];
2186 
2187                unsigned ref_poc = dpb->pStdReferenceInfo->PicOrderCntVal;
2188                int32_t diff_poc = frame_info->pStdPictureInfo->PicOrderCntVal - ref_poc;
2189 
2190                ref.ReferenceListEntry[i].ReferencePicturetbValue = CLAMP(diff_poc, -128, 127) & 0xff;
2191                ref.ReferenceListEntry[i].TopField = true;
2192             }
2193          }
2194       }
2195 
2196       uint8_t chroma_log2_weight_denom = 0;
2197 
2198       if ((pps->flags.weighted_pred_flag && (slice_type == STD_VIDEO_H265_SLICE_TYPE_P)) ||
2199             (pps->flags.weighted_bipred_flag && (slice_type == STD_VIDEO_H265_SLICE_TYPE_B))) {
2200          assert (slice_header->pWeightTable);
2201 
2202          uint16_t chroma_weight, chroma_offset;
2203          const StdVideoEncodeH265WeightTable *w_tbl = slice_header->pWeightTable;
2204          chroma_log2_weight_denom = w_tbl->luma_log2_weight_denom + w_tbl->delta_chroma_log2_weight_denom;
2205 
2206          anv_batch_emit(&cmd->batch, GENX(HCP_WEIGHTOFFSET_STATE), w) {
2207             w.ReferencePictureListSelect = 0;
2208 
2209             for (unsigned i = 0; i < STD_VIDEO_H265_MAX_NUM_LIST_REF; i++) {
2210 
2211                w.LumaOffsets[i].DeltaLumaWeightLX = w_tbl->delta_luma_weight_l0[i] & 0xff;
2212                w.LumaOffsets[i].LumaOffsetLX = w_tbl->luma_offset_l0[i] & 0xff;
2213                w.ChromaOffsets[i].DeltaChromaWeightLX0 = w_tbl->delta_chroma_weight_l0[i][0] & 0xff;
2214                w.ChromaOffsets[i].DeltaChromaWeightLX1 = w_tbl->delta_chroma_weight_l0[i][1] & 0xff;
2215 
2216 
2217                chroma_weight = (1 << chroma_log2_weight_denom) + w_tbl->delta_chroma_weight_l0[i][0];
2218                chroma_offset = CLAMP(w_tbl->delta_chroma_offset_l0[i][0] -
2219                   ((128 * chroma_weight) >> chroma_log2_weight_denom) + 128, -128, 127);
2220                w.ChromaOffsets[i].ChromaOffsetLX0 = chroma_offset & 0xff;
2221 
2222                chroma_weight = (1 << chroma_log2_weight_denom) + w_tbl->delta_chroma_weight_l0[i][1];
2223                chroma_offset = CLAMP(w_tbl->delta_chroma_offset_l0[i][1] -
2224                   ((128 * chroma_weight) >> chroma_log2_weight_denom) + 128, -128, 127);
2225                w.ChromaOffsets[i].ChromaOffsetLX1 = chroma_offset & 0xff;
2226             }
2227          }
2228 
2229          if (slice_type == STD_VIDEO_H265_SLICE_TYPE_B) {
2230             anv_batch_emit(&cmd->batch, GENX(HCP_WEIGHTOFFSET_STATE), w) {
2231                w.ReferencePictureListSelect = 1;
2232 
2233                for (unsigned i = 0; i < STD_VIDEO_H265_MAX_NUM_LIST_REF; i++) {
2234                   w.LumaOffsets[i].DeltaLumaWeightLX = w_tbl->delta_luma_weight_l1[i] & 0xff;
2235                   w.LumaOffsets[i].LumaOffsetLX = w_tbl->luma_offset_l1[i] & 0xff;
2236                   w.ChromaOffsets[i].DeltaChromaWeightLX0 = w_tbl->delta_chroma_weight_l1[i][0] & 0xff;
2237                   w.ChromaOffsets[i].DeltaChromaWeightLX1 = w_tbl->delta_chroma_weight_l1[i][1] & 0xff;
2238 
2239                   chroma_weight = (1 << chroma_log2_weight_denom) + w_tbl->delta_chroma_weight_l1[i][0];
2240                   chroma_offset = CLAMP(w_tbl->delta_chroma_offset_l1[i][0] -
2241                      ((128 * chroma_weight) >> chroma_log2_weight_denom) + 128, -128, 127);
2242                   w.ChromaOffsets[i].ChromaOffsetLX0 = chroma_offset & 0xff;
2243 
2244                   chroma_weight = (1 << chroma_log2_weight_denom) + w_tbl->delta_chroma_weight_l1[i][1];
2245                   chroma_offset = CLAMP(w_tbl->delta_chroma_offset_l1[i][1] -
2246                      ((128 * chroma_weight) >> chroma_log2_weight_denom) + 128, -128, 127);
2247                   w.ChromaOffsets[i].ChromaOffsetLX1 = chroma_offset & 0xff;
2248                }
2249             }
2250          }
2251       }
2252 
2253       uint8_t slice_header_data[256] = { 0, };
2254       size_t slice_header_data_len_in_bytes = 0;
2255       vk_video_encode_h265_slice_header(frame_info->pStdPictureInfo,
2256                                         vps,
2257                                         sps,
2258                                         pps,
2259                                         slice_header,
2260                                         slice_qp_delta,
2261                                         &slice_header_data_len_in_bytes,
2262                                         &slice_header_data);
2263       uint32_t slice_header_data_len_in_bits = slice_header_data_len_in_bytes * 8;
2264 
2265       anv_batch_emit(&cmd->batch, GENX(HCP_SLICE_STATE), slice) {
2266          slice.SliceHorizontalPosition = slice_header->slice_segment_address % ctb_w;
2267          slice.SliceVerticalPosition = slice_header->slice_segment_address / ctb_w;
2268 
2269          if (is_last) {
2270             slice.NextSliceHorizontalPosition = 0;
2271             slice.NextSliceVerticalPosition = 0;
2272          } else {
2273             slice.NextSliceHorizontalPosition = next_slice_header->slice_segment_address % ctb_w;
2274             slice.NextSliceVerticalPosition = next_slice_header->slice_segment_address / ctb_w;
2275          }
2276 
2277          slice.SliceType = slice_type;
2278          slice.LastSlice = is_last;
2279          slice.DependentSlice = slice_header->flags.dependent_slice_segment_flag;
2280          slice.SliceTemporalMVPEnable = frame_info->pStdPictureInfo->flags.slice_temporal_mvp_enabled_flag;;
2281          slice.SliceQP = slice_qp;
2282          slice.SliceCbQPOffset = slice_header->slice_cb_qp_offset;
2283          slice.SliceCrQPOffset = slice_header->slice_cr_qp_offset;
2284          slice.SliceHeaderDisableDeblockingFilter = slice_header->flags.slice_deblocking_filter_disabled_flag;
2285          slice.SliceTCOffsetDiv2 = slice_header->slice_tc_offset_div2;
2286          slice.SliceBetaOffsetDiv2 = slice_header->slice_beta_offset_div2;
2287          slice.SliceLoopFilterEnable = slice_header->flags.slice_loop_filter_across_slices_enabled_flag;
2288          slice.SliceSAOChroma = slice_header->flags.slice_sao_chroma_flag;
2289          slice.SliceSAOLuma = slice_header->flags.slice_sao_luma_flag;
2290          slice.MVDL1Zero = slice_header->flags.mvd_l1_zero_flag;
2291          slice.CollocatedFromL0 = slice_header->flags.collocated_from_l0_flag;
2292          /* TODO. Support Low Delay mode */
2293          slice.LowDelay = false;
2294 
2295          if (slice_type != STD_VIDEO_H265_SLICE_TYPE_I && slice_header->pWeightTable) {
2296             slice.Log2WeightDenominatorChroma = slice_header->pWeightTable->luma_log2_weight_denom +
2297                (chroma_log2_weight_denom - slice_header->pWeightTable->luma_log2_weight_denom);
2298             slice.Log2WeightDenominatorLuma = slice_header->pWeightTable->luma_log2_weight_denom;
2299          }
2300          slice.CABACInit = slice_header->flags.cabac_init_flag;
2301          slice.MaxMergeIndex = slice_header->MaxNumMergeCand - 1;
2302 
2303          slice.CollocatedMVTemporalBufferIndex = dpb_idx[slice_header->collocated_ref_idx];
2304          assert(slice.CollocatedMVTemporalBufferIndex < ANV_VIDEO_H265_HCP_NUM_REF_FRAME);
2305 
2306          /* For VDEnc mode */
2307          slice.RoundInter = 4;
2308          slice.RoundIntra = 10;
2309 
2310          slice.SliceHeaderLength = 0;
2311          slice.CABACZeroWordInsertionEnable = false;
2312          slice.EmulationByteSliceInsertEnable = true;
2313          slice.TailInsertionPresent = false;
2314          slice.SliceDataInsertionPresent = true;
2315          slice.HeaderInsertionPresent = true;
2316 
2317          slice.IndirectPAKBSEDataStartOffset = 0;
2318          slice.TransformSkipLambda = 162;
2319          slice.TransformSkipNumberofZeroCoeffsFactor0 = 42;
2320          slice.TransformSkipNumberofNonZeroCoeffsFactor0 = 72;
2321          slice.TransformSkipNumberofZeroCoeffsFactor1 = 32;
2322          slice.TransformSkipNumberofNonZeroCoeffsFactor1 = 77;
2323 
2324          slice.OriginalSliceStartCtbX = slice_header->slice_segment_address % ctb_w;
2325          slice.OriginalSliceStartCtbY = slice_header->slice_segment_address / ctb_w;
2326       }
2327 
2328       uint32_t *dw;
2329       uint32_t length_in_dw;
2330       uint32_t data_bits_in_last_dw;
2331 
2332       length_in_dw = ALIGN(slice_header_data_len_in_bits, 32) >> 5;
2333       data_bits_in_last_dw = slice_header_data_len_in_bits & 0x1f;
2334 
2335       dw = anv_batch_emitn(&cmd->batch, length_in_dw + 2, GENX(HCP_PAK_INSERT_OBJECT),
2336             .LastHeader = true,
2337             .EndofSlice = true,
2338             .DataBitsInLastDW = data_bits_in_last_dw > 0 ? data_bits_in_last_dw : 32,
2339             .SliceHeaderIndicator = true,
2340             .HeaderLengthExcludedFromSize =  ACCUMULATE);
2341 
2342       memcpy(dw + 2, slice_header_data, length_in_dw * 4);
2343 
2344       anv_batch_emit(&cmd->batch, GENX(VDENC_WEIGHTSOFFSETS_STATE), vdenc_offsets) {
2345          vdenc_offsets.WeightsForwardReference0 = 1;
2346          vdenc_offsets.WeightsForwardReference1 = 1;
2347          vdenc_offsets.WeightsForwardReference2 = 1;
2348          vdenc_offsets.HEVCVP9WeightsBackwardReference0 = 1;
2349       }
2350 
2351       anv_batch_emit(&cmd->batch, GENX(VDENC_WALKER_STATE), vdenc_walker) {
2352          uint32_t slice_block_rows = DIV_ROUND_UP(src_img->vk.extent.height, ANV_MAX_H265_CTB_SIZE);
2353          uint32_t slice_block_cols = DIV_ROUND_UP(src_img->vk.extent.width, ANV_MAX_H265_CTB_SIZE);
2354          uint32_t num_ctu_in_slice = slice_block_cols * slice_block_rows;
2355 
2356          vdenc_walker.MBLCUStartYPosition = slice_header->slice_segment_address % ctb_w;
2357          vdenc_walker.NextSliceMBLCUStartXPosition = (slice_header->slice_segment_address + num_ctu_in_slice) / ctb_h;
2358          vdenc_walker.NextSliceMBStartYPosition = (slice_header->slice_segment_address + num_ctu_in_slice) / ctb_w;
2359          vdenc_walker.NextSliceMBLCUStartXPosition = (slice_header->slice_segment_address + num_ctu_in_slice) / ctb_h;
2360          vdenc_walker.TileWidth = width_in_pix - 1;
2361          vdenc_walker.TileHeight = height_in_pix - 1;
2362       }
2363 
2364       anv_batch_emit(&cmd->batch, GENX(VD_PIPELINE_FLUSH), flush) {
2365          flush.MFXPipelineDone = true;
2366          flush.VDENCPipelineDone = true;
2367          flush.VDENCPipelineCommandFlush = true;
2368          flush.VDCommandMessageParserDone = true;
2369       }
2370    }
2371 
2372    anv_batch_emit(&cmd->batch, GENX(MI_FLUSH_DW), flush) {
2373       flush.VideoPipelineCacheInvalidate = 1;
2374    };
2375 
2376    anv_batch_emit(&cmd->batch, GENX(VD_PIPELINE_FLUSH), flush) {
2377       flush.HEVCPipelineDone = true;
2378       flush.HEVCPipelineCommandFlush = true;
2379       flush.VDCommandMessageParserDone = true;
2380    }
2381 
2382    anv_batch_emit(&cmd->batch, GENX(MI_FLUSH_DW), flush) {
2383       flush.VideoPipelineCacheInvalidate = 0;
2384    };
2385 
2386 #endif // GFX_VER >= 12
2387 
2388 }
2389 
2390 static void
emit_query_mi_availability(struct mi_builder * b,struct anv_address addr,bool available)2391 emit_query_mi_availability(struct mi_builder *b,
2392                            struct anv_address addr,
2393                            bool available)
2394 {
2395    mi_store(b, mi_mem64(addr), mi_imm(available));
2396 }
2397 
2398 
2399 #if GFX_VER < 11
2400 #define MFC_BITSTREAM_BYTECOUNT_FRAME_REG       0x128A0
2401 #define HCP_BITSTREAM_BYTECOUNT_FRAME_REG       0x1E9A0
2402 #elif GFX_VER >= 11
2403 #define MFC_BITSTREAM_BYTECOUNT_FRAME_REG       0x1C08A0
2404 #define HCP_BITSTREAM_BYTECOUNT_FRAME_REG       0x1C28A0
2405 #endif
2406 
2407 static void
handle_inline_query_end(struct anv_cmd_buffer * cmd_buffer,const VkVideoInlineQueryInfoKHR * inline_query)2408 handle_inline_query_end(struct anv_cmd_buffer *cmd_buffer,
2409                         const VkVideoInlineQueryInfoKHR *inline_query)
2410 {
2411    uint32_t reg_addr;
2412    struct mi_builder b;
2413    ANV_FROM_HANDLE(anv_query_pool, pool, inline_query->queryPool);
2414    if (pool == VK_NULL_HANDLE)
2415       return;
2416    struct anv_address query_addr = {
2417       .bo = pool->bo,
2418       .offset = inline_query->firstQuery * pool->stride,
2419    };
2420 
2421    mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch);
2422    const uint32_t mocs = anv_mocs_for_address(cmd_buffer->device, &query_addr);
2423    mi_builder_set_mocs(&b, mocs);
2424 
2425    if (pool->codec & VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR) {
2426       reg_addr = MFC_BITSTREAM_BYTECOUNT_FRAME_REG;
2427    } else if (pool->codec & VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR) {
2428       reg_addr = HCP_BITSTREAM_BYTECOUNT_FRAME_REG;
2429    } else {
2430       unreachable("Invalid codec operation");
2431    }
2432 
2433    mi_store(&b, mi_mem64(anv_address_add(query_addr, 8)), mi_reg32(reg_addr));
2434    emit_query_mi_availability(&b, query_addr, true);
2435 }
2436 
2437 void
genX(CmdEncodeVideoKHR)2438 genX(CmdEncodeVideoKHR)(VkCommandBuffer commandBuffer,
2439                         const VkVideoEncodeInfoKHR *pEncodeInfo)
2440 {
2441    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
2442 
2443    const VkVideoInlineQueryInfoKHR *inline_query =
2444       vk_find_struct_const(pEncodeInfo->pNext, VIDEO_INLINE_QUERY_INFO_KHR);
2445 
2446    switch (cmd_buffer->video.vid->vk.op) {
2447    case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
2448       anv_h264_encode_video(cmd_buffer, pEncodeInfo);
2449       break;
2450    case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
2451       anv_h265_encode_video(cmd_buffer, pEncodeInfo);
2452       break;
2453    default:
2454       assert(0);
2455    }
2456 
2457    if (inline_query)
2458       handle_inline_query_end(cmd_buffer, inline_query);
2459 }
2460