• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&params->vk, h265_pic_info->pStdPictureInfo->pps_seq_parameter_set_id);
185    const StdVideoH265PictureParameterSet *pps =
186       vk_video_find_h265_dec_std_pps(&params->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(&params->vk, h264_pic_info->pStdPictureInfo->seq_parameter_set_id);
892    const StdVideoH264PictureParameterSet *pps = vk_video_find_h264_dec_std_pps(&params->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 = &params->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 = &params->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