1 /*
2 * Copyright © 2021 Red Hat
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
29 #include "util/vl_zscan_data.h"
30
31 void
genX(CmdBeginVideoCodingKHR)32 genX(CmdBeginVideoCodingKHR)(VkCommandBuffer commandBuffer,
33 const VkVideoBeginCodingInfoKHR *pBeginInfo)
34 {
35 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
36 ANV_FROM_HANDLE(anv_video_session, vid, pBeginInfo->videoSession);
37 ANV_FROM_HANDLE(anv_video_session_params, params, pBeginInfo->videoSessionParameters);
38
39 cmd_buffer->video.vid = vid;
40 cmd_buffer->video.params = params;
41
42 if (vid->vk.op != VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR)
43 return;
44
45 if (!vid->cdf_initialized) {
46 anv_init_av1_cdf_tables(cmd_buffer, vid);
47 vid->cdf_initialized = true;
48 }
49 }
50
51 void
genX(CmdControlVideoCodingKHR)52 genX(CmdControlVideoCodingKHR)(VkCommandBuffer commandBuffer,
53 const VkVideoCodingControlInfoKHR *pCodingControlInfo)
54 {
55 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
56
57 if (pCodingControlInfo->flags & VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR) {
58 anv_batch_emit(&cmd_buffer->batch, GENX(MI_FLUSH_DW), flush) {
59 flush.VideoPipelineCacheInvalidate = 1;
60 }
61 }
62
63 if (pCodingControlInfo->flags & VK_VIDEO_CODING_CONTROL_ENCODE_RATE_CONTROL_BIT_KHR) {
64 const struct VkVideoEncodeRateControlInfoKHR *rate_control_info =
65 vk_find_struct_const(pCodingControlInfo->pNext, VIDEO_ENCODE_RATE_CONTROL_INFO_KHR);
66
67 /* Support for only CQP rate control for the moment */
68 assert((rate_control_info->rateControlMode == VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR) ||
69 (rate_control_info->rateControlMode == VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR));
70
71 cmd_buffer->video.params->rc_mode = rate_control_info->rateControlMode;
72 } else {
73 cmd_buffer->video.params->rc_mode = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR;
74 }
75 }
76
77 void
genX(CmdEndVideoCodingKHR)78 genX(CmdEndVideoCodingKHR)(VkCommandBuffer commandBuffer,
79 const VkVideoEndCodingInfoKHR *pEndCodingInfo)
80 {
81 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
82
83 cmd_buffer->video.vid = NULL;
84 cmd_buffer->video.params = NULL;
85 }
86
87 /*
88 * The default scan order of scaling lists is up-right-diagonal
89 * according to the spec. But the device requires raster order,
90 * so we need to convert from the passed scaling lists.
91 */
92 static void
anv_h265_matrix_from_uprightdiagonal(StdVideoH265ScalingLists * out_sl,const StdVideoH265ScalingLists * sl)93 anv_h265_matrix_from_uprightdiagonal(StdVideoH265ScalingLists *out_sl,
94 const StdVideoH265ScalingLists *sl)
95 {
96 uint8_t i, j;
97
98 for (i = 0; i < 6; i++) {
99 for (j = 0; j < STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS; j++)
100 out_sl->ScalingList4x4[i][vl_zscan_h265_up_right_diagonal_16[j]] =
101 sl->ScalingList4x4[i][j];
102
103 for (j = 0; j < STD_VIDEO_H265_SCALING_LIST_8X8_NUM_ELEMENTS; j++)
104 out_sl->ScalingList8x8[i][vl_zscan_h265_up_right_diagonal[j]] =
105 sl->ScalingList8x8[i][j];
106
107 for (j = 0; j < STD_VIDEO_H265_SCALING_LIST_16X16_NUM_ELEMENTS; j++)
108 out_sl->ScalingList16x16[i][vl_zscan_h265_up_right_diagonal[j]] =
109 sl->ScalingList16x16[i][j];
110 }
111
112 for (i = 0; i < STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS; i++) {
113 for (j = 0; j < STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS; j++)
114 out_sl->ScalingList32x32[i][vl_zscan_h265_up_right_diagonal[j]] =
115 sl->ScalingList32x32[i][j];
116 }
117 }
118
119 static void
scaling_list(struct anv_cmd_buffer * cmd_buffer,const StdVideoH265ScalingLists * scaling_list)120 scaling_list(struct anv_cmd_buffer *cmd_buffer,
121 const StdVideoH265ScalingLists *scaling_list)
122 {
123 StdVideoH265ScalingLists out_sl = {0, };
124
125 anv_h265_matrix_from_uprightdiagonal(&out_sl, scaling_list);
126
127 /* 4x4, 8x8, 16x16, 32x32 */
128 for (uint8_t size = 0; size < 4; size++) {
129 /* Intra, Inter */
130 for (uint8_t pred = 0; pred < 2; pred++) {
131 /* Y, Cb, Cr */
132 for (uint8_t color = 0; color < 3; color++) {
133 if (size == 3 && color > 0)
134 continue;
135
136 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_QM_STATE), qm) {
137 qm.SizeID = size;
138 qm.PredictionType = pred;
139 qm.ColorComponent = color;
140
141 qm.DCCoefficient = size > 1 ?
142 (size == 2 ? scaling_list->ScalingListDCCoef16x16[3 * pred + color] :
143 scaling_list->ScalingListDCCoef32x32[pred]) : 0;
144
145 if (size == 0) {
146 for (uint8_t i = 0; i < 4; i++)
147 for (uint8_t j = 0; j < 4; j++)
148 qm.QuantizerMatrix8x8[4 * i + j] =
149 out_sl.ScalingList4x4[3 * pred + color][4 * i + j];
150 } else if (size == 1) {
151 for (uint8_t i = 0; i < 8; i++)
152 for (uint8_t j = 0; j < 8; j++)
153 qm.QuantizerMatrix8x8[8 * i + j] =
154 out_sl.ScalingList8x8[3 * pred + color][8 * i + j];
155 } else if (size == 2) {
156 for (uint8_t i = 0; i < 8; i++)
157 for (uint8_t j = 0; j < 8; j++)
158 qm.QuantizerMatrix8x8[8 * i + j] =
159 out_sl.ScalingList16x16[3 * pred + color][8 * i + j];
160 } else if (size == 3) {
161 for (uint8_t i = 0; i < 8; i++)
162 for (uint8_t j = 0; j < 8; j++)
163 qm.QuantizerMatrix8x8[8 * i + j] =
164 out_sl.ScalingList32x32[pred][8 * i + j];
165 }
166 }
167 }
168 }
169 }
170 }
171
172 static void
anv_h265_decode_video(struct anv_cmd_buffer * cmd_buffer,const VkVideoDecodeInfoKHR * frame_info)173 anv_h265_decode_video(struct anv_cmd_buffer *cmd_buffer,
174 const VkVideoDecodeInfoKHR *frame_info)
175 {
176 ANV_FROM_HANDLE(anv_buffer, src_buffer, frame_info->srcBuffer);
177 struct anv_video_session *vid = cmd_buffer->video.vid;
178 struct anv_video_session_params *params = cmd_buffer->video.params;
179
180 const struct VkVideoDecodeH265PictureInfoKHR *h265_pic_info =
181 vk_find_struct_const(frame_info->pNext, VIDEO_DECODE_H265_PICTURE_INFO_KHR);
182
183 const StdVideoH265SequenceParameterSet *sps =
184 vk_video_find_h265_dec_std_sps(¶ms->vk, h265_pic_info->pStdPictureInfo->pps_seq_parameter_set_id);
185 const StdVideoH265PictureParameterSet *pps =
186 vk_video_find_h265_dec_std_pps(¶ms->vk, h265_pic_info->pStdPictureInfo->pps_pic_parameter_set_id);
187
188 struct vk_video_h265_reference ref_slots[2][8] = { 0 };
189 uint8_t dpb_idx[ANV_VIDEO_H265_MAX_NUM_REF_FRAME] = { 0,};
190 bool is_10bit = sps->bit_depth_chroma_minus8 || sps->bit_depth_luma_minus8;
191
192 anv_batch_emit(&cmd_buffer->batch, GENX(MI_FLUSH_DW), flush) {
193 flush.VideoPipelineCacheInvalidate = 1;
194 };
195
196 #if GFX_VER >= 12
197 anv_batch_emit(&cmd_buffer->batch, GENX(MI_FORCE_WAKEUP), wake) {
198 wake.HEVCPowerWellControl = 1;
199 wake.MaskBits = 768;
200 }
201
202 anv_batch_emit(&cmd_buffer->batch, GENX(VD_CONTROL_STATE), cs) {
203 cs.PipelineInitialization = true;
204 }
205
206 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_WAIT), mfx) {
207 mfx.MFXSyncControlFlag = 1;
208 }
209 #endif
210
211 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_PIPE_MODE_SELECT), sel) {
212 sel.CodecSelect = Decode;
213 sel.CodecStandardSelect = HEVC;
214 }
215
216 #if GFX_VER >= 12
217 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_WAIT), mfx) {
218 mfx.MFXSyncControlFlag = 1;
219 }
220 #endif
221
222 const struct anv_image_view *iv =
223 anv_image_view_from_handle(frame_info->dstPictureResource.imageViewBinding);
224 const struct anv_image *img = iv->image;
225
226 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_SURFACE_STATE), ss) {
227 ss.SurfacePitch = img->planes[0].primary_surface.isl.row_pitch_B - 1;
228 ss.SurfaceID = HCP_CurrentDecodedPicture;
229 ss.SurfaceFormat = is_10bit ? P010 : PLANAR_420_8;
230
231 ss.YOffsetforUCb = img->planes[1].primary_surface.memory_range.offset /
232 img->planes[0].primary_surface.isl.row_pitch_B;
233
234 #if GFX_VER >= 11
235 ss.DefaultAlphaValue = 0xffff;
236 #endif
237 }
238
239 #if GFX_VER >= 12
240 /* Seems to need to set same states to ref as decode on gen12 */
241 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_SURFACE_STATE), ss) {
242 ss.SurfacePitch = img->planes[0].primary_surface.isl.row_pitch_B - 1;
243 ss.SurfaceID = HCP_ReferencePicture;
244 ss.SurfaceFormat = is_10bit ? P010 : PLANAR_420_8;
245
246 ss.YOffsetforUCb = img->planes[1].primary_surface.memory_range.offset /
247 img->planes[0].primary_surface.isl.row_pitch_B;
248
249 ss.DefaultAlphaValue = 0xffff;
250 }
251 #endif
252
253 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_PIPE_BUF_ADDR_STATE), buf) {
254 buf.DecodedPictureAddress =
255 anv_image_address(img, &img->planes[0].primary_surface.memory_range);
256
257 buf.DecodedPictureMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
258 .MOCS = anv_mocs(cmd_buffer->device, buf.DecodedPictureAddress.bo, 0),
259 };
260
261 buf.DeblockingFilterLineBufferAddress = (struct anv_address) {
262 vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_LINE].mem->bo,
263 vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_LINE].offset
264 };
265
266 buf.DeblockingFilterLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
267 .MOCS = anv_mocs(cmd_buffer->device, buf.DeblockingFilterLineBufferAddress.bo, 0),
268 };
269
270 buf.DeblockingFilterTileLineBufferAddress = (struct anv_address) {
271 vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_TILE_LINE].mem->bo,
272 vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_TILE_LINE].offset
273 };
274
275 buf.DeblockingFilterTileLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
276 .MOCS = anv_mocs(cmd_buffer->device, buf.DeblockingFilterTileLineBufferAddress.bo, 0),
277 };
278
279 buf.DeblockingFilterTileColumnBufferAddress = (struct anv_address) {
280 vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_TILE_COLUMN].mem->bo,
281 vid->vid_mem[ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_TILE_COLUMN].offset
282 };
283
284 buf.DeblockingFilterTileColumnBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
285 .MOCS = anv_mocs(cmd_buffer->device, buf.DeblockingFilterTileColumnBufferAddress.bo, 0),
286 };
287
288 buf.MetadataLineBufferAddress = (struct anv_address) {
289 vid->vid_mem[ANV_VID_MEM_H265_METADATA_LINE].mem->bo,
290 vid->vid_mem[ANV_VID_MEM_H265_METADATA_LINE].offset
291 };
292
293 buf.MetadataLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
294 .MOCS = anv_mocs(cmd_buffer->device, buf.MetadataLineBufferAddress.bo, 0),
295 };
296
297 buf.MetadataTileLineBufferAddress = (struct anv_address) {
298 vid->vid_mem[ANV_VID_MEM_H265_METADATA_TILE_LINE].mem->bo,
299 vid->vid_mem[ANV_VID_MEM_H265_METADATA_TILE_LINE].offset
300 };
301
302 buf.MetadataTileLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
303 .MOCS = anv_mocs(cmd_buffer->device, buf.MetadataTileLineBufferAddress.bo, 0),
304 };
305
306 buf.MetadataTileColumnBufferAddress = (struct anv_address) {
307 vid->vid_mem[ANV_VID_MEM_H265_METADATA_TILE_COLUMN].mem->bo,
308 vid->vid_mem[ANV_VID_MEM_H265_METADATA_TILE_COLUMN].offset
309 };
310
311 buf.MetadataTileColumnBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
312 .MOCS = anv_mocs(cmd_buffer->device, buf.MetadataTileColumnBufferAddress.bo, 0),
313 };
314
315 buf.SAOLineBufferAddress = (struct anv_address) {
316 vid->vid_mem[ANV_VID_MEM_H265_SAO_LINE].mem->bo,
317 vid->vid_mem[ANV_VID_MEM_H265_SAO_LINE].offset
318 };
319
320 buf.SAOLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
321 .MOCS = anv_mocs(cmd_buffer->device, buf.SAOLineBufferAddress.bo, 0),
322 };
323
324 buf.SAOTileLineBufferAddress = (struct anv_address) {
325 vid->vid_mem[ANV_VID_MEM_H265_SAO_TILE_LINE].mem->bo,
326 vid->vid_mem[ANV_VID_MEM_H265_SAO_TILE_LINE].offset
327 };
328
329 buf.SAOTileLineBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
330 .MOCS = anv_mocs(cmd_buffer->device, buf.SAOTileLineBufferAddress.bo, 0),
331 };
332
333 buf.SAOTileColumnBufferAddress = (struct anv_address) {
334 vid->vid_mem[ANV_VID_MEM_H265_SAO_TILE_COLUMN].mem->bo,
335 vid->vid_mem[ANV_VID_MEM_H265_SAO_TILE_COLUMN].offset
336 };
337
338 buf.SAOTileColumnBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
339 .MOCS = anv_mocs(cmd_buffer->device, buf.SAOTileColumnBufferAddress.bo, 0),
340 };
341
342 buf.CurrentMVTemporalBufferAddress = anv_image_address(img, &img->vid_dmv_top_surface);
343
344 buf.CurrentMVTemporalBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
345 .MOCS = anv_mocs(cmd_buffer->device, buf.CurrentMVTemporalBufferAddress.bo, 0),
346 };
347
348 for (unsigned i = 0; i < frame_info->referenceSlotCount; i++) {
349 const struct anv_image_view *ref_iv =
350 anv_image_view_from_handle(frame_info->pReferenceSlots[i].pPictureResource->imageViewBinding);
351 int slot_idx = frame_info->pReferenceSlots[i].slotIndex;
352
353 assert(slot_idx < ANV_VIDEO_H265_MAX_NUM_REF_FRAME);
354
355 if (slot_idx < 0)
356 continue;
357 dpb_idx[slot_idx] = i;
358
359 buf.ReferencePictureAddress[i] =
360 anv_image_address(ref_iv->image, &ref_iv->image->planes[0].primary_surface.memory_range);
361 }
362
363 buf.ReferencePictureMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
364 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
365 };
366
367 buf.OriginalUncompressedPictureSourceMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
368 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
369 };
370
371 buf.StreamOutDataDestinationMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
372 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
373 };
374
375 buf.DecodedPictureStatusBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
376 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
377 };
378
379 buf.LCUILDBStreamOutBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
380 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
381 };
382
383 for (unsigned i = 0; i < frame_info->referenceSlotCount; i++) {
384 const struct anv_image_view *ref_iv =
385 anv_image_view_from_handle(frame_info->pReferenceSlots[i].pPictureResource->imageViewBinding);
386
387 buf.CollocatedMVTemporalBufferAddress[i] =
388 anv_image_address(ref_iv->image, &ref_iv->image->vid_dmv_top_surface);
389 }
390
391 buf.CollocatedMVTemporalBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
392 .MOCS = anv_mocs(cmd_buffer->device, buf.CollocatedMVTemporalBufferAddress[0].bo, 0),
393 };
394
395 buf.VP9ProbabilityBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
396 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
397 };
398
399 buf.VP9SegmentIDBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
400 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
401 };
402
403 buf.VP9HVDLineRowStoreBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
404 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
405 };
406
407 buf.VP9HVDTileRowStoreBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
408 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
409 };
410 #if GFX_VER >= 11
411 buf.SAOStreamOutDataDestinationBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
412 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
413 };
414 buf.FrameStatisticsStreamOutDataDestinationBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
415 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
416 };
417 buf.SSESourcePixelRowStoreBufferMemoryAddressAttributesReadWrite = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
418 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
419 };
420 buf.HCPScalabilitySliceStateBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
421 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
422 };
423 buf.HCPScalabilityCABACDecodedSyntaxElementsBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
424 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
425 };
426 buf.MVUpperRightColumnStoreBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
427 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
428 };
429 buf.IntraPredictionUpperRightColumnStoreBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
430 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
431 };
432 buf.IntraPredictionLeftReconColumnStoreBufferMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
433 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
434 };
435 #endif
436 }
437
438 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_IND_OBJ_BASE_ADDR_STATE), indirect) {
439 indirect.HCPIndirectBitstreamObjectBaseAddress =
440 anv_address_add(src_buffer->address, frame_info->srcBufferOffset & ~4095);
441
442 indirect.HCPIndirectBitstreamObjectMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
443 .MOCS = anv_mocs(cmd_buffer->device, src_buffer->address.bo, 0),
444 };
445
446 indirect.HCPIndirectBitstreamObjectAccessUpperBound =
447 anv_address_add(src_buffer->address, align64(frame_info->srcBufferRange, 4096));
448
449 indirect.HCPIndirectCUObjectMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
450 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
451 };
452
453 indirect.HCPPAKBSEObjectMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
454 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
455 };
456
457 #if GFX_VER >= 11
458 indirect.HCPVP9PAKCompressedHeaderSyntaxStreamInMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
459 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
460 };
461 indirect.HCPVP9PAKProbabilityCounterStreamOutMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
462 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
463 };
464 indirect.HCPVP9PAKProbabilityDeltasStreamInMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
465 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
466 };
467 indirect.HCPVP9PAKTileRecordStreamOutMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
468 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
469 };
470 indirect.HCPVP9PAKCULevelStatisticStreamOutMemoryAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
471 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
472 };
473 #endif
474 }
475
476 if (sps->flags.scaling_list_enabled_flag) {
477 if (pps->flags.pps_scaling_list_data_present_flag) {
478 scaling_list(cmd_buffer, pps->pScalingLists);
479 } else if (sps->flags.sps_scaling_list_data_present_flag) {
480 scaling_list(cmd_buffer, sps->pScalingLists);
481 }
482 } else {
483 for (uint8_t size = 0; size < 4; size++) {
484 for (uint8_t pred = 0; pred < 2; pred++) {
485 for (uint8_t color = 0; color < 3; color++) {
486
487 if (size == 3 && color > 0)
488 continue;
489
490 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_QM_STATE), qm) {
491 qm.SizeID = size;
492 qm.PredictionType = pred;
493 qm.ColorComponent = color;
494 qm.DCCoefficient = (size > 1) ? 16 : 0;
495 unsigned len = (size == 0) ? 16 : 64;
496
497 for (uint8_t q = 0; q < len; q++)
498 qm.QuantizerMatrix8x8[q] = 0x10;
499 }
500 }
501 }
502 }
503 }
504
505 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_PIC_STATE), pic) {
506 pic.FrameWidthInMinimumCodingBlockSize =
507 sps->pic_width_in_luma_samples / (1 << (sps->log2_min_luma_coding_block_size_minus3 + 3)) - 1;
508 pic.FrameHeightInMinimumCodingBlockSize =
509 sps->pic_height_in_luma_samples / (1 << (sps->log2_min_luma_coding_block_size_minus3 + 3)) - 1;
510
511 pic.MinCUSize = sps->log2_min_luma_coding_block_size_minus3 & 0x3;
512 pic.LCUSize = (sps->log2_diff_max_min_luma_coding_block_size +
513 sps->log2_min_luma_coding_block_size_minus3) & 0x3;
514
515 pic.MinTUSize = sps->log2_min_luma_transform_block_size_minus2 & 0x3;
516 pic.MaxTUSize = (sps->log2_diff_max_min_luma_transform_block_size + sps->log2_min_luma_transform_block_size_minus2) & 0x3;
517 pic.MinPCMSize = sps->log2_min_pcm_luma_coding_block_size_minus3 & 0x3;
518 pic.MaxPCMSize = (sps->log2_diff_max_min_pcm_luma_coding_block_size + sps->log2_min_pcm_luma_coding_block_size_minus3) & 0x3;
519
520 #if GFX_VER >= 11
521 pic.Log2SAOOffsetScaleLuma = pps->log2_sao_offset_scale_luma;
522 pic.Log2SAOOffsetScaleChroma = pps->log2_sao_offset_scale_chroma;
523 pic.ChromaQPOffsetListLength = pps->chroma_qp_offset_list_len_minus1;
524 pic.DiffCUChromaQPOffsetDepth = pps->diff_cu_chroma_qp_offset_depth;
525 pic.ChromaQPOffsetListEnable = pps->flags.chroma_qp_offset_list_enabled_flag;
526 pic.ChromaSubsampling = sps->chroma_format_idc;
527
528 pic.HighPrecisionOffsetsEnable = sps->flags.high_precision_offsets_enabled_flag;
529 pic.Log2MaxTransformSkipSize = pps->log2_max_transform_skip_block_size_minus2 + 2;
530 pic.CrossComponentPredictionEnable = pps->flags.cross_component_prediction_enabled_flag;
531 pic.CABACBypassAlignmentEnable = sps->flags.cabac_bypass_alignment_enabled_flag;
532 pic.PersistentRiceAdaptationEnable = sps->flags.persistent_rice_adaptation_enabled_flag;
533 pic.IntraSmoothingDisable = sps->flags.intra_smoothing_disabled_flag;
534 pic.ExplicitRDPCMEnable = sps->flags.explicit_rdpcm_enabled_flag;
535 pic.ImplicitRDPCMEnable = sps->flags.implicit_rdpcm_enabled_flag;
536 pic.TransformSkipContextEnable = sps->flags.transform_skip_context_enabled_flag;
537 pic.TransformSkipRotationEnable = sps->flags.transform_skip_rotation_enabled_flag;
538 pic.SPSRangeExtensionEnable = sps->flags.sps_range_extension_flag;
539 #endif
540
541 pic.CollocatedPictureIsISlice = false;
542 pic.CurrentPictureIsISlice = false;
543 pic.SampleAdaptiveOffsetEnable = sps->flags.sample_adaptive_offset_enabled_flag;
544 pic.PCMEnable = sps->flags.pcm_enabled_flag;
545 pic.CUQPDeltaEnable = pps->flags.cu_qp_delta_enabled_flag;
546 pic.MaxDQPDepth = pps->diff_cu_qp_delta_depth;
547 pic.PCMLoopFilterDisable = sps->flags.pcm_loop_filter_disabled_flag;
548 pic.ConstrainedIntraPrediction = pps->flags.constrained_intra_pred_flag;
549 pic.Log2ParallelMergeLevel = pps->log2_parallel_merge_level_minus2;
550 pic.SignDataHiding = pps->flags.sign_data_hiding_enabled_flag;
551 pic.LoopFilterEnable = pps->flags.loop_filter_across_tiles_enabled_flag;
552 pic.EntropyCodingSyncEnable = pps->flags.entropy_coding_sync_enabled_flag;
553 pic.TilingEnable = pps->flags.tiles_enabled_flag;
554 pic.WeightedBiPredicationEnable = pps->flags.weighted_bipred_flag;
555 pic.WeightedPredicationEnable = pps->flags.weighted_pred_flag;
556 pic.FieldPic = 0;
557 pic.TopField = true;
558 pic.TransformSkipEnable = pps->flags.transform_skip_enabled_flag;
559 pic.AMPEnable = sps->flags.amp_enabled_flag;
560 pic.TransquantBypassEnable = pps->flags.transquant_bypass_enabled_flag;
561 pic.StrongIntraSmoothingEnable = sps->flags.strong_intra_smoothing_enabled_flag;
562 pic.CUPacketStructure = 0;
563
564 pic.PictureCbQPOffset = pps->pps_cb_qp_offset;
565 pic.PictureCrQPOffset = pps->pps_cr_qp_offset;
566 pic.IntraMaxTransformHierarchyDepth = sps->max_transform_hierarchy_depth_intra;
567 pic.InterMaxTransformHierarchyDepth = sps->max_transform_hierarchy_depth_inter;
568 pic.ChromaPCMSampleBitDepth = sps->pcm_sample_bit_depth_chroma_minus1 & 0xf;
569 pic.LumaPCMSampleBitDepth = sps->pcm_sample_bit_depth_luma_minus1 & 0xf;
570
571 pic.ChromaBitDepth = sps->bit_depth_chroma_minus8;
572 pic.LumaBitDepth = sps->bit_depth_luma_minus8;
573
574 #if GFX_VER >= 11
575 pic.CbQPOffsetList0 = pps->cb_qp_offset_list[0];
576 pic.CbQPOffsetList1 = pps->cb_qp_offset_list[1];
577 pic.CbQPOffsetList2 = pps->cb_qp_offset_list[2];
578 pic.CbQPOffsetList3 = pps->cb_qp_offset_list[3];
579 pic.CbQPOffsetList4 = pps->cb_qp_offset_list[4];
580 pic.CbQPOffsetList5 = pps->cb_qp_offset_list[5];
581
582 pic.CrQPOffsetList0 = pps->cr_qp_offset_list[0];
583 pic.CrQPOffsetList1 = pps->cr_qp_offset_list[1];
584 pic.CrQPOffsetList2 = pps->cr_qp_offset_list[2];
585 pic.CrQPOffsetList3 = pps->cr_qp_offset_list[3];
586 pic.CrQPOffsetList4 = pps->cr_qp_offset_list[4];
587 pic.CrQPOffsetList5 = pps->cr_qp_offset_list[5];
588 #endif
589 }
590
591 if (pps->flags.tiles_enabled_flag) {
592 int cum = 0;
593 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_TILE_STATE), tile) {
594 tile.NumberofTileColumns = pps->num_tile_columns_minus1;
595 tile.NumberofTileRows = pps->num_tile_rows_minus1;
596 for (unsigned i = 0; i < 5; i++) {
597 tile.ColumnPosition[i].CtbPos0i = cum;
598 if ((4 * i) == pps->num_tile_columns_minus1)
599 break;
600
601 cum += pps->column_width_minus1[4 * i] + 1;
602 tile.ColumnPosition[i].CtbPos1i = cum;
603
604 if ((4 * i + 1) == pps->num_tile_columns_minus1)
605 break;
606 cum += pps->column_width_minus1[4 * i + 1] + 1;
607 tile.ColumnPosition[i].CtbPos2i = cum;
608
609 if ((4 * i + 2) == pps->num_tile_columns_minus1)
610 break;
611 cum += pps->column_width_minus1[4 * i + 2] + 1;
612 tile.ColumnPosition[i].CtbPos3i = cum;
613
614 if ((4 * i + 3) >= MIN2(pps->num_tile_columns_minus1,
615 ARRAY_SIZE(pps->column_width_minus1)))
616 break;
617
618 cum += pps->column_width_minus1[4 * i + 3] + 1;
619 }
620
621 cum = 0;
622
623 for (unsigned i = 0; i < 5; i++) {
624 tile.Rowposition[i].CtbPos0i = cum;
625 if ((4 * i) == pps->num_tile_rows_minus1)
626 break;
627
628 cum += pps->row_height_minus1[4 * i] + 1;
629 tile.Rowposition[i].CtbPos1i = cum;
630
631 if ((4 * i + 1) == pps->num_tile_rows_minus1)
632 break;
633 cum += pps->row_height_minus1[4 * i + 1] + 1;
634 tile.Rowposition[i].CtbPos2i = cum;
635
636 if ((4 * i + 2) == pps->num_tile_rows_minus1)
637 break;
638 cum += pps->row_height_minus1[4 * i + 2] + 1;
639 tile.Rowposition[i].CtbPos3i = cum;
640
641 if ((4 * i + 3) == pps->num_tile_rows_minus1)
642 break;
643
644 cum += pps->row_height_minus1[4 * i + 3] + 1;
645 }
646
647 if (pps->num_tile_rows_minus1 == 20) {
648 tile.Rowposition[5].CtbPos0i = cum;
649 }
650 if (pps->num_tile_rows_minus1 == 20) {
651 tile.Rowposition[5].CtbPos0i = cum;
652 cum += pps->row_height_minus1[20] + 1;
653 tile.Rowposition[5].CtbPos1i = cum;
654 }
655 }
656 }
657
658 /* Slice parsing */
659 uint32_t last_slice = h265_pic_info->sliceSegmentCount - 1;
660 void *slice_map;
661 VkResult result =
662 anv_device_map_bo(cmd_buffer->device,
663 src_buffer->address.bo,
664 src_buffer->address.offset,
665 frame_info->srcBufferRange + frame_info->srcBufferOffset,
666 NULL /* placed_addr */,
667 &slice_map);
668 if (result != VK_SUCCESS) {
669 anv_batch_set_error(&cmd_buffer->batch, result);
670 return;
671 }
672
673 slice_map += frame_info->srcBufferOffset;
674
675 struct vk_video_h265_slice_params slice_params[h265_pic_info->sliceSegmentCount];
676
677 /* All slices should be parsed in advance to collect information necessary */
678 for (unsigned s = 0; s < h265_pic_info->sliceSegmentCount; s++) {
679 uint32_t current_offset = h265_pic_info->pSliceSegmentOffsets[s];
680 void *map = slice_map + current_offset;
681 uint32_t slice_size = 0;
682
683 if (s == last_slice)
684 slice_size = frame_info->srcBufferRange - current_offset;
685 else
686 slice_size = h265_pic_info->pSliceSegmentOffsets[s + 1] - current_offset;
687
688 vk_video_parse_h265_slice_header(frame_info, h265_pic_info, sps, pps, map, slice_size, &slice_params[s]);
689 vk_fill_video_h265_reference_info(frame_info, h265_pic_info, &slice_params[s], ref_slots);
690 }
691
692 anv_device_unmap_bo(cmd_buffer->device, src_buffer->address.bo,
693 slice_map, frame_info->srcBufferRange,
694 false /* replace */);
695
696 for (unsigned s = 0; s < h265_pic_info->sliceSegmentCount; s++) {
697 uint32_t ctb_size = 1 << (sps->log2_diff_max_min_luma_coding_block_size +
698 sps->log2_min_luma_coding_block_size_minus3 + 3);
699 uint32_t pic_width_in_min_cbs_y = sps->pic_width_in_luma_samples /
700 (1 << (sps->log2_min_luma_coding_block_size_minus3 + 3));
701 uint32_t width_in_pix = (1 << (sps->log2_min_luma_coding_block_size_minus3 + 3)) *
702 pic_width_in_min_cbs_y;
703 uint32_t ctb_w = DIV_ROUND_UP(width_in_pix, ctb_size);
704 bool is_last = (s == last_slice);
705 int slice_qp = (slice_params[s].slice_qp_delta + pps->init_qp_minus26 + 26) & 0x3f;
706
707 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_SLICE_STATE), slice) {
708 slice.SliceHorizontalPosition = slice_params[s].slice_segment_address % ctb_w;
709 slice.SliceVerticalPosition = slice_params[s].slice_segment_address / ctb_w;
710
711 if (is_last) {
712 slice.NextSliceHorizontalPosition = 0;
713 slice.NextSliceVerticalPosition = 0;
714 } else {
715 slice.NextSliceHorizontalPosition = (slice_params[s + 1].slice_segment_address) % ctb_w;
716 slice.NextSliceVerticalPosition = (slice_params[s + 1].slice_segment_address) / ctb_w;
717 }
718
719 slice.SliceType = slice_params[s].slice_type;
720 slice.LastSlice = is_last;
721 slice.DependentSlice = slice_params[s].dependent_slice_segment;
722 slice.SliceTemporalMVPEnable = slice_params[s].temporal_mvp_enable;
723 slice.SliceQP = abs(slice_qp);
724 slice.SliceQPSign = slice_qp >= 0 ? 0 : 1;
725 slice.SliceCbQPOffset = slice_params[s].slice_cb_qp_offset;
726 slice.SliceCrQPOffset = slice_params[s].slice_cr_qp_offset;
727 slice.SliceHeaderDisableDeblockingFilter = pps->flags.deblocking_filter_override_enabled_flag ?
728 slice_params[s].disable_deblocking_filter_idc : pps->flags.pps_deblocking_filter_disabled_flag;
729 slice.SliceTCOffsetDiv2 = slice_params[s].tc_offset_div2;
730 slice.SliceBetaOffsetDiv2 = slice_params[s].beta_offset_div2;
731 slice.SliceLoopFilterEnable = slice_params[s].loop_filter_across_slices_enable;
732 slice.SliceSAOChroma = slice_params[s].sao_chroma_flag;
733 slice.SliceSAOLuma = slice_params[s].sao_luma_flag;
734 slice.MVDL1Zero = slice_params[s].mvd_l1_zero_flag;
735
736 uint8_t low_delay = true;
737
738 if (slice_params[s].slice_type == STD_VIDEO_H265_SLICE_TYPE_I) {
739 low_delay = false;
740 } else {
741 for (unsigned i = 0; i < slice_params[s].num_ref_idx_l0_active; i++) {
742 int slot_idx = ref_slots[0][i].slot_index;
743
744 if (vk_video_h265_poc_by_slot(frame_info, slot_idx) >
745 h265_pic_info->pStdPictureInfo->PicOrderCntVal) {
746 low_delay = false;
747 break;
748 }
749 }
750
751 for (unsigned i = 0; i < slice_params[s].num_ref_idx_l1_active; i++) {
752 int slot_idx = ref_slots[1][i].slot_index;
753 if (vk_video_h265_poc_by_slot(frame_info, slot_idx) >
754 h265_pic_info->pStdPictureInfo->PicOrderCntVal) {
755 low_delay = false;
756 break;
757 }
758 }
759 }
760
761 slice.LowDelay = low_delay;
762 slice.CollocatedFromL0 = slice_params[s].collocated_list == 0 ? true : false;
763 slice.Log2WeightDenominatorChroma = slice_params[s].luma_log2_weight_denom +
764 (slice_params[s].chroma_log2_weight_denom - slice_params[s].luma_log2_weight_denom);
765 slice.Log2WeightDenominatorLuma = slice_params[s].luma_log2_weight_denom;
766 slice.CABACInit = slice_params[s].cabac_init_idc;
767 slice.MaxMergeIndex = slice_params[s].max_num_merge_cand - 1;
768 slice.CollocatedMVTemporalBufferIndex =
769 dpb_idx[ref_slots[slice_params[s].collocated_list][slice_params[s].collocated_ref_idx].slot_index];
770 assert(slice.CollocatedMVTemporalBufferIndex < ANV_VIDEO_H265_HCP_NUM_REF_FRAME);
771
772 slice.SliceHeaderLength = slice_params[s].slice_data_bytes_offset;
773 slice.CABACZeroWordInsertionEnable = false;
774 slice.EmulationByteSliceInsertEnable = false;
775 slice.TailInsertionPresent = false;
776 slice.SliceDataInsertionPresent = false;
777 slice.HeaderInsertionPresent = false;
778
779 slice.IndirectPAKBSEDataStartOffset = 0;
780 slice.TransformSkipLambda = 0;
781 slice.TransformSkipNumberofNonZeroCoeffsFactor0 = 0;
782 slice.TransformSkipNumberofZeroCoeffsFactor0 = 0;
783 slice.TransformSkipNumberofNonZeroCoeffsFactor1 = 0;
784 slice.TransformSkipNumberofZeroCoeffsFactor1 = 0;
785
786 #if GFX_VER >= 12
787 slice.OriginalSliceStartCtbX = slice_params[s].slice_segment_address % ctb_w;
788 slice.OriginalSliceStartCtbY = slice_params[s].slice_segment_address / ctb_w;
789 #endif
790 }
791
792 if (slice_params[s].slice_type != STD_VIDEO_H265_SLICE_TYPE_I) {
793 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_REF_IDX_STATE), ref) {
794 ref.ReferencePictureListSelect = 0;
795 ref.NumberofReferenceIndexesActive = slice_params[s].num_ref_idx_l0_active - 1;
796
797 for (unsigned i = 0; i < ref.NumberofReferenceIndexesActive + 1; i++) {
798 int slot_idx = ref_slots[0][i].slot_index;
799 unsigned poc = ref_slots[0][i].pic_order_cnt;
800 int32_t diff_poc = h265_pic_info->pStdPictureInfo->PicOrderCntVal - poc;
801
802 assert(dpb_idx[slot_idx] < ANV_VIDEO_H265_HCP_NUM_REF_FRAME);
803
804 ref.ReferenceListEntry[i].ListEntry = dpb_idx[slot_idx];
805 ref.ReferenceListEntry[i].ReferencePicturetbValue = CLAMP(diff_poc, -128, 127) & 0xff;
806 ref.ReferenceListEntry[i].TopField = true;
807 }
808 }
809 }
810
811 if (slice_params[s].slice_type == STD_VIDEO_H265_SLICE_TYPE_B) {
812 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_REF_IDX_STATE), ref) {
813 ref.ReferencePictureListSelect = 1;
814 ref.NumberofReferenceIndexesActive = slice_params[s].num_ref_idx_l1_active - 1;
815
816 for (unsigned i = 0; i < ref.NumberofReferenceIndexesActive + 1; i++) {
817 int slot_idx = ref_slots[1][i].slot_index;;
818 unsigned poc = ref_slots[1][i].pic_order_cnt;
819 int32_t diff_poc = h265_pic_info->pStdPictureInfo->PicOrderCntVal - poc;
820
821 assert(dpb_idx[slot_idx] < ANV_VIDEO_H265_HCP_NUM_REF_FRAME);
822
823 ref.ReferenceListEntry[i].ListEntry = dpb_idx[slot_idx];
824 ref.ReferenceListEntry[i].ReferencePicturetbValue = CLAMP(diff_poc, -128, 127) & 0xff;
825 ref.ReferenceListEntry[i].TopField = true;
826 }
827 }
828 }
829
830 if ((pps->flags.weighted_pred_flag && (slice_params[s].slice_type == STD_VIDEO_H265_SLICE_TYPE_P)) ||
831 (pps->flags.weighted_bipred_flag && (slice_params[s].slice_type == STD_VIDEO_H265_SLICE_TYPE_B))) {
832 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_WEIGHTOFFSET_STATE), w) {
833 w.ReferencePictureListSelect = 0;
834
835 for (unsigned i = 0; i < ANV_VIDEO_H265_MAX_NUM_REF_FRAME; i++) {
836 w.LumaOffsets[i].DeltaLumaWeightLX = slice_params[s].delta_luma_weight_l0[i] & 0xff;
837 w.LumaOffsets[i].LumaOffsetLX = slice_params[s].luma_offset_l0[i] & 0xff;
838 w.ChromaOffsets[i].DeltaChromaWeightLX0 = slice_params[s].delta_chroma_weight_l0[i][0] & 0xff;
839 w.ChromaOffsets[i].ChromaOffsetLX0 = slice_params[s].chroma_offset_l0[i][0] & 0xff;
840 w.ChromaOffsets[i].DeltaChromaWeightLX1 = slice_params[s].delta_chroma_weight_l0[i][1] & 0xff;
841 w.ChromaOffsets[i].ChromaOffsetLX1 = slice_params[s].chroma_offset_l0[i][1] & 0xff;
842 }
843 }
844
845 if (slice_params[s].slice_type == STD_VIDEO_H265_SLICE_TYPE_B) {
846 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_WEIGHTOFFSET_STATE), w) {
847 w.ReferencePictureListSelect = 1;
848
849 for (unsigned i = 0; i < ANV_VIDEO_H265_MAX_NUM_REF_FRAME; i++) {
850 w.LumaOffsets[i].DeltaLumaWeightLX = slice_params[s].delta_luma_weight_l1[i] & 0xff;
851 w.LumaOffsets[i].LumaOffsetLX = slice_params[s].luma_offset_l1[i] & 0xff;
852 w.ChromaOffsets[i].DeltaChromaWeightLX0 = slice_params[s].delta_chroma_weight_l1[i][0] & 0xff;
853 w.ChromaOffsets[i].DeltaChromaWeightLX1 = slice_params[s].delta_chroma_weight_l1[i][1] & 0xff;
854 w.ChromaOffsets[i].ChromaOffsetLX0 = slice_params[s].chroma_offset_l1[i][0] & 0xff;
855 w.ChromaOffsets[i].ChromaOffsetLX1 = slice_params[s].chroma_offset_l1[i][1] & 0xff;
856 }
857 }
858 }
859 }
860
861 uint32_t buffer_offset = frame_info->srcBufferOffset & 4095;
862
863 anv_batch_emit(&cmd_buffer->batch, GENX(HCP_BSD_OBJECT), bsd) {
864 bsd.IndirectBSDDataLength = slice_params[s].slice_size - 3;
865 bsd.IndirectBSDDataStartAddress = buffer_offset + h265_pic_info->pSliceSegmentOffsets[s] + 3;
866 }
867 }
868
869 #if GFX_VER >= 12
870 anv_batch_emit(&cmd_buffer->batch, GENX(VD_CONTROL_STATE), cs) {
871 cs.MemoryImplicitFlush = true;
872 }
873 #endif
874
875 anv_batch_emit(&cmd_buffer->batch, GENX(VD_PIPELINE_FLUSH), flush) {
876 flush.HEVCPipelineDone = true;
877 flush.HEVCPipelineCommandFlush = true;
878 flush.VDCommandMessageParserDone = true;
879 }
880 }
881
882 static void
anv_h264_decode_video(struct anv_cmd_buffer * cmd_buffer,const VkVideoDecodeInfoKHR * frame_info)883 anv_h264_decode_video(struct anv_cmd_buffer *cmd_buffer,
884 const VkVideoDecodeInfoKHR *frame_info)
885 {
886 ANV_FROM_HANDLE(anv_buffer, src_buffer, frame_info->srcBuffer);
887 struct anv_video_session *vid = cmd_buffer->video.vid;
888 struct anv_video_session_params *params = cmd_buffer->video.params;
889 const struct VkVideoDecodeH264PictureInfoKHR *h264_pic_info =
890 vk_find_struct_const(frame_info->pNext, VIDEO_DECODE_H264_PICTURE_INFO_KHR);
891 const StdVideoH264SequenceParameterSet *sps = vk_video_find_h264_dec_std_sps(¶ms->vk, h264_pic_info->pStdPictureInfo->seq_parameter_set_id);
892 const StdVideoH264PictureParameterSet *pps = vk_video_find_h264_dec_std_pps(¶ms->vk, h264_pic_info->pStdPictureInfo->pic_parameter_set_id);
893
894 uint8_t dpb_slots[ANV_VIDEO_H264_MAX_DPB_SLOTS] = { 0,};
895
896 anv_batch_emit(&cmd_buffer->batch, GENX(MI_FLUSH_DW), flush) {
897 flush.DWordLength = 2;
898 flush.VideoPipelineCacheInvalidate = 1;
899 };
900
901 #if GFX_VER >= 12
902 anv_batch_emit(&cmd_buffer->batch, GENX(MI_FORCE_WAKEUP), wake) {
903 wake.MFXPowerWellControl = 1;
904 wake.MaskBits = 768;
905 }
906
907 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_WAIT), mfx) {
908 mfx.MFXSyncControlFlag = 1;
909 }
910 #endif
911
912 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_PIPE_MODE_SELECT), sel) {
913 sel.StandardSelect = SS_AVC;
914 sel.CodecSelect = Decode;
915 sel.DecoderShortFormatMode = ShortFormatDriverInterface;
916 sel.DecoderModeSelect = VLDMode; // Hardcoded
917
918 sel.PreDeblockingOutputEnable = 0;
919 sel.PostDeblockingOutputEnable = 1;
920 }
921
922 #if GFX_VER >= 12
923 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_WAIT), mfx) {
924 mfx.MFXSyncControlFlag = 1;
925 }
926 #endif
927
928 const struct anv_image_view *iv = anv_image_view_from_handle(frame_info->dstPictureResource.imageViewBinding);
929 const struct anv_image *img = iv->image;
930 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_SURFACE_STATE), ss) {
931 ss.Width = img->vk.extent.width - 1;
932 ss.Height = img->vk.extent.height - 1;
933 ss.SurfaceFormat = PLANAR_420_8; // assert on this?
934 ss.InterleaveChroma = 1;
935 ss.SurfacePitch = img->planes[0].primary_surface.isl.row_pitch_B - 1;
936 ss.TiledSurface = img->planes[0].primary_surface.isl.tiling != ISL_TILING_LINEAR;
937 ss.TileWalk = TW_YMAJOR;
938
939 ss.YOffsetforUCb = ss.YOffsetforVCr =
940 img->planes[1].primary_surface.memory_range.offset / img->planes[0].primary_surface.isl.row_pitch_B;
941 }
942
943 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_PIPE_BUF_ADDR_STATE), buf) {
944 bool use_pre_deblock = false;
945 if (use_pre_deblock) {
946 buf.PreDeblockingDestinationAddress = anv_image_address(img,
947 &img->planes[0].primary_surface.memory_range);
948 } else {
949 buf.PostDeblockingDestinationAddress = anv_image_address(img,
950 &img->planes[0].primary_surface.memory_range);
951 }
952 buf.PreDeblockingDestinationAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
953 .MOCS = anv_mocs(cmd_buffer->device, buf.PreDeblockingDestinationAddress.bo, 0),
954 };
955 buf.PostDeblockingDestinationAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
956 .MOCS = anv_mocs(cmd_buffer->device, buf.PostDeblockingDestinationAddress.bo, 0),
957 };
958
959 buf.IntraRowStoreScratchBufferAddress = (struct anv_address) { vid->vid_mem[ANV_VID_MEM_H264_INTRA_ROW_STORE].mem->bo, vid->vid_mem[ANV_VID_MEM_H264_INTRA_ROW_STORE].offset };
960 buf.IntraRowStoreScratchBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
961 .MOCS = anv_mocs(cmd_buffer->device, buf.IntraRowStoreScratchBufferAddress.bo, 0),
962 };
963 buf.DeblockingFilterRowStoreScratchAddress = (struct anv_address) { vid->vid_mem[ANV_VID_MEM_H264_DEBLOCK_FILTER_ROW_STORE].mem->bo, vid->vid_mem[ANV_VID_MEM_H264_DEBLOCK_FILTER_ROW_STORE].offset };
964 buf.DeblockingFilterRowStoreScratchAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
965 .MOCS = anv_mocs(cmd_buffer->device, buf.DeblockingFilterRowStoreScratchAddress.bo, 0),
966 };
967 buf.MBStatusBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
968 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
969 };
970 buf.MBILDBStreamOutBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
971 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
972 };
973 buf.SecondMBILDBStreamOutBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
974 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
975 };
976 buf.ScaledReferenceSurfaceAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
977 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
978 };
979 buf.OriginalUncompressedPictureSourceAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
980 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
981 };
982 buf.StreamOutDataDestinationAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
983 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
984 };
985
986 struct anv_bo *ref_bo = NULL;
987 for (unsigned i = 0; i < frame_info->referenceSlotCount; i++) {
988 const struct anv_image_view *ref_iv = anv_image_view_from_handle(frame_info->pReferenceSlots[i].pPictureResource->imageViewBinding);
989 int idx = frame_info->pReferenceSlots[i].slotIndex;
990
991 assert(idx < ANV_VIDEO_H264_MAX_DPB_SLOTS);
992
993 if (idx < 0)
994 continue;
995
996 dpb_slots[idx] = i;
997
998 buf.ReferencePictureAddress[i] = anv_image_address(ref_iv->image,
999 &ref_iv->image->planes[0].primary_surface.memory_range);
1000
1001 if (i == 0) {
1002 ref_bo = ref_iv->image->bindings[0].address.bo;
1003 }
1004 }
1005 buf.ReferencePictureAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1006 .MOCS = anv_mocs(cmd_buffer->device, ref_bo, 0),
1007 };
1008 }
1009
1010 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_IND_OBJ_BASE_ADDR_STATE), index_obj) {
1011 index_obj.MFXIndirectBitstreamObjectAddress = anv_address_add(src_buffer->address,
1012 frame_info->srcBufferOffset & ~4095);
1013 index_obj.MFXIndirectBitstreamObjectAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1014 .MOCS = anv_mocs(cmd_buffer->device, src_buffer->address.bo, 0),
1015 };
1016 index_obj.MFXIndirectMVObjectAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1017 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1018 };
1019 index_obj.MFDIndirectITCOEFFObjectAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1020 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1021 };
1022 index_obj.MFDIndirectITDBLKObjectAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1023 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1024 };
1025 index_obj.MFCIndirectPAKBSEObjectAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1026 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1027 };
1028 }
1029
1030 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_BSP_BUF_BASE_ADDR_STATE), bsp) {
1031 bsp.BSDMPCRowStoreScratchBufferAddress = (struct anv_address) { vid->vid_mem[ANV_VID_MEM_H264_BSD_MPC_ROW_SCRATCH].mem->bo,
1032 vid->vid_mem[ANV_VID_MEM_H264_BSD_MPC_ROW_SCRATCH].offset };
1033
1034 bsp.BSDMPCRowStoreScratchBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1035 .MOCS = anv_mocs(cmd_buffer->device, bsp.BSDMPCRowStoreScratchBufferAddress.bo, 0),
1036 };
1037 bsp.MPRRowStoreScratchBufferAddress = (struct anv_address) { vid->vid_mem[ANV_VID_MEM_H264_MPR_ROW_SCRATCH].mem->bo,
1038 vid->vid_mem[ANV_VID_MEM_H264_MPR_ROW_SCRATCH].offset };
1039
1040 bsp.MPRRowStoreScratchBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1041 .MOCS = anv_mocs(cmd_buffer->device, bsp.MPRRowStoreScratchBufferAddress.bo, 0),
1042 };
1043 bsp.BitplaneReadBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1044 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1045 };
1046 }
1047
1048 anv_batch_emit(&cmd_buffer->batch, GENX(MFD_AVC_DPB_STATE), avc_dpb) {
1049 for (unsigned i = 0; i < frame_info->referenceSlotCount; i++) {
1050 const struct VkVideoDecodeH264DpbSlotInfoKHR *dpb_slot =
1051 vk_find_struct_const(frame_info->pReferenceSlots[i].pNext, VIDEO_DECODE_H264_DPB_SLOT_INFO_KHR);
1052 const StdVideoDecodeH264ReferenceInfo *ref_info = dpb_slot->pStdReferenceInfo;
1053
1054 if (frame_info->pReferenceSlots[i].slotIndex < 0)
1055 continue;
1056
1057 int idx = dpb_slots[frame_info->pReferenceSlots[i].slotIndex];
1058
1059 avc_dpb.NonExistingFrame[idx] = ref_info->flags.is_non_existing;
1060 avc_dpb.LongTermFrame[idx] = ref_info->flags.used_for_long_term_reference;
1061 if (!ref_info->flags.top_field_flag && !ref_info->flags.bottom_field_flag)
1062 avc_dpb.UsedforReference[idx] = 3;
1063 else
1064 avc_dpb.UsedforReference[idx] = ref_info->flags.top_field_flag | (ref_info->flags.bottom_field_flag << 1);
1065 avc_dpb.LTSTFrameNumberList[idx] = ref_info->FrameNum;
1066 }
1067 }
1068
1069 anv_batch_emit(&cmd_buffer->batch, GENX(MFD_AVC_PICID_STATE), picid) {
1070 unsigned i = 0;
1071 picid.PictureIDRemappingDisable = false;
1072
1073 for (i = 0; i < frame_info->referenceSlotCount; i++)
1074 picid.PictureID[i] = frame_info->pReferenceSlots[i].slotIndex;
1075
1076 for (; i < ANV_VIDEO_H264_MAX_NUM_REF_FRAME; i++)
1077 picid.PictureID[i] = 0xffff;
1078 }
1079
1080 uint32_t pic_height = sps->pic_height_in_map_units_minus1 + 1;
1081 if (!sps->flags.frame_mbs_only_flag)
1082 pic_height *= 2;
1083 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_AVC_IMG_STATE), avc_img) {
1084 avc_img.FrameWidth = sps->pic_width_in_mbs_minus1;
1085 avc_img.FrameHeight = pic_height - 1;
1086 avc_img.FrameSize = (sps->pic_width_in_mbs_minus1 + 1) * pic_height;
1087
1088 if (!h264_pic_info->pStdPictureInfo->flags.field_pic_flag)
1089 avc_img.ImageStructure = FramePicture;
1090 else if (h264_pic_info->pStdPictureInfo->flags.bottom_field_flag)
1091 avc_img.ImageStructure = BottomFieldPicture;
1092 else
1093 avc_img.ImageStructure = TopFieldPicture;
1094
1095 avc_img.WeightedBiPredictionIDC = pps->weighted_bipred_idc;
1096 avc_img.WeightedPredictionEnable = pps->flags.weighted_pred_flag;
1097 avc_img.FirstChromaQPOffset = pps->chroma_qp_index_offset;
1098 avc_img.SecondChromaQPOffset = pps->second_chroma_qp_index_offset;
1099 avc_img.FieldPicture = h264_pic_info->pStdPictureInfo->flags.field_pic_flag;
1100 avc_img.MBAFFMode = (sps->flags.mb_adaptive_frame_field_flag &&
1101 !h264_pic_info->pStdPictureInfo->flags.field_pic_flag);
1102 avc_img.FrameMBOnly = sps->flags.frame_mbs_only_flag;
1103 avc_img._8x8IDCTTransformMode = pps->flags.transform_8x8_mode_flag;
1104 avc_img.Direct8x8Inference = sps->flags.direct_8x8_inference_flag;
1105 avc_img.ConstrainedIntraPrediction = pps->flags.constrained_intra_pred_flag;
1106 avc_img.NonReferencePicture = !h264_pic_info->pStdPictureInfo->flags.is_reference;
1107 avc_img.EntropyCodingSyncEnable = pps->flags.entropy_coding_mode_flag;
1108 avc_img.ChromaFormatIDC = sps->chroma_format_idc;
1109 avc_img.TrellisQuantizationChromaDisable = true;
1110 avc_img.NumberofReferenceFrames = frame_info->referenceSlotCount;
1111 avc_img.NumberofActiveReferencePicturesfromL0 = pps->num_ref_idx_l0_default_active_minus1 + 1;
1112 avc_img.NumberofActiveReferencePicturesfromL1 = pps->num_ref_idx_l1_default_active_minus1 + 1;
1113 avc_img.InitialQPValue = pps->pic_init_qp_minus26;
1114 avc_img.PicOrderPresent = pps->flags.bottom_field_pic_order_in_frame_present_flag;
1115 avc_img.DeltaPicOrderAlwaysZero = sps->flags.delta_pic_order_always_zero_flag;
1116 avc_img.PicOrderCountType = sps->pic_order_cnt_type;
1117 avc_img.DeblockingFilterControlPresent = pps->flags.deblocking_filter_control_present_flag;
1118 avc_img.RedundantPicCountPresent = pps->flags.redundant_pic_cnt_present_flag;
1119 avc_img.Log2MaxFrameNumber = sps->log2_max_frame_num_minus4;
1120 avc_img.Log2MaxPicOrderCountLSB = sps->log2_max_pic_order_cnt_lsb_minus4;
1121 avc_img.CurrentPictureFrameNumber = h264_pic_info->pStdPictureInfo->frame_num;
1122 }
1123
1124 StdVideoH264ScalingLists scaling_lists;
1125 vk_video_derive_h264_scaling_list(sps, pps, &scaling_lists);
1126 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_QM_STATE), qm) {
1127 qm.DWordLength = 16;
1128 qm.AVC = AVC_4x4_Intra_MATRIX;
1129 for (unsigned m = 0; m < 3; m++)
1130 for (unsigned q = 0; q < 16; q++)
1131 qm.ForwardQuantizerMatrix[m * 16 + vl_zscan_normal_16[q]] = scaling_lists.ScalingList4x4[m][q];
1132 }
1133 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_QM_STATE), qm) {
1134 qm.DWordLength = 16;
1135 qm.AVC = AVC_4x4_Inter_MATRIX;
1136 for (unsigned m = 0; m < 3; m++)
1137 for (unsigned q = 0; q < 16; q++)
1138 qm.ForwardQuantizerMatrix[m * 16 + vl_zscan_normal_16[q]] = scaling_lists.ScalingList4x4[m + 3][q];
1139 }
1140 if (pps->flags.transform_8x8_mode_flag) {
1141 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_QM_STATE), qm) {
1142 qm.DWordLength = 16;
1143 qm.AVC = AVC_8x8_Intra_MATRIX;
1144 for (unsigned q = 0; q < 64; q++)
1145 qm.ForwardQuantizerMatrix[vl_zscan_normal[q]] = scaling_lists.ScalingList8x8[0][q];
1146 }
1147 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_QM_STATE), qm) {
1148 qm.DWordLength = 16;
1149 qm.AVC = AVC_8x8_Inter_MATRIX;
1150 for (unsigned q = 0; q < 64; q++)
1151 qm.ForwardQuantizerMatrix[vl_zscan_normal[q]] = scaling_lists.ScalingList8x8[1][q];
1152 }
1153 }
1154
1155 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_AVC_DIRECTMODE_STATE), avc_directmode) {
1156 /* bind reference frame DMV */
1157 struct anv_bo *dmv_bo = NULL;
1158 for (unsigned i = 0; i < frame_info->referenceSlotCount; i++) {
1159 if (frame_info->pReferenceSlots[i].slotIndex < 0)
1160 continue;
1161
1162 int idx = dpb_slots[frame_info->pReferenceSlots[i].slotIndex];
1163
1164 const struct VkVideoDecodeH264DpbSlotInfoKHR *dpb_slot =
1165 vk_find_struct_const(frame_info->pReferenceSlots[i].pNext, VIDEO_DECODE_H264_DPB_SLOT_INFO_KHR);
1166 const struct anv_image_view *ref_iv = anv_image_view_from_handle(frame_info->pReferenceSlots[i].pPictureResource->imageViewBinding);
1167 const StdVideoDecodeH264ReferenceInfo *ref_info = dpb_slot->pStdReferenceInfo;
1168 avc_directmode.DirectMVBufferAddress[idx] = anv_image_address(ref_iv->image,
1169 &ref_iv->image->vid_dmv_top_surface);
1170 if (i == 0) {
1171 dmv_bo = ref_iv->image->bindings[0].address.bo;
1172 }
1173 avc_directmode.POCList[2 * idx] = ref_info->PicOrderCnt[0];
1174 avc_directmode.POCList[2 * idx + 1] = ref_info->PicOrderCnt[1];
1175 }
1176 avc_directmode.DirectMVBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1177 .MOCS = anv_mocs(cmd_buffer->device, dmv_bo, 0),
1178 };
1179
1180 avc_directmode.DirectMVBufferWriteAddress = anv_image_address(img,
1181 &img->vid_dmv_top_surface);
1182 avc_directmode.DirectMVBufferWriteAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1183 .MOCS = anv_mocs(cmd_buffer->device, img->bindings[0].address.bo, 0),
1184 };
1185 avc_directmode.POCList[32] = h264_pic_info->pStdPictureInfo->PicOrderCnt[0];
1186 avc_directmode.POCList[33] = h264_pic_info->pStdPictureInfo->PicOrderCnt[1];
1187 }
1188
1189 uint32_t buffer_offset = frame_info->srcBufferOffset & 4095;
1190 #define HEADER_OFFSET 3
1191 for (unsigned s = 0; s < h264_pic_info->sliceCount; s++) {
1192 bool last_slice = s == (h264_pic_info->sliceCount - 1);
1193 uint32_t current_offset = h264_pic_info->pSliceOffsets[s];
1194 uint32_t this_end;
1195 if (!last_slice) {
1196 uint32_t next_offset = h264_pic_info->pSliceOffsets[s + 1];
1197 uint32_t next_end = h264_pic_info->pSliceOffsets[s + 2];
1198 if (s == h264_pic_info->sliceCount - 2)
1199 next_end = frame_info->srcBufferRange;
1200 anv_batch_emit(&cmd_buffer->batch, GENX(MFD_AVC_SLICEADDR), sliceaddr) {
1201 sliceaddr.IndirectBSDDataLength = next_end - next_offset - HEADER_OFFSET;
1202 /* start decoding after the 3-byte header. */
1203 sliceaddr.IndirectBSDDataStartAddress = buffer_offset + next_offset + HEADER_OFFSET;
1204 };
1205 this_end = next_offset;
1206 } else
1207 this_end = frame_info->srcBufferRange;
1208 anv_batch_emit(&cmd_buffer->batch, GENX(MFD_AVC_BSD_OBJECT), avc_bsd) {
1209 avc_bsd.IndirectBSDDataLength = this_end - current_offset - HEADER_OFFSET;
1210 /* start decoding after the 3-byte header. */
1211 avc_bsd.IndirectBSDDataStartAddress = buffer_offset + current_offset + HEADER_OFFSET;
1212 avc_bsd.InlineData.LastSlice = last_slice;
1213 avc_bsd.InlineData.FixPrevMBSkipped = 1;
1214 avc_bsd.InlineData.IntraPredictionErrorControl = 1;
1215 avc_bsd.InlineData.Intra8x84x4PredictionErrorConcealmentControl = 1;
1216 avc_bsd.InlineData.ISliceConcealmentMode = 1;
1217 };
1218 }
1219 }
1220
1221 #if GFX_VERx10 >= 120
1222
1223 enum av1_seg_index
1224 {
1225 SEG_LVL_ALT_Q = 0, /* Use alternate Quantizer */
1226 SEG_LVL_ALT_LFYV, /* Use alternate loop filter value on y plane vertical */
1227 SEG_LVL_ALT_LFYH, /* Use alternate loop filter value on y plane horizontal */
1228 SEG_LVL_ALT_LFU, /* Use alternate loop filter value on u plane */
1229 SEG_LVL_ALT_LFV, /* Use alternate loop filter value on v plane */
1230 SEG_LVL_REF_FRAME, /* Optional Segment reference frame */
1231 SEG_LVL_SKIP, /* Optional Segment (0,0) + skip mode */
1232 SEG_LVL_GLOBAL_MV, /* Global MV */
1233 };
1234
1235 enum av1_ref_frame
1236 {
1237 AV1_NONE_FRAME = -1, /* none frame */
1238 AV1_INTRA_FRAME = 0, /* intra frame, which means the current frame */
1239 AV1_LAST_FRAME = 1, /* last frame */
1240 AV1_LAST2_FRAME = 2, /* last2 frame */
1241 AV1_LAST3_FRAME = 3, /* last3 frame */
1242 AV1_GOLDEN_FRAME = 4, /* golden frame */
1243 AV1_BWDREF_FRAME = 5, /* bwdref frame */
1244 AV1_ALTREF2_FRAME = 6, /* altref2 frame */
1245 AV1_ALTREF_FRAME = 7, /* altref frame */
1246 AV1_TOTAL_REFS_PER_FRAME = 8, /* total reference frame number */
1247 AV1_NUM_INTER_REFS = AV1_ALTREF_FRAME - AV1_LAST_FRAME + 1 /* total number of inter ref frames */
1248 };
1249
1250 enum av1_gm_type
1251 {
1252 AV1_IDENTITY = 0,
1253 AV1_TRANSLATION,
1254 AV1_ROTZOOM,
1255 AV1_AFFINE,
1256 };
1257
1258 static const uint32_t btdl_cache_offset = 0;
1259 static const uint32_t smvl_cache_offset = 128;
1260 static const uint32_t ipdl_cache_offset = 384;
1261 static const uint32_t dfly_cache_offset = 640;
1262 static const uint32_t dflu_cache_offset = 1344;
1263 static const uint32_t dflv_cache_offset = 1536;
1264 static const uint32_t cdef_cache_offset = 1728;
1265
1266 static const uint32_t av1_max_qindex = 255;
1267 static const uint32_t av1_num_qm_levels = 16;
1268 static const uint32_t av1_scaling_factor = (1 << 14);
1269
1270 static const uint32_t av1_warped_model_prec_bits = 16; /* Warp model precision bits */
1271 static const uint32_t av1_gm_trans_prec_diff = 10; /* Warp model precision bits - gm transformation precision bits */
1272 static const uint32_t av1_gm_trans_only_prec_diff = 13; /* Warp model precision bits - 3 */
1273 static const uint32_t av1_gm_alpha_prec_diff = 1; /* Warp model precision bits - gm alpha precision bits */
1274
1275 static const uint32_t av1_max_mib_size_log2 = 5;
1276 static const uint32_t av1_min_mib_size_log2 = 4;
1277 static const uint32_t av1_mi_size_log2 = 2;
1278
1279 static const uint32_t av1_rs_scale_subpel_bits = 14;
1280 static const uint32_t av1_rs_scale_subpel_mask = 16383;
1281 static const uint32_t av1_rs_scale_extra_off = 128;
1282 static const uint32_t av1_mfmv_stack_size = 3;
1283
1284 static int32_t chroma_xstep_qn = 0;
1285 static int32_t luma_xstep_qn = 0;
1286 static int32_t chroma_x0_qn[64] = { 0, };
1287 static int32_t luma_x0_qn[64] = { 0, };
1288
1289 static uint32_t
get_qindex(const VkVideoDecodeAV1PictureInfoKHR * av1_pic_info,uint32_t segment_id)1290 get_qindex(const VkVideoDecodeAV1PictureInfoKHR *av1_pic_info,
1291 uint32_t segment_id)
1292 {
1293 const StdVideoDecodeAV1PictureInfo *std_pic_info = av1_pic_info->pStdPictureInfo;
1294 uint8_t base_qindex = std_pic_info->pQuantization->base_q_idx;
1295 uint32_t feature_mask = std_pic_info->pSegmentation->FeatureEnabled[segment_id];
1296 if (std_pic_info->flags.segmentation_enabled &&
1297 feature_mask & (1 << SEG_LVL_ALT_Q)) {
1298 int data = std_pic_info->pSegmentation->FeatureData[segment_id][SEG_LVL_ALT_Q];
1299 return CLAMP(base_qindex + data, 0, av1_max_qindex);
1300 } else
1301 return base_qindex;
1302 }
1303
1304 static bool
frame_is_key_or_intra(const StdVideoAV1FrameType frame_type)1305 frame_is_key_or_intra(const StdVideoAV1FrameType frame_type)
1306 {
1307 return (frame_type == STD_VIDEO_AV1_FRAME_TYPE_INTRA_ONLY ||
1308 frame_type == STD_VIDEO_AV1_FRAME_TYPE_KEY);
1309 }
1310
1311 static int32_t
get_relative_dist(const VkVideoDecodeAV1PictureInfoKHR * av1_pic_info,const struct anv_video_session_params * params,int32_t a,int32_t b)1312 get_relative_dist(const VkVideoDecodeAV1PictureInfoKHR *av1_pic_info,
1313 const struct anv_video_session_params *params,
1314 int32_t a, int32_t b)
1315 {
1316 if (!params->vk.av1_dec.seq_hdr.base.flags.enable_order_hint)
1317 return 0;
1318
1319 int32_t bits = params->vk.av1_dec.seq_hdr.base.order_hint_bits_minus_1 + 1;
1320 int32_t diff = a - b;
1321 int32_t m = 1 << (bits - 1);
1322 diff = (diff & (m - 1)) - (diff & m);
1323
1324 return diff;
1325 }
1326
1327 struct av1_refs_info {
1328 const struct anv_image *img;
1329 uint8_t order_hint;
1330 uint8_t ref_order_hints[STD_VIDEO_AV1_NUM_REF_FRAMES];
1331 uint8_t disable_frame_end_update_cdf;
1332 uint8_t idx;
1333 uint8_t frame_type;
1334 uint32_t frame_width;
1335 uint32_t frame_height;
1336 uint8_t default_cdf_index;
1337 };
1338
1339 static int
find_cdf_index(const struct anv_video_session * vid,const struct av1_refs_info * refs_info,const struct anv_image * img)1340 find_cdf_index(const struct anv_video_session *vid,
1341 const struct av1_refs_info *refs_info,
1342 const struct anv_image *img)
1343 {
1344 for (uint32_t i = 0; i < STD_VIDEO_AV1_NUM_REF_FRAMES; i++) {
1345 if (vid) {
1346 if (!vid->prev_refs[i].img)
1347 continue;
1348
1349 if (vid->prev_refs[i].img == img)
1350 return vid->prev_refs[i].default_cdf_index;
1351 } else {
1352 if (!refs_info[i].img)
1353 continue;
1354
1355 if (refs_info[i].img == img)
1356 return refs_info[i].default_cdf_index;
1357 }
1358 }
1359
1360 return 0;
1361 }
1362
1363 static void
anv_av1_decode_video_tile(struct anv_cmd_buffer * cmd_buffer,const VkVideoDecodeInfoKHR * frame_info,int tile_idx)1364 anv_av1_decode_video_tile(struct anv_cmd_buffer *cmd_buffer,
1365 const VkVideoDecodeInfoKHR *frame_info,
1366 int tile_idx)
1367 {
1368 ANV_FROM_HANDLE(anv_buffer, src_buffer, frame_info->srcBuffer);
1369 struct anv_video_session *vid = cmd_buffer->video.vid;
1370 struct anv_video_session_params *params = cmd_buffer->video.params;
1371 const VkVideoDecodeAV1PictureInfoKHR *av1_pic_info =
1372 vk_find_struct_const(frame_info->pNext, VIDEO_DECODE_AV1_PICTURE_INFO_KHR);
1373 const StdVideoDecodeAV1PictureInfo *std_pic_info = av1_pic_info->pStdPictureInfo;
1374 const StdVideoAV1SequenceHeader *seq_hdr = ¶ms->vk.av1_dec.seq_hdr.base;
1375 int cdf_index = 0;
1376 if (std_pic_info->pQuantization->base_q_idx <= 20)
1377 cdf_index = 0;
1378 else if (std_pic_info->pQuantization->base_q_idx <= 60)
1379 cdf_index = 1;
1380 else if (std_pic_info->pQuantization->base_q_idx <= 120)
1381 cdf_index = 2;
1382 else
1383 cdf_index = 3;
1384
1385 anv_batch_emit(&cmd_buffer->batch, GENX(MI_FORCE_WAKEUP), wake) {
1386 wake.HEVCPowerWellControl = true;
1387 wake.MaskBits = 768;
1388 }
1389 anv_batch_emit(&cmd_buffer->batch, GENX(MI_FORCE_WAKEUP), wake) {
1390 wake.HEVCPowerWellControl = true;
1391 wake.MaskBits = 768;
1392 }
1393
1394 anv_batch_emit(&cmd_buffer->batch, GENX(MI_FLUSH_DW), flush) {
1395 flush.DWordLength = 2;
1396 flush.VideoPipelineCacheInvalidate = 1;
1397 };
1398
1399 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_VD_CONTROL_STATE), vd) {
1400 vd.VDControlState.PipelineInitialization = 1;
1401 }
1402
1403 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_WAIT), mfx) {
1404 mfx.MFXSyncControlFlag = 1;
1405 }
1406
1407 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_PIPE_MODE_SELECT), sel) {
1408 sel.CodecSelect = Decode;
1409 sel.MultiEngineMode = SingleEngineMode;
1410 };
1411
1412 anv_batch_emit(&cmd_buffer->batch, GENX(MFX_WAIT), mfx) {
1413 mfx.MFXSyncControlFlag = 1;
1414 }
1415
1416 struct av1_refs_info ref_info[AV1_TOTAL_REFS_PER_FRAME] = { 0, };
1417
1418 const struct anv_image_view *dst_iv =
1419 anv_image_view_from_handle(frame_info->dstPictureResource.imageViewBinding);
1420 const struct anv_image *dst_img = dst_iv->image;
1421 const struct anv_image_view *dpb_iv = frame_info->pSetupReferenceSlot ?
1422 anv_image_view_from_handle(frame_info->pSetupReferenceSlot->pPictureResource->imageViewBinding) :
1423 dst_iv;
1424 const struct anv_image *dpb_img = dpb_iv->image;
1425 const bool is_10bit = seq_hdr->pColorConfig->BitDepth == 10;
1426
1427 VkExtent2D frameExtent = frame_info->dstPictureResource.codedExtent;
1428 int denom = std_pic_info->coded_denom + 9;
1429 unsigned downscaled_width = (frameExtent.width * 8 + denom / 2) / denom;
1430
1431 ref_info[AV1_INTRA_FRAME].img = dpb_img;
1432 ref_info[AV1_INTRA_FRAME].frame_width = frameExtent.width;
1433 ref_info[AV1_INTRA_FRAME].frame_height = frameExtent.height;
1434
1435 if (dpb_img && frame_info->referenceSlotCount) {
1436 ref_info[AV1_INTRA_FRAME].order_hint = std_pic_info->OrderHint;
1437 ref_info[AV1_INTRA_FRAME].disable_frame_end_update_cdf =
1438 std_pic_info->flags.disable_frame_end_update_cdf;
1439 }
1440
1441 for (int i = 0; i < STD_VIDEO_AV1_REFS_PER_FRAME; ++i) {
1442 uint8_t ref_idx = av1_pic_info->referenceNameSlotIndices[i];
1443
1444 for (unsigned j = 0; j < frame_info->referenceSlotCount; j++) {
1445 int idx = frame_info->pReferenceSlots[j].slotIndex;
1446
1447 if (ref_idx == idx) {
1448 const struct anv_image_view *ref_iv =
1449 anv_image_view_from_handle(frame_info->pReferenceSlots[j].pPictureResource->imageViewBinding);
1450 const struct anv_image *ref_img = ref_iv->image;
1451 const struct VkVideoDecodeAV1DpbSlotInfoKHR *dpb_slot =
1452 vk_find_struct_const(frame_info->pReferenceSlots[j].pNext, VIDEO_DECODE_AV1_DPB_SLOT_INFO_KHR);
1453 const struct StdVideoDecodeAV1ReferenceInfo *std_ref_info = dpb_slot->pStdReferenceInfo;
1454
1455 ref_info[i + 1].idx = idx;
1456 ref_info[i + 1].frame_type = std_ref_info->frame_type;
1457 ref_info[i + 1].frame_width = frameExtent.width;
1458 ref_info[i + 1].frame_height = frameExtent.height;
1459 ref_info[i + 1].img = ref_img;
1460 ref_info[i + 1].order_hint = std_ref_info->OrderHint;
1461 memcpy(ref_info[i + 1].ref_order_hints, std_ref_info->SavedOrderHints, STD_VIDEO_AV1_NUM_REF_FRAMES);
1462 ref_info[i + 1].disable_frame_end_update_cdf = std_ref_info->flags.disable_frame_end_update_cdf;
1463 ref_info[i + 1].default_cdf_index = find_cdf_index(vid, NULL, ref_img);
1464 }
1465 }
1466 }
1467
1468 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_SURFACE_STATE), ss) {
1469 ss.SurfaceFormat = is_10bit ? AVP_P010 : AVP_PLANAR_420_8;
1470 ss.SurfacePitchMinus1 = dst_img->planes[0].primary_surface.isl.row_pitch_B - 1;
1471 ss.YOffsetforUCb = dst_img->planes[1].primary_surface.memory_range.offset /
1472 dst_img->planes[0].primary_surface.isl.row_pitch_B;
1473 };
1474
1475 if (!frame_is_key_or_intra(std_pic_info->frame_type)) {
1476 for (enum av1_ref_frame r = AV1_INTRA_FRAME; r <= AV1_ALTREF_FRAME; r++) {
1477 if (ref_info[r].img && frame_info->referenceSlotCount) {
1478 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_SURFACE_STATE), ss) {
1479 ss.SurfaceID = 0x6 + r;
1480 ss.SurfaceFormat = is_10bit ? AVP_P010 : AVP_PLANAR_420_8;
1481 ss.SurfacePitchMinus1 = ref_info[r].img->planes[0].primary_surface.isl.row_pitch_B - 1;
1482 ss.YOffsetforUCb = ref_info[r].img->planes[1].primary_surface.memory_range.offset /
1483 ref_info[r].img->planes[0].primary_surface.isl.row_pitch_B;
1484 }
1485 }
1486 }
1487 }
1488
1489 if (std_pic_info->flags.allow_intrabc) {
1490 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_SURFACE_STATE), ss) {
1491 ss.SurfaceID = 0xE;
1492 ss.SurfaceFormat = is_10bit ? AVP_P010 : AVP_PLANAR_420_8;
1493 ss.SurfacePitchMinus1 = dst_img->planes[0].primary_surface.isl.row_pitch_B - 1;
1494 ss.YOffsetforUCb = dst_img->planes[1].primary_surface.memory_range.offset /
1495 dst_img->planes[0].primary_surface.isl.row_pitch_B;
1496 }
1497 }
1498
1499 bool use_internal_cache_mem = true;
1500
1501 #if GFX_VERx10 == 125
1502 assert(dst_img->planes[0].primary_surface.isl.tiling == ISL_TILING_4);
1503 #endif
1504 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_PIPE_BUF_ADDR_STATE), buf) {
1505 buf.DecodedOutputFrameBufferAddress = anv_image_address(dst_img,
1506 &dst_img->planes[0].primary_surface.memory_range);
1507 buf.DecodedOutputFrameBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1508 .MOCS = anv_mocs(cmd_buffer->device, buf.DecodedOutputFrameBufferAddress.bo, 0),
1509 #if GFX_VERx10 >= 125
1510 .TiledResourceMode = TRMODE_TILEF,
1511 #endif
1512 };
1513 buf.CurrentFrameMVWriteBufferAddress = anv_image_address(dpb_img,
1514 &dpb_img->vid_dmv_top_surface);
1515 buf.CurrentFrameMVWriteBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1516 .MOCS = anv_mocs(cmd_buffer->device, buf.CurrentFrameMVWriteBufferAddress.bo, 0),
1517 };
1518
1519 if (std_pic_info->flags.allow_intrabc) {
1520 buf.IntraBCDecodedOutputFrameBufferAddress =
1521 anv_image_address(dst_img, &dst_img->planes[0].primary_surface.memory_range);
1522 }
1523
1524 buf.IntraBCDecodedOutputFrameBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1525 .MOCS = anv_mocs(cmd_buffer->device, buf.IntraBCDecodedOutputFrameBufferAddress.bo, 0),
1526 };
1527
1528 if (use_internal_cache_mem) {
1529 buf.BitstreamLineRowstoreBufferAddress = (struct anv_address) {
1530 NULL,
1531 btdl_cache_offset * 64
1532 };
1533
1534 buf.BitstreamLineRowstoreBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1535 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1536 .RowStoreScratchBufferCacheSelect = 1,
1537 };
1538 } else {
1539 buf.BitstreamLineRowstoreBufferAddress = (struct anv_address) {
1540 vid->vid_mem[ANV_VID_MEM_AV1_BITSTREAM_LINE_ROWSTORE].mem->bo,
1541 vid->vid_mem[ANV_VID_MEM_AV1_BITSTREAM_LINE_ROWSTORE].offset
1542 };
1543 buf.BitstreamLineRowstoreBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1544 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_BITSTREAM_LINE_ROWSTORE].mem->bo, 0),
1545 };
1546 }
1547
1548 buf.BitstreamTileLineRowstoreBufferAddress = (struct anv_address) {
1549 vid->vid_mem[ANV_VID_MEM_AV1_BITSTREAM_TILE_LINE_ROWSTORE].mem->bo,
1550 vid->vid_mem[ANV_VID_MEM_AV1_BITSTREAM_TILE_LINE_ROWSTORE].offset
1551 };
1552
1553 buf.BitstreamTileLineRowstoreBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1554 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_BITSTREAM_TILE_LINE_ROWSTORE].mem->bo, 0),
1555 };
1556
1557 if (use_internal_cache_mem) {
1558 buf.IntraPredictionLineRowstoreBufferAddress = (struct anv_address) {
1559 NULL,
1560 ipdl_cache_offset * 64
1561 };
1562 buf.IntraPredictionLineRowstoreBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1563 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1564 .RowStoreScratchBufferCacheSelect = 1
1565 };
1566 } else {
1567 buf.IntraPredictionLineRowstoreBufferAddress = (struct anv_address) {
1568 vid->vid_mem[ANV_VID_MEM_AV1_INTRA_PREDICTION_LINE_ROWSTORE].mem->bo,
1569 vid->vid_mem[ANV_VID_MEM_AV1_INTRA_PREDICTION_LINE_ROWSTORE].offset
1570 };
1571 buf.IntraPredictionLineRowstoreBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1572 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_INTRA_PREDICTION_LINE_ROWSTORE].mem->bo, 0),
1573 };
1574 }
1575 buf.IntraPredictionTileLineRowstoreBufferAddress = (struct anv_address) {
1576 vid->vid_mem[ANV_VID_MEM_AV1_INTRA_PREDICTION_TILE_LINE_ROWSTORE].mem->bo,
1577 vid->vid_mem[ANV_VID_MEM_AV1_INTRA_PREDICTION_TILE_LINE_ROWSTORE].offset
1578 };
1579
1580 buf.IntraPredictionTileLineRowstoreBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1581 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_INTRA_PREDICTION_TILE_LINE_ROWSTORE].mem->bo, 0),
1582 };
1583
1584 if (use_internal_cache_mem) {
1585 buf.SpatialMotionVectorLineBufferAddress = (struct anv_address) {
1586 NULL,
1587 smvl_cache_offset * 64
1588 };
1589 buf.SpatialMotionVectorLineBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1590 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1591 .RowStoreScratchBufferCacheSelect = 1
1592 };
1593 } else {
1594 buf.SpatialMotionVectorLineBufferAddress = (struct anv_address) {
1595 vid->vid_mem[ANV_VID_MEM_AV1_SPATIAL_MOTION_VECTOR_LINE].mem->bo,
1596 vid->vid_mem[ANV_VID_MEM_AV1_SPATIAL_MOTION_VECTOR_LINE].offset
1597 };
1598 buf.SpatialMotionVectorLineBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1599 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_SPATIAL_MOTION_VECTOR_LINE].mem->bo, 0),
1600 };
1601 }
1602
1603 buf.SpatialMotionVectorTileLineBufferAddress = (struct anv_address) {
1604 vid->vid_mem[ANV_VID_MEM_AV1_SPATIAL_MOTION_VECTOR_TILE_LINE].mem->bo,
1605 vid->vid_mem[ANV_VID_MEM_AV1_SPATIAL_MOTION_VECTOR_TILE_LINE].offset
1606 };
1607
1608 buf.SpatialMotionVectorTileLineBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1609 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_SPATIAL_MOTION_VECTOR_TILE_LINE].mem->bo, 0),
1610 };
1611
1612 buf.LoopRestorationMetaTileColumnBufferAddress = (struct anv_address) {
1613 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_META_TILE_COLUMN].mem->bo,
1614 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_META_TILE_COLUMN].offset
1615 };
1616 buf.LoopRestorationMetaTileColumnBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1617 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_META_TILE_COLUMN].mem->bo, 0),
1618 };
1619
1620 buf.LoopRestorationFilterTileLineYBufferAddress = (struct anv_address) {
1621 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_Y].mem->bo,
1622 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_Y].offset
1623 };
1624 buf.LoopRestorationFilterTileLineYBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1625 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_Y].mem->bo, 0),
1626 };
1627
1628 buf.LoopRestorationFilterTileLineUBufferAddress = (struct anv_address) {
1629 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_U].mem->bo,
1630 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_U].offset
1631 };
1632
1633 buf.LoopRestorationFilterTileLineUBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1634 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_U].mem->bo, 0),
1635 };
1636
1637 buf.LoopRestorationFilterTileLineVBufferAddress = (struct anv_address) {
1638 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_V].mem->bo,
1639 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_V].offset
1640 };
1641
1642 buf.LoopRestorationFilterTileLineVBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1643 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_LINE_V].mem->bo, 0),
1644 };
1645
1646 if (use_internal_cache_mem) {
1647 buf.DeblockerFilterLineYBufferAddress = (struct anv_address) {
1648 NULL,
1649 dfly_cache_offset * 64
1650 };
1651 buf.DeblockerFilterLineYBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1652 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1653 .RowStoreScratchBufferCacheSelect = 1,
1654 };
1655 } else {
1656 buf.DeblockerFilterLineYBufferAddress = (struct anv_address) {
1657 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_Y].mem->bo,
1658 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_Y].offset
1659 };
1660 buf.DeblockerFilterLineYBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1661 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_Y].mem->bo, 0),
1662 };
1663 }
1664
1665 if (use_internal_cache_mem) {
1666 buf.DeblockerFilterLineUBufferAddress = (struct anv_address) {
1667 NULL,
1668 dflu_cache_offset * 64
1669 };
1670 buf.DeblockerFilterLineUBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1671 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1672 .RowStoreScratchBufferCacheSelect = 1,
1673 };
1674 } else {
1675 buf.DeblockerFilterLineUBufferAddress = (struct anv_address) {
1676 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_U].mem->bo,
1677 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_U].offset
1678 };
1679 buf.DeblockerFilterLineUBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1680 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_U].mem->bo, 0),
1681 };
1682 }
1683 if (use_internal_cache_mem) {
1684 buf.DeblockerFilterLineVBufferAddress = (struct anv_address) {
1685 NULL,
1686 dflv_cache_offset * 64
1687 };
1688 buf.DeblockerFilterLineVBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1689 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1690 .RowStoreScratchBufferCacheSelect = 1,
1691 };
1692 } else {
1693 buf.DeblockerFilterLineVBufferAddress = (struct anv_address) {
1694 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_V].mem->bo,
1695 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_V].offset
1696 };
1697 buf.DeblockerFilterLineVBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1698 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_LINE_V].mem->bo, 0),
1699 };
1700 }
1701
1702 buf.DeblockerFilterTileLineYBufferAddress = (struct anv_address) {
1703 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_Y].mem->bo,
1704 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_Y].offset
1705 };
1706 buf.DeblockerFilterTileLineYBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1707 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_Y].mem->bo, 0),
1708 };
1709
1710 buf.DeblockerFilterTileLineUBufferAddress = (struct anv_address) {
1711 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_U].mem->bo,
1712 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_U].offset
1713 };
1714
1715 buf.DeblockerFilterTileLineUBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1716 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_U].mem->bo, 0),
1717 };
1718
1719 buf.DeblockerFilterTileLineVBufferAddress = (struct anv_address) {
1720 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_V].mem->bo,
1721 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_V].offset
1722 };
1723 buf.DeblockerFilterTileLineVBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1724 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_LINE_V].mem->bo, 0),
1725 };
1726
1727 buf.DeblockerFilterTileColumnYBufferAddress = (struct anv_address) {
1728 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_Y].mem->bo,
1729 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_Y].offset
1730 };
1731
1732 buf.DeblockerFilterTileColumnYBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1733 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_Y].mem->bo, 0),
1734 };
1735
1736 buf.DeblockerFilterTileColumnUBufferAddress = (struct anv_address) {
1737 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_U].mem->bo,
1738 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_U].offset
1739 };
1740
1741 buf.DeblockerFilterTileColumnUBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1742 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_U].mem->bo, 0),
1743 };
1744 buf.DeblockerFilterTileColumnVBufferAddress = (struct anv_address) {
1745 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_V].mem->bo,
1746 vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_V].offset
1747 };
1748 buf.DeblockerFilterTileColumnVBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1749 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_DEBLOCKER_FILTER_TILE_COLUMN_V].mem->bo, 0),
1750 };
1751
1752 if (use_internal_cache_mem) {
1753 buf.CDEFFilterLineBufferAddress = (struct anv_address) { NULL, cdef_cache_offset * 64};
1754 buf.CDEFFilterLineBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1755 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1756 .RowStoreScratchBufferCacheSelect = 1,
1757 };
1758 } else {
1759 buf.CDEFFilterLineBufferAddress = (struct anv_address) {
1760 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_LINE].mem->bo,
1761 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_LINE].offset
1762 };
1763 buf.CDEFFilterLineBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1764 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_LINE].mem->bo, 0),
1765 };
1766 }
1767
1768 buf.CDEFFilterTileLineBufferAddress = (struct anv_address) {
1769 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_TILE_LINE].mem->bo,
1770 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_TILE_LINE].offset
1771 };
1772 buf.CDEFFilterTileLineBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1773 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_TILE_LINE].mem->bo, 0),
1774 };
1775
1776 buf.CDEFFilterTileColumnBufferAddress = (struct anv_address) {
1777 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_TILE_COLUMN].mem->bo,
1778 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_TILE_COLUMN].offset
1779 };
1780 buf.CDEFFilterTileColumnBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1781 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_TILE_COLUMN].mem->bo, 0),
1782 };
1783
1784 buf.CDEFFilterMetaTileLineBufferAddress = (struct anv_address) {
1785 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_META_TILE_LINE].mem->bo,
1786 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_META_TILE_LINE].offset
1787 };
1788 buf.CDEFFilterMetaTileLineBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1789 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_META_TILE_LINE].mem->bo, 0),
1790 };
1791
1792 buf.CDEFFilterMetaTileColumnBufferAddress = (struct anv_address) {
1793 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_META_TILE_COLUMN].mem->bo,
1794 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_META_TILE_COLUMN].offset
1795 };
1796
1797 buf.CDEFFilterMetaTileColumnBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1798 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_META_TILE_COLUMN].mem->bo, 0),
1799 };
1800
1801 buf.CDEFFilterTopLeftCornerBufferAddress = (struct anv_address) {
1802 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_TOP_LEFT_CORNER].mem->bo,
1803 vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_TOP_LEFT_CORNER].offset
1804 };
1805 buf.CDEFFilterTopLeftCornerBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1806 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_CDEF_FILTER_TOP_LEFT_CORNER].mem->bo, 0),
1807 };
1808
1809 buf.SuperResTileColumnYBufferAddress = (struct anv_address) {
1810 vid->vid_mem[ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_Y].mem->bo,
1811 vid->vid_mem[ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_Y].offset
1812 };
1813 buf.SuperResTileColumnYBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1814 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_Y].mem->bo, 0),
1815 };
1816
1817 buf.SuperResTileColumnUBufferAddress = (struct anv_address) {
1818 vid->vid_mem[ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_U].mem->bo,
1819 vid->vid_mem[ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_U].offset
1820 };
1821 buf.SuperResTileColumnUBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1822 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_U].mem->bo, 0),
1823 };
1824
1825 buf.SuperResTileColumnVBufferAddress = (struct anv_address) {
1826 vid->vid_mem[ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_V].mem->bo,
1827 vid->vid_mem[ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_V].offset
1828 };
1829 buf.SuperResTileColumnVBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1830 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_SUPER_RES_TILE_COLUMN_V].mem->bo, 0),
1831 };
1832
1833 buf.LoopRestorationFilterTileColumnYBufferAddress = (struct anv_address) {
1834 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_Y].mem->bo,
1835 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_Y].offset
1836 };
1837
1838 buf.LoopRestorationFilterTileColumnYBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1839 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_Y].mem->bo, 0),
1840 };
1841
1842 buf.LoopRestorationFilterTileColumnUBufferAddress = (struct anv_address) {
1843 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_U].mem->bo,
1844 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_U].offset
1845 };
1846
1847 buf.LoopRestorationFilterTileColumnUBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1848 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_U].mem->bo, 0),
1849 };
1850
1851 buf.LoopRestorationFilterTileColumnVBufferAddress = (struct anv_address) {
1852 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_V].mem->bo,
1853 vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_V].offset
1854 };
1855 buf.LoopRestorationFilterTileColumnVBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1856 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_LOOP_RESTORATION_FILTER_TILE_COLUMN_V].mem->bo, 0),
1857 };
1858
1859 struct anv_bo *ref_bo = NULL;
1860 struct anv_bo *collocated_bo = NULL;
1861
1862 if (std_pic_info->frame_type != STD_VIDEO_AV1_FRAME_TYPE_KEY) {
1863 for (enum av1_ref_frame r = AV1_INTRA_FRAME; r <= AV1_ALTREF_FRAME; r++) {
1864 const struct anv_image *ref_img = ref_info[r].img;
1865 if (ref_img) {
1866
1867 buf.ReferencePictureAddress[r] =
1868 anv_image_address(ref_img, &ref_img->planes[0].primary_surface.memory_range);
1869 buf.CollocatedMVTemporalBufferAddress[r] =
1870 anv_image_address(ref_img, &ref_img->vid_dmv_top_surface);
1871
1872 if (!ref_bo)
1873 ref_bo = ref_img->bindings[0].address.bo;
1874 if (!collocated_bo)
1875 collocated_bo = ref_img->bindings[ref_img->vid_dmv_top_surface.binding].address.bo;
1876
1877 }
1878 }
1879 }
1880
1881 buf.ReferencePictureAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1882 .MOCS = anv_mocs(cmd_buffer->device, ref_bo, 0),
1883 #if GFX_VERx10 >= 125
1884 .TiledResourceMode = TRMODE_TILEF,
1885 #endif
1886 };
1887 buf.CollocatedMVTemporalBufferAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1888 .MOCS = anv_mocs(cmd_buffer->device, collocated_bo, 0),
1889 };
1890
1891 bool use_default_cdf = false;
1892
1893 if (std_pic_info->primary_ref_frame == 7) {
1894 use_default_cdf = true;
1895 } else {
1896 if (ref_info[std_pic_info->primary_ref_frame + 1].disable_frame_end_update_cdf) {
1897 use_default_cdf = true;
1898
1899 const struct anv_image *ref_img = ref_info[std_pic_info->primary_ref_frame + 1].img;
1900 cdf_index = find_cdf_index(vid, NULL, ref_img);
1901 }
1902 }
1903
1904 if (use_default_cdf) {
1905 buf.CDFTablesInitializationBufferAddress = (struct anv_address) {
1906 vid->vid_mem[ANV_VID_MEM_AV1_CDF_DEFAULTS_0 + cdf_index].mem->bo,
1907 vid->vid_mem[ANV_VID_MEM_AV1_CDF_DEFAULTS_0 + cdf_index].offset };
1908
1909 ref_info[0].default_cdf_index = cdf_index;
1910 } else {
1911 const struct anv_image *ref_img = ref_info[std_pic_info->primary_ref_frame + 1].img;
1912 buf.CDFTablesInitializationBufferAddress = anv_image_address(ref_img,
1913 &ref_img->av1_cdf_table);
1914 }
1915 buf.CDFTablesInitializationBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1916 .MOCS = anv_mocs(cmd_buffer->device, buf.CDFTablesInitializationBufferAddress.bo, 0),
1917 };
1918
1919 if (!std_pic_info->flags.disable_frame_end_update_cdf) {
1920 const struct anv_image *ref_img = ref_info[0].img;
1921 buf.CDFTablesBackwardAdaptationBufferAddress = anv_image_address(ref_img,
1922 &ref_img->av1_cdf_table);
1923 }
1924
1925 buf.CDFTablesBackwardAdaptationBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1926 .MOCS = anv_mocs(cmd_buffer->device, buf.CDFTablesBackwardAdaptationBufferAddress.bo, 0),
1927 };
1928 buf.AV1SegmentIDReadBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1929 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1930 };
1931 buf.AV1SegmentIDWriteBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1932 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1933 };
1934 buf.DecodedFrameStatusErrorBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1935 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1936 };
1937
1938 buf.DecodedBlockDataStreamoutBufferAddress = (struct anv_address) {
1939 vid->vid_mem[ANV_VID_MEM_AV1_DBD_BUFFER].mem->bo,
1940 vid->vid_mem[ANV_VID_MEM_AV1_DBD_BUFFER].offset
1941 };
1942 buf.DecodedBlockDataStreamoutBufferAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1943 .MOCS = anv_mocs(cmd_buffer->device, vid->vid_mem[ANV_VID_MEM_AV1_DBD_BUFFER].mem->bo, 0),
1944 };
1945 };
1946
1947 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_IND_OBJ_BASE_ADDR_STATE), ind) {
1948 ind.AVPIndirectBitstreamObjectBaseAddress = anv_address_add(src_buffer->address,
1949 frame_info->srcBufferOffset & ~4095);
1950 ind.AVPIndirectBitstreamObjectAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1951 .MOCS = anv_mocs(cmd_buffer->device, src_buffer->address.bo, 0),
1952 };
1953 #if GFX_VERx10 >= 125
1954 /* FIXME.
1955 ind.AVPIndirectCUObjectAddressAttributes = (struct GENX(MEMORYADDRESSATTRIBUTES)) {
1956 .MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
1957 };
1958 */
1959 #endif
1960 }
1961
1962 uint32_t frame_restoration_type[3];
1963 for (unsigned i = 0; i < 3; i++) {
1964 frame_restoration_type[i] = std_pic_info->pLoopRestoration ?
1965 std_pic_info->pLoopRestoration->FrameRestorationType[i] : 0;
1966 }
1967
1968 uint32_t ref_mask = 0;
1969 uint32_t ref_frame_sign_bias = 0;
1970 uint32_t ref_frame_side = 0;
1971 for (enum av1_ref_frame r = AV1_LAST_FRAME; r <= AV1_ALTREF_FRAME; r++) {
1972 if (seq_hdr->flags.enable_order_hint &&
1973 !frame_is_key_or_intra(std_pic_info->frame_type)) {
1974 if (get_relative_dist(av1_pic_info, params,
1975 ref_info[r].order_hint, ref_info[AV1_INTRA_FRAME].order_hint) > 0)
1976 ref_frame_sign_bias |= (1 << r);
1977
1978 if ((get_relative_dist(av1_pic_info, params,
1979 ref_info[r].order_hint, ref_info[AV1_INTRA_FRAME].order_hint) > 0) ||
1980 ref_info[r].order_hint == ref_info[AV1_INTRA_FRAME].order_hint)
1981 ref_frame_side |= (1 << r);
1982 }
1983 }
1984
1985 uint8_t num_mfmv = 0;
1986 uint8_t mfmv_ref[7] = { 0, };
1987 if (!frame_is_key_or_intra(std_pic_info->frame_type) &&
1988 std_pic_info->flags.use_ref_frame_mvs &&
1989 seq_hdr->order_hint_bits_minus_1 + 1) {
1990
1991 assert (seq_hdr->flags.enable_order_hint);
1992
1993 int total = av1_mfmv_stack_size - 1;
1994
1995 if (ref_info[AV1_LAST_FRAME].ref_order_hints[AV1_ALTREF_FRAME - AV1_LAST_FRAME + 1] !=
1996 ref_info[AV1_GOLDEN_FRAME].order_hint) {
1997
1998 if (!frame_is_key_or_intra(ref_info[0 + 1].frame_type)) {
1999 total = av1_mfmv_stack_size;
2000 mfmv_ref[num_mfmv++] = AV1_LAST_FRAME - AV1_LAST_FRAME;
2001 }
2002 }
2003
2004 if (get_relative_dist(av1_pic_info, params,
2005 ref_info[AV1_BWDREF_FRAME].order_hint,
2006 ref_info[AV1_INTRA_FRAME].order_hint) > 0 &&
2007 !frame_is_key_or_intra(ref_info[AV1_BWDREF_FRAME - AV1_LAST_FRAME + 1].frame_type)) {
2008 mfmv_ref[num_mfmv++] = AV1_BWDREF_FRAME - AV1_LAST_FRAME;
2009 }
2010
2011 if (get_relative_dist(av1_pic_info, params,
2012 ref_info[AV1_ALTREF2_FRAME].order_hint,
2013 ref_info[AV1_INTRA_FRAME].order_hint) > 0 &&
2014 !frame_is_key_or_intra(ref_info[AV1_ALTREF2_FRAME - AV1_LAST_FRAME + 1].frame_type)) {
2015 mfmv_ref[num_mfmv++] = AV1_ALTREF2_FRAME - AV1_LAST_FRAME;
2016 }
2017
2018 if (num_mfmv < total &&
2019 get_relative_dist(av1_pic_info, params,
2020 ref_info[AV1_ALTREF_FRAME].order_hint,
2021 ref_info[AV1_INTRA_FRAME].order_hint) > 0 &&
2022 !frame_is_key_or_intra(ref_info[AV1_ALTREF_FRAME - AV1_LAST_FRAME + 1].frame_type)) {
2023 mfmv_ref[num_mfmv++] = AV1_ALTREF_FRAME - AV1_LAST_FRAME;
2024 }
2025
2026 if (num_mfmv < total &&
2027 !frame_is_key_or_intra(ref_info[AV1_LAST2_FRAME - AV1_LAST_FRAME + 1].frame_type)) {
2028 mfmv_ref[num_mfmv++] = AV1_LAST2_FRAME - AV1_LAST_FRAME;
2029 }
2030 }
2031
2032 assert(num_mfmv <= 7);
2033
2034 for (unsigned int i = 0; i < num_mfmv; i++) {
2035 ref_mask |= (1 << mfmv_ref[i]);
2036 }
2037
2038 uint8_t preskip_segid = 0;
2039 uint8_t last_active_segid = 0;
2040 bool frame_lossless = true;
2041 bool lossless[8] = { false };
2042
2043 for (unsigned i = 0; i < 8; i++) {
2044 for (unsigned j = 0; j < 8; j++) {
2045 if (std_pic_info->pSegmentation->FeatureEnabled[i] & (1 << j)) {
2046 last_active_segid = i;
2047 if (j >= 5)
2048 preskip_segid = 1;
2049 }
2050 }
2051 uint32_t qindex = get_qindex(av1_pic_info, i);
2052 lossless[i] = (qindex == 0) &&
2053 (std_pic_info->pQuantization->DeltaQYDc == 0) &&
2054 (std_pic_info->pQuantization->DeltaQUAc == 0) &&
2055 (std_pic_info->pQuantization->DeltaQUDc == 0) &&
2056 (std_pic_info->pQuantization->DeltaQVAc == 0) &&
2057 (std_pic_info->pQuantization->DeltaQVDc == 0);
2058 frame_lossless &= lossless[i];
2059 }
2060
2061 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_PIC_STATE), pic) {
2062 if (std_pic_info->flags.use_superres) {
2063 pic.FrameWidth = downscaled_width - 1;
2064 } else {
2065 pic.FrameWidth = frameExtent.width - 1;
2066 }
2067 pic.FrameHeight = frameExtent.height - 1;
2068
2069 if (seq_hdr->pColorConfig->BitDepth == 12)
2070 pic.SequencePixelBitDepthIdc = SeqPix_12bit;
2071 else if (seq_hdr->pColorConfig->BitDepth == 10)
2072 pic.SequencePixelBitDepthIdc = SeqPix_10bit;
2073 else
2074 pic.SequencePixelBitDepthIdc = SeqPix_8bit;
2075 if (seq_hdr->pColorConfig->subsampling_x == 1 &&
2076 seq_hdr->pColorConfig->subsampling_y == 1) {
2077 if (seq_hdr->pColorConfig->flags.mono_chrome)
2078 pic.SequenceChromaSubSamplingFormat = SS_Monochrome;
2079 else
2080 pic.SequenceChromaSubSamplingFormat = SS_420;
2081 } else if (seq_hdr->pColorConfig->subsampling_x == 1 &&
2082 seq_hdr->pColorConfig->subsampling_y == 0) {
2083 pic.SequenceChromaSubSamplingFormat = SS_422;
2084 } else if (seq_hdr->pColorConfig->subsampling_x == 0 &&
2085 seq_hdr->pColorConfig->subsampling_y == 0) {
2086 pic.SequenceChromaSubSamplingFormat = SS_444;
2087 }
2088
2089 pic.SequenceSuperblockSizeUsed = seq_hdr->flags.use_128x128_superblock;
2090 pic.SequenceEnableOrderHintFlag = seq_hdr->flags.enable_order_hint;
2091 pic.SequenceOrderHintBitsMinus1 = seq_hdr->flags.enable_order_hint ? seq_hdr->order_hint_bits_minus_1 : 0;
2092 pic.SequenceEnableFilterIntraFlag = seq_hdr->flags.enable_filter_intra;
2093 pic.SequenceEnableIntraEdgeFilterFlag = seq_hdr->flags.enable_intra_edge_filter;
2094 pic.SequenceEnableDualFilterFlag = seq_hdr->flags.enable_dual_filter;
2095 pic.SequenceEnableInterIntraCompoundFlag = seq_hdr->flags.enable_interintra_compound;
2096 pic.SequenceEnableMaskedCompoundFlag = seq_hdr->flags.enable_masked_compound;
2097 pic.SequenceEnableJointCompoundFlag = seq_hdr->flags.enable_jnt_comp;
2098 pic.AllowScreenContentToolsFlag = std_pic_info->flags.allow_screen_content_tools;
2099 pic.ForceIntegerMVFlag = std_pic_info->flags.force_integer_mv;
2100 pic.AllowWarpedMotionFlag = std_pic_info->flags.allow_warped_motion;
2101 pic.UseCDEFFilterFlag = seq_hdr->flags.enable_cdef;
2102 pic.UseSuperResFlag = std_pic_info->flags.use_superres;
2103 pic.FrameLevelLoopRestorationFilterEnable = frame_restoration_type[0] || frame_restoration_type[1] || frame_restoration_type[2];
2104 pic.FrameType = std_pic_info->frame_type;
2105 pic.IntraOnlyFlag = frame_is_key_or_intra(std_pic_info->frame_type);
2106 pic.ErrorResilientModeFlag = std_pic_info->flags.error_resilient_mode;
2107 pic.AllowIntraBCFlag = std_pic_info->flags.allow_intrabc;
2108 pic.PrimaryReferenceFrameIdx = std_pic_info->primary_ref_frame;
2109 pic.SegmentationEnableFlag = std_pic_info->flags.segmentation_enabled;
2110 pic.SegmentationUpdateMapFlag = std_pic_info->flags.segmentation_update_map;
2111 pic.SegmentationTemporalUpdateFlag = pic.IntraOnlyFlag ? 0 : std_pic_info->flags.segmentation_temporal_update;
2112 pic.PreSkipSegmentIDFlag = preskip_segid;
2113 pic.LastActiveSegmentSegmentID = last_active_segid;
2114 pic.DeltaQPresentFlag = std_pic_info->flags.delta_q_present;
2115 pic.DeltaQRes = std_pic_info->delta_q_res;
2116 pic.FrameCodedLosslessMode = frame_lossless; /* TODO */
2117 pic.SegmentMapisZeroFlag = 0; /* TODO */
2118 pic.SegmentIDBufferStreamInEnableFlag = 0; /* TODO */
2119 pic.SegmentIDBufferStreamOutEnableFlag = 0; /* TODO */
2120 pic.BaseQindex = std_pic_info->pQuantization->base_q_idx;
2121 pic.YdcdeltaQ = std_pic_info->pQuantization->DeltaQYDc;
2122 pic.UdcdeltaQ = std_pic_info->pQuantization->DeltaQUDc;
2123 pic.UacdeltaQ = std_pic_info->pQuantization->DeltaQUAc;
2124 pic.VdcdeltaQ = std_pic_info->pQuantization->DeltaQVDc;
2125 pic.VacdeltaQ = std_pic_info->pQuantization->DeltaQVAc;
2126 pic.AllowHighPrecisionMV = std_pic_info->flags.allow_high_precision_mv;
2127 pic.FrameLevelReferenceModeSelect = !(std_pic_info->flags.reference_select == 0);
2128 pic.McompFilterType = std_pic_info->interpolation_filter;
2129 pic.MotionModeSwitchableFlag = std_pic_info->flags.is_motion_mode_switchable;
2130 pic.UseReferenceFrameMVSetFlag = std_pic_info->flags.use_ref_frame_mvs;
2131 pic.ReferenceFrameSignBias = ref_frame_sign_bias;
2132 pic.CurrentFrameOrderHint = std_pic_info->OrderHint;
2133 pic.ReducedTxSetUsed = std_pic_info->flags.reduced_tx_set;
2134 pic.FrameTransformMode = std_pic_info->TxMode;
2135 pic.SkipModePresentFlag = std_pic_info->flags.skip_mode_present;
2136 pic.SkipModeFrame0 = std_pic_info->SkipModeFrame[0];
2137 pic.SkipModeFrame1 = std_pic_info->SkipModeFrame[1];
2138 pic.ReferenceFrameSide = ref_frame_side;
2139 pic.GlobalMotionType1 = std_pic_info->pGlobalMotion->GmType[1];
2140 pic.GlobalMotionType2 = std_pic_info->pGlobalMotion->GmType[2];
2141 pic.GlobalMotionType3 = std_pic_info->pGlobalMotion->GmType[3];
2142 pic.GlobalMotionType4 = std_pic_info->pGlobalMotion->GmType[4];
2143 pic.GlobalMotionType5 = std_pic_info->pGlobalMotion->GmType[5];
2144 pic.GlobalMotionType6 = std_pic_info->pGlobalMotion->GmType[6];
2145 pic.GlobalMotionType7 = std_pic_info->pGlobalMotion->GmType[7];
2146 pic.FrameLevelGlobalMotionInvalidFlags = 0;
2147
2148 uint8_t idx = 0;
2149 int warp_params[8][6] = { 0, };
2150
2151 for (enum av1_ref_frame r = AV1_LAST_FRAME; r <= AV1_ALTREF_FRAME; r++) {
2152 unsigned gm_type = std_pic_info->pGlobalMotion->GmType[r];
2153
2154 for (uint32_t i = 0; i < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; i++) {
2155 warp_params[r][i] = std_pic_info->pGlobalMotion->gm_params[r][i];
2156 }
2157
2158 if (gm_type >= AV1_ROTZOOM) {
2159 warp_params[r][2] -= (1 << av1_warped_model_prec_bits);
2160 warp_params[r][2] >>= av1_gm_alpha_prec_diff;
2161 warp_params[r][3] >>= av1_gm_alpha_prec_diff;
2162 }
2163
2164 if (gm_type == AV1_AFFINE) {
2165 warp_params[r][4] >>= av1_gm_alpha_prec_diff;
2166 warp_params[r][5] -= (1 << av1_warped_model_prec_bits);
2167 warp_params[r][5] >>= av1_gm_alpha_prec_diff;
2168 } else {
2169 warp_params[r][4] = -warp_params[r][3];
2170 warp_params[r][5] = warp_params[r][2];
2171 }
2172
2173 if (gm_type >= AV1_TRANSLATION) {
2174 int trans_shift =
2175 (gm_type == AV1_TRANSLATION) ?
2176 av1_gm_trans_only_prec_diff + (std_pic_info->flags.allow_high_precision_mv ? 0 : 1) :
2177 av1_gm_trans_prec_diff;
2178
2179 warp_params[r][0] >>= trans_shift;
2180 warp_params[r][1] >>= trans_shift;
2181 }
2182
2183 }
2184
2185 for (enum av1_ref_frame r = AV1_LAST_FRAME; r <= AV1_ALTREF_FRAME; r++) {
2186 for (uint32_t i = 0; i < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; i++)
2187 pic.WarpParameters[idx++] = warp_params[r][i] & 0xffff;
2188 }
2189
2190 pic.ReferenceFrameIdx1 = AV1_LAST_FRAME;
2191 pic.ReferenceFrameIdx2 = AV1_LAST2_FRAME;
2192 pic.ReferenceFrameIdx3 = AV1_LAST3_FRAME;
2193 pic.ReferenceFrameIdx4 = AV1_GOLDEN_FRAME;
2194 pic.ReferenceFrameIdx5 = AV1_BWDREF_FRAME;
2195 pic.ReferenceFrameIdx6 = AV1_ALTREF2_FRAME;
2196 pic.ReferenceFrameIdx7 = AV1_ALTREF_FRAME;
2197
2198 if (!frame_is_key_or_intra(std_pic_info->frame_type)) {
2199 for (enum av1_ref_frame r = AV1_INTRA_FRAME; r <= AV1_ALTREF_FRAME; r++) {
2200
2201 int ref_width = ref_info[r].frame_width - 1;
2202 int ref_height = ref_info[r].frame_height - 1;
2203
2204 int cur_frame_width = std_pic_info->flags.use_superres ? downscaled_width : frameExtent.width;
2205 int cur_frame_height = frameExtent.height;
2206
2207 uint32_t h_scale_factor =
2208 ((ref_width + 1) * av1_scaling_factor + (cur_frame_width >> 1)) / cur_frame_width;
2209 uint32_t v_scale_factor =
2210 ((ref_height + 1) * av1_scaling_factor + (cur_frame_height >> 1)) / cur_frame_height;
2211
2212 switch (r) {
2213 case AV1_INTRA_FRAME:
2214 pic.IntraFrameWidthinPixelMinus1 = cur_frame_width - 1;
2215 pic.IntraFrameHeightinPixelMinus1 = cur_frame_height - 1;
2216 pic.VerticalScaleFactorForIntra = av1_scaling_factor;
2217 pic.HorizontalScaleFactorForIntra = av1_scaling_factor;
2218 break;
2219 case AV1_LAST_FRAME:
2220 pic.LastFrameWidthinPixelMinus1 = ref_width;
2221 pic.LastFrameHeightinPixelMinus1 = ref_height;
2222 pic.VerticalScaleFactorForLast = v_scale_factor;
2223 pic.HorizontalScaleFactorForLast = h_scale_factor;
2224 break;
2225 case AV1_LAST2_FRAME:
2226 pic.Last2FrameWidthinPixelMinus1 = ref_width;
2227 pic.Last2FrameHeightinPixelMinus1 = ref_height;
2228 pic.VerticalScaleFactorForLast2 = v_scale_factor;
2229 pic.HorizontalScaleFactorForLast2 = h_scale_factor;
2230 break;
2231 case AV1_LAST3_FRAME:
2232 pic.Last3FrameWidthinPixelMinus1 = ref_width;
2233 pic.Last3FrameHeightinPixelMinus1 = ref_height;
2234 pic.VerticalScaleFactorForLast3 = v_scale_factor;
2235 pic.HorizontalScaleFactorForLast3 = h_scale_factor;
2236 break;
2237 case AV1_GOLDEN_FRAME:
2238 pic.GoldenFrameWidthinPixelMinus1 = ref_width;
2239 pic.GoldenFrameHeightinPixelMinus1 = ref_height;
2240 pic.VerticalScaleFactorForGolden = v_scale_factor;
2241 pic.HorizontalScaleFactorForGolden = h_scale_factor;
2242 break;
2243 case AV1_BWDREF_FRAME:
2244 pic.BWDREFFrameWidthinPixelMinus1 = ref_width;
2245 pic.BWDREFFrameHeightinPixelMinus1 = ref_height;
2246 pic.VerticalScaleFactorForBWDREF = v_scale_factor;
2247 pic.HorizontalScaleFactorForBWDREF = h_scale_factor;
2248 break;
2249 case AV1_ALTREF2_FRAME:
2250 pic.ALTREF2FrameWidthinPixelMinus1 = ref_width;
2251 pic.ALTREF2FrameHeightinPixelMinus1 = ref_height;
2252 pic.VerticalScaleFactorForALTREF2 = v_scale_factor;
2253 pic.HorizontalScaleFactorForALTREF2 = h_scale_factor;
2254 break;
2255 case AV1_ALTREF_FRAME:
2256 pic.ALTREFFrameWidthinPixelMinus1 = ref_width;
2257 pic.ALTREFFrameHeightinPixelMinus1 = ref_height;
2258 pic.VerticalScaleFactorForALTREF = v_scale_factor;
2259 pic.HorizontalScaleFactorForALTREF = h_scale_factor;
2260 break;
2261 default:
2262 break;
2263 }
2264 }
2265 }
2266
2267 pic.FrameLevelGlobalMotionInvalidFlags = 0;
2268 for (enum av1_ref_frame r = AV1_INTRA_FRAME; r <= AV1_ALTREF_FRAME; r++)
2269 pic.ReferenceFrameOrderHint[r] = ref_info[r].order_hint;
2270 };
2271
2272 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_INTER_PRED_STATE), inter) {
2273 inter.ActiveReferenceBitmask = ref_mask;
2274
2275 for (enum av1_ref_frame r = AV1_LAST_FRAME; r <= AV1_ALTREF_FRAME; r++) {
2276 switch (r) {
2277 case AV1_LAST_FRAME:
2278 for (unsigned j = 0; j < 7; j++)
2279 inter.SavedOrderHints0[j] = ref_info[r].ref_order_hints[j + 1];
2280 break;
2281 case AV1_LAST2_FRAME:
2282 for (unsigned j = 0; j < 7; j++)
2283 inter.SavedOrderHints1[j] = ref_info[r].ref_order_hints[j + 1];
2284 break;
2285 case AV1_LAST3_FRAME:
2286 for (unsigned j = 0; j < 7; j++)
2287 inter.SavedOrderHints2[j] = ref_info[r].ref_order_hints[j + 1];
2288 break;
2289 case AV1_GOLDEN_FRAME:
2290 for (unsigned j = 0; j < 7; j++)
2291 inter.SavedOrderHints3[j] = ref_info[r].ref_order_hints[j + 1];
2292 break;
2293 case AV1_BWDREF_FRAME:
2294 for (unsigned j = 0; j < 7; j++)
2295 inter.SavedOrderHints4[j] = ref_info[r].ref_order_hints[j + 1];
2296 break;
2297 case AV1_ALTREF2_FRAME:
2298 for (unsigned j = 0; j < 7; j++)
2299 inter.SavedOrderHints5[j] = ref_info[r].ref_order_hints[j + 1];
2300 break;
2301 case AV1_ALTREF_FRAME:
2302 for (unsigned j = 0; j < 7; j++)
2303 inter.SavedOrderHints6[j] = ref_info[r].ref_order_hints[j + 1];
2304 break;
2305 default:
2306 break;
2307 }
2308 }
2309 }
2310
2311 for (unsigned i = 0; i < 8; ++i) {
2312 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_SEGMENT_STATE), seg) {
2313 seg.SegmentID = i;
2314 seg.SegmentFeatureMask = std_pic_info->pSegmentation->FeatureEnabled[i];
2315 seg.SegmentDeltaQindex = std_pic_info->pSegmentation->FeatureData[i][SEG_LVL_ALT_Q];
2316 seg.SegmentBlockSkipFlag = std_pic_info->pSegmentation->FeatureData[i][SEG_LVL_SKIP];
2317 seg.SegmentBlockGlobalMVFlag = std_pic_info->pSegmentation->FeatureData[i][SEG_LVL_GLOBAL_MV];
2318 seg.SegmentLosslessFlag = lossless[i];
2319 if (lossless[i] || !std_pic_info->pQuantization->flags.using_qmatrix) {
2320 seg.SegmentLumaYQMLevel = av1_num_qm_levels - 1;
2321 seg.SegmentChromaUQMLevel = av1_num_qm_levels - 1;
2322 seg.SegmentChromaVQMLevel = av1_num_qm_levels - 1;
2323 } else {
2324 seg.SegmentLumaYQMLevel = std_pic_info->pQuantization->qm_y;
2325 seg.SegmentChromaUQMLevel = std_pic_info->pQuantization->qm_u;
2326 seg.SegmentChromaVQMLevel = std_pic_info->pQuantization->qm_v;
2327 }
2328 /* TODO. handling negative values?
2329 seg.SegmentDeltaLoopFilterLevelLumaVertical = std_pic_info->pSegmentation->FeatureData[i][SEG_LVL_ALT_LFYV];
2330 seg.SegmentDeltaLoopFilterLevelLumaHorizontal = std_pic_info->pSegmentation->FeatureData[i][SEG_LVL_ALT_LFYH];
2331 seg.SegmentDeltaLoopFilterLevelChromaU = std_pic_info->pSegmentation->FeatureData[i][SEG_LVL_ALT_LFU];
2332 seg.SegmentDeltaLoopFilterLevelChromaV = std_pic_info->pSegmentation->FeatureData[i][SEG_LVL_ALT_LFV];
2333 seg.SegmentReferenceFrame = std_pic_info->pSegmentation->FeatureData[i][SEG_LVL_REF_FRAME];
2334 */
2335 };
2336
2337 if (!std_pic_info->flags.segmentation_enabled)
2338 break;
2339 }
2340
2341 const StdVideoAV1LoopFilter *lf = std_pic_info->pLoopFilter;
2342 const StdVideoAV1CDEF *cdef = std_pic_info->pCDEF;
2343 uint32_t cdef_strengths[8] = { 0 }, cdef_uv_strengths[8] = { 0 };
2344 for (unsigned i = 0; i < (1 << cdef->cdef_bits); ++i) {
2345 cdef_strengths[i] = (cdef->cdef_y_pri_strength[i] << 2) +
2346 cdef->cdef_y_sec_strength[i];
2347 cdef_uv_strengths[i] = (cdef->cdef_uv_pri_strength[i] << 2) +
2348 cdef->cdef_uv_sec_strength[i];
2349 }
2350
2351 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_INLOOP_FILTER_STATE), fil) {
2352 fil.LumaYDeblockerFilterLevelVertical = lf->loop_filter_level[0];
2353 fil.LumaYDeblockerFilterLevelHorizontal = lf->loop_filter_level[1];
2354 fil.ChromaUDeblockerFilterLevel = lf->loop_filter_level[2];
2355 fil.ChromaVDeblockerFilterLevel = lf->loop_filter_level[3];
2356 fil.DeblockerFilterSharpnessLevel = lf->loop_filter_sharpness;
2357 fil.DeblockerFilterModeRefDeltaEnableFlag = lf->flags.loop_filter_delta_enabled;
2358 fil.DeblockerDeltaLFResolution = std_pic_info->delta_lf_res;
2359 fil.DeblockerFilterDeltaLFMultiFlag = std_pic_info->flags.delta_lf_multi;
2360 fil.DeblockerFilterDeltaLFPresentFlag = std_pic_info->flags.delta_lf_present;
2361 fil.DeblockerFilterRefDeltas0 = lf->loop_filter_ref_deltas[0];
2362 fil.DeblockerFilterRefDeltas1 = lf->loop_filter_ref_deltas[1];
2363 fil.DeblockerFilterRefDeltas2 = lf->loop_filter_ref_deltas[2];
2364 fil.DeblockerFilterRefDeltas3 = lf->loop_filter_ref_deltas[3];
2365 fil.DeblockerFilterRefDeltas4 = lf->loop_filter_ref_deltas[4];
2366 fil.DeblockerFilterRefDeltas5 = lf->loop_filter_ref_deltas[5];
2367 fil.DeblockerFilterRefDeltas6 = lf->loop_filter_ref_deltas[6];
2368 fil.DeblockerFilterRefDeltas7 = lf->loop_filter_ref_deltas[7];
2369 fil.DeblockerFilterModeDeltas0 = lf->loop_filter_mode_deltas[0];
2370 fil.DeblockerFilterModeDeltas1 = lf->loop_filter_mode_deltas[1];
2371 fil.CDEFYStrength0 = cdef_strengths[0];
2372 fil.CDEFYStrength1 = cdef_strengths[1];
2373 fil.CDEFYStrength2 = cdef_strengths[2];
2374 fil.CDEFYStrength3 = cdef_strengths[3];
2375 fil.CDEFBits = cdef->cdef_bits;
2376 fil.CDEFFilterDmpaingFactorMinus3 = cdef->cdef_damping_minus_3;
2377 fil.CDEFYStrength4 = cdef_strengths[4];
2378 fil.CDEFYStrength5 = cdef_strengths[5];
2379 fil.CDEFYStrength6 = cdef_strengths[6];
2380 fil.CDEFYStrength7 = cdef_strengths[7];
2381 fil.CDEFUVStrength0 = cdef_uv_strengths[0];
2382 fil.CDEFUVStrength1 = cdef_uv_strengths[1];
2383 fil.CDEFUVStrength2 = cdef_uv_strengths[2];
2384 fil.CDEFUVStrength3 = cdef_uv_strengths[3];
2385 fil.CDEFUVStrength4 = cdef_uv_strengths[4];
2386 fil.CDEFUVStrength5 = cdef_uv_strengths[5];
2387 fil.CDEFUVStrength6 = cdef_uv_strengths[6];
2388 fil.CDEFUVStrength7 = cdef_uv_strengths[7];
2389 fil.SuperResUpscaledFrameWidthMinus1 = frameExtent.width - 1;
2390 fil.SuperResDenom = std_pic_info->flags.use_superres ? denom : 8;
2391 fil.FrameLoopRestorationFilterLumaY = frame_restoration_type[0];
2392 fil.FrameLoopRestorationFilterChromaU = frame_restoration_type[1];
2393 fil.FrameLoopRestorationFilterChromaV = frame_restoration_type[2];
2394
2395 bool loop_restoration_filter_enable =
2396 frame_restoration_type[0] || frame_restoration_type[1] || frame_restoration_type[2];
2397
2398 fil.LoopRestorationUnitSizeLumaY =loop_restoration_filter_enable ?
2399 std_pic_info->pLoopRestoration->LoopRestorationSize[0] : 0;
2400 fil.UseSameLoopRestorationUnitSizeChromasUVFlag = (frame_restoration_type[1] != 0 || frame_restoration_type[2] !=0) ?
2401 std_pic_info->pLoopRestoration->LoopRestorationSize[0] == std_pic_info->pLoopRestoration->LoopRestorationSize[1] : false;
2402
2403 fil.LumaPlanex_step_qn = luma_xstep_qn;
2404 fil.LumaPlanex0_qn = luma_x0_qn[tile_idx];
2405 fil.ChromaPlanex_step_qn = chroma_xstep_qn;
2406 fil.ChromaPlanex0_qn = chroma_x0_qn[tile_idx];
2407
2408 };
2409
2410 unsigned column = tile_idx % std_pic_info->pTileInfo->TileCols;
2411 unsigned row = tile_idx / std_pic_info->pTileInfo->TileCols;
2412 bool last_tile = (column == std_pic_info->pTileInfo->TileCols - 1) &&
2413 (row == std_pic_info->pTileInfo->TileRows - 1);
2414
2415 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_TILE_CODING), til) {
2416 til.FrameTileID = tile_idx;
2417 til.TGTileNum = tile_idx;
2418 til.TileGroupID = 0;
2419 til.TileColumnPositioninSBUnit = std_pic_info->pTileInfo->pMiColStarts[column];
2420 til.TileRowPositioninSBUnit = std_pic_info->pTileInfo->pMiRowStarts[row];
2421 til.TileWidthinSBMinus1 = std_pic_info->pTileInfo->pWidthInSbsMinus1[column];
2422 til.TileHeightinSBMinus1 = std_pic_info->pTileInfo->pHeightInSbsMinus1[row];
2423 til.IsLastTileofRowFlag = column == std_pic_info->pTileInfo->TileCols - 1;
2424 til.IsLastTileofColumnFlag = row == std_pic_info->pTileInfo->TileRows - 1;
2425 til.IsStartTileofTileGroupFlag = tile_idx == 0;
2426 til.IsEndTileofTileGroupFlag = (column == std_pic_info->pTileInfo->TileCols - 1) &&
2427 (row == std_pic_info->pTileInfo->TileRows - 1);
2428 til.IsLastTileofFrameFlag = (column == std_pic_info->pTileInfo->TileCols - 1) &&
2429 (row == std_pic_info->pTileInfo->TileRows - 1);
2430 til.DisableCDFUpdateFlag = std_pic_info->flags.disable_cdf_update;
2431 til.DisableFrameContextUpdateFlag = std_pic_info->flags.disable_frame_end_update_cdf || (tile_idx != std_pic_info->pTileInfo->context_update_tile_id);
2432 til.NumberofActiveBEPipes = 1;
2433 til.NumofTileColumnsinFrameMinus1 = std_pic_info->pTileInfo->TileCols - 1;
2434 til.NumofTileRowsinFrameMinus1 = std_pic_info->pTileInfo->TileRows - 1;
2435 };
2436
2437 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_BSD_OBJECT), bsd) {
2438 bsd.TileIndirectBSDDataLength = av1_pic_info->pTileSizes[tile_idx];
2439 bsd.TileIndirectDataStartAddress = (frame_info->srcBufferOffset & 4095) +
2440 av1_pic_info->pTileOffsets[tile_idx];
2441 };
2442
2443 if (last_tile) {
2444 anv_batch_emit(&cmd_buffer->batch, GENX(AVP_VD_CONTROL_STATE), vd) {
2445 vd.VDControlState.MemoryImplicitFlush = 1;
2446 }
2447
2448 anv_batch_emit(&cmd_buffer->batch, GENX(VD_PIPELINE_FLUSH), vd) {
2449 vd.AVPPipelineDone = 1;
2450 vd.VDCommandMessageParserDone = 1;
2451 vd.AVPPipelineCommandFlush = 1;
2452 }
2453 }
2454
2455 /* Set necessary info from current refs to the prev_refs */
2456 for (int i = 0; i < STD_VIDEO_AV1_NUM_REF_FRAMES; ++i) {
2457 vid->prev_refs[i].img = ref_info[i].img;
2458 vid->prev_refs[i].default_cdf_index =
2459 i == 0 ? ref_info[i].default_cdf_index :
2460 find_cdf_index(NULL, ref_info, ref_info[i].img);
2461 }
2462 }
2463
2464 static void
anv_av1_calculate_xstep_qn(struct anv_cmd_buffer * cmd_buffer,const VkVideoDecodeInfoKHR * frame_info)2465 anv_av1_calculate_xstep_qn(struct anv_cmd_buffer *cmd_buffer,
2466 const VkVideoDecodeInfoKHR *frame_info)
2467 {
2468 const VkVideoDecodeAV1PictureInfoKHR *av1_pic_info =
2469 vk_find_struct_const(frame_info->pNext, VIDEO_DECODE_AV1_PICTURE_INFO_KHR);
2470
2471 const StdVideoDecodeAV1PictureInfo *std_pic_info = av1_pic_info->pStdPictureInfo;
2472 struct anv_video_session_params *params = cmd_buffer->video.params;
2473 const StdVideoAV1SequenceHeader *seq_hdr = ¶ms->vk.av1_dec.seq_hdr.base;
2474 VkExtent2D frameExtent = frame_info->dstPictureResource.codedExtent;
2475 unsigned tile_cols = std_pic_info->pTileInfo->TileCols;
2476
2477 if (!std_pic_info->flags.use_superres) {
2478 luma_xstep_qn = chroma_xstep_qn = 0;
2479 memset(luma_x0_qn, 0, sizeof(luma_x0_qn));
2480 memset(chroma_x0_qn, 0, sizeof(chroma_x0_qn));
2481
2482 return;
2483 }
2484
2485 int32_t mib_size_log2 = seq_hdr->flags.use_128x128_superblock ?
2486 av1_max_mib_size_log2 : av1_min_mib_size_log2;
2487
2488 int32_t mi_cols = ALIGN(frameExtent.width, 8) >> mib_size_log2;
2489
2490 int denom = std_pic_info->coded_denom + 9;
2491 unsigned downscaled_width = (frameExtent.width * 8 + denom / 2) / denom;
2492
2493 for (uint8_t i = 0; i < 2; i++) { /* i == 0 : luma, i == 1 : chroma */
2494 int subsampling_x = seq_hdr->pColorConfig->subsampling_x;
2495 int ssx = i & subsampling_x;
2496 int downscaled = ALIGN(downscaled_width, 2) >> ssx;
2497 int upscaled = ALIGN(frameExtent.width, 2) >> ssx;
2498
2499 int xstep_qn = ((downscaled << av1_rs_scale_subpel_bits) + upscaled / 2) / upscaled;
2500
2501 if (i == 0)
2502 luma_xstep_qn = xstep_qn;
2503 else
2504 chroma_xstep_qn = xstep_qn;
2505
2506 int32_t err = upscaled * xstep_qn - (downscaled << av1_rs_scale_subpel_bits);
2507 int32_t x0 = (-((upscaled - downscaled) << (av1_rs_scale_subpel_bits - 1)) + upscaled / 2) /
2508 upscaled + av1_rs_scale_extra_off - err / 2;
2509
2510 x0 = (int32_t)(x0 & av1_rs_scale_subpel_mask);
2511
2512 for (unsigned j = 0; j < tile_cols; j++) {
2513 int32_t tile_col_end_sb;
2514 bool last_col = (j == tile_cols - 1);
2515
2516 if (i == 0)
2517 luma_x0_qn[j] = x0;
2518 else
2519 chroma_x0_qn[j] = x0;
2520
2521 if (!last_col) {
2522 tile_col_end_sb = std_pic_info->pTileInfo->pMiColStarts[j + 1];
2523 } else {
2524 tile_col_end_sb = std_pic_info->pTileInfo->pMiColStarts[tile_cols - 1] +
2525 std_pic_info->pTileInfo->pWidthInSbsMinus1[tile_cols - 1];
2526 }
2527
2528
2529 int32_t mi_col_end = tile_col_end_sb >> mib_size_log2;
2530 mi_col_end = MIN2(mi_col_end, mi_cols);
2531
2532 int32_t downscaled_x1 = mi_col_end << (av1_mi_size_log2 - ssx);
2533 int32_t downscaled_x0 = std_pic_info->pTileInfo->pMiColStarts[j] << mib_size_log2 << (av1_mi_size_log2 - ssx);
2534
2535 int32_t src_w = downscaled_x1 - downscaled_x0;
2536 int32_t upscaled_x0 = (downscaled_x0 * denom) / 8;
2537 int32_t upscaled_x1;
2538
2539 if (last_col) {
2540 upscaled_x1 = upscaled;
2541 } else
2542 upscaled_x1 = (downscaled_x1 * denom) / 8;
2543
2544 int32_t dst_w = upscaled_x1 - upscaled_x0;
2545
2546 x0 += (dst_w * xstep_qn) - (src_w << av1_rs_scale_subpel_bits);
2547 }
2548
2549 }
2550 }
2551
2552 static void
anv_av1_decode_video(struct anv_cmd_buffer * cmd_buffer,const VkVideoDecodeInfoKHR * frame_info)2553 anv_av1_decode_video(struct anv_cmd_buffer *cmd_buffer,
2554 const VkVideoDecodeInfoKHR *frame_info)
2555 {
2556 const VkVideoDecodeAV1PictureInfoKHR *av1_pic_info =
2557 vk_find_struct_const(frame_info->pNext, VIDEO_DECODE_AV1_PICTURE_INFO_KHR);
2558
2559 anv_av1_calculate_xstep_qn(cmd_buffer, frame_info);
2560
2561 for (unsigned t = 0; t < av1_pic_info->tileCount; t++)
2562 anv_av1_decode_video_tile(cmd_buffer, frame_info, t);
2563 }
2564 #endif
2565
2566 static void
handle_inline_query_end(struct anv_cmd_buffer * cmd_buffer,const VkVideoInlineQueryInfoKHR * inline_query)2567 handle_inline_query_end(struct anv_cmd_buffer *cmd_buffer,
2568 const VkVideoInlineQueryInfoKHR *inline_query)
2569 {
2570 ANV_FROM_HANDLE(anv_query_pool, pool, inline_query->queryPool);
2571 if (pool == VK_NULL_HANDLE)
2572 return;
2573
2574 struct anv_address query_addr = {
2575 .bo = pool->bo,
2576 .offset = inline_query->firstQuery * pool->stride,
2577 };
2578
2579 anv_batch_emit(&cmd_buffer->batch, GENX(MI_FLUSH_DW), flush) {
2580 flush.PostSyncOperation = WriteImmediateData;
2581 flush.Address = query_addr;
2582 flush.ImmediateData = true;
2583 }
2584 }
2585
2586 void
genX(CmdDecodeVideoKHR)2587 genX(CmdDecodeVideoKHR)(VkCommandBuffer commandBuffer,
2588 const VkVideoDecodeInfoKHR *frame_info)
2589 {
2590 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
2591
2592 if (anv_batch_has_error(&cmd_buffer->batch))
2593 return;
2594
2595 const VkVideoInlineQueryInfoKHR *inline_query =
2596 vk_find_struct_const(frame_info->pNext, VIDEO_INLINE_QUERY_INFO_KHR);
2597
2598 switch (cmd_buffer->video.vid->vk.op) {
2599 case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
2600 anv_h264_decode_video(cmd_buffer, frame_info);
2601 break;
2602 case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
2603 anv_h265_decode_video(cmd_buffer, frame_info);
2604 break;
2605 #if GFX_VERx10 >= 120
2606 case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR:
2607 anv_av1_decode_video(cmd_buffer, frame_info);
2608 break;
2609 #endif
2610 default:
2611 assert(0);
2612 }
2613
2614 if (inline_query)
2615 handle_inline_query_end(cmd_buffer, inline_query);
2616 }
2617