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(¶ms->vk, frame_info->pStdPictureInfo->seq_parameter_set_id);
392 const StdVideoH264PictureParameterSet *pps = vk_video_find_h264_enc_std_pps(¶ms->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(¶ms->vk, frame_info->pStdPictureInfo->sps_video_parameter_set_id);
1406 const StdVideoH265SequenceParameterSet *sps = vk_video_find_h265_enc_std_sps(¶ms->vk, frame_info->pStdPictureInfo->pps_seq_parameter_set_id);
1407 const StdVideoH265PictureParameterSet *pps = vk_video_find_h265_enc_std_pps(¶ms->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