xref: /aosp_15_r20/external/mesa3d/src/intel/vulkan/anv_video.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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 "vk_video/vulkan_video_codecs_common.h"
27 
28 VkResult
anv_CreateVideoSessionKHR(VkDevice _device,const VkVideoSessionCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkVideoSessionKHR * pVideoSession)29 anv_CreateVideoSessionKHR(VkDevice _device,
30                            const VkVideoSessionCreateInfoKHR *pCreateInfo,
31                            const VkAllocationCallbacks *pAllocator,
32                            VkVideoSessionKHR *pVideoSession)
33 {
34    ANV_FROM_HANDLE(anv_device, device, _device);
35 
36    struct anv_video_session *vid =
37       vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*vid), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
38    if (!vid)
39       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
40 
41    memset(vid, 0, sizeof(struct anv_video_session));
42 
43    VkResult result = vk_video_session_init(&device->vk,
44                                            &vid->vk,
45                                            pCreateInfo);
46    if (result != VK_SUCCESS) {
47       vk_free2(&device->vk.alloc, pAllocator, vid);
48       return result;
49    }
50 
51    *pVideoSession = anv_video_session_to_handle(vid);
52    return VK_SUCCESS;
53 }
54 
55 void
anv_DestroyVideoSessionKHR(VkDevice _device,VkVideoSessionKHR _session,const VkAllocationCallbacks * pAllocator)56 anv_DestroyVideoSessionKHR(VkDevice _device,
57                            VkVideoSessionKHR _session,
58                            const VkAllocationCallbacks *pAllocator)
59 {
60    ANV_FROM_HANDLE(anv_device, device, _device);
61    ANV_FROM_HANDLE(anv_video_session, vid, _session);
62    if (!_session)
63       return;
64 
65    vk_object_base_finish(&vid->vk.base);
66    vk_free2(&device->vk.alloc, pAllocator, vid);
67 }
68 
69 VkResult
anv_CreateVideoSessionParametersKHR(VkDevice _device,const VkVideoSessionParametersCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkVideoSessionParametersKHR * pVideoSessionParameters)70 anv_CreateVideoSessionParametersKHR(VkDevice _device,
71                                      const VkVideoSessionParametersCreateInfoKHR *pCreateInfo,
72                                      const VkAllocationCallbacks *pAllocator,
73                                      VkVideoSessionParametersKHR *pVideoSessionParameters)
74 {
75    ANV_FROM_HANDLE(anv_device, device, _device);
76    ANV_FROM_HANDLE(anv_video_session, vid, pCreateInfo->videoSession);
77    ANV_FROM_HANDLE(anv_video_session_params, templ, pCreateInfo->videoSessionParametersTemplate);
78    struct anv_video_session_params *params =
79       vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*params), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
80    if (!params)
81       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
82 
83    VkResult result = vk_video_session_parameters_init(&device->vk,
84                                                       &params->vk,
85                                                       &vid->vk,
86                                                       templ ? &templ->vk : NULL,
87                                                       pCreateInfo);
88    if (result != VK_SUCCESS) {
89       vk_free2(&device->vk.alloc, pAllocator, params);
90       return result;
91    }
92 
93    *pVideoSessionParameters = anv_video_session_params_to_handle(params);
94    return VK_SUCCESS;
95 }
96 
97 void
anv_DestroyVideoSessionParametersKHR(VkDevice _device,VkVideoSessionParametersKHR _params,const VkAllocationCallbacks * pAllocator)98 anv_DestroyVideoSessionParametersKHR(VkDevice _device,
99                                       VkVideoSessionParametersKHR _params,
100                                       const VkAllocationCallbacks *pAllocator)
101 {
102    ANV_FROM_HANDLE(anv_device, device, _device);
103    ANV_FROM_HANDLE(anv_video_session_params, params, _params);
104    if (!_params)
105       return;
106    vk_video_session_parameters_finish(&device->vk, &params->vk);
107    vk_free2(&device->vk.alloc, pAllocator, params);
108 }
109 
110 VkResult
anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice,const VkVideoProfileInfoKHR * pVideoProfile,VkVideoCapabilitiesKHR * pCapabilities)111 anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice,
112                                            const VkVideoProfileInfoKHR *pVideoProfile,
113                                            VkVideoCapabilitiesKHR *pCapabilities)
114 {
115    ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
116 
117    pCapabilities->minBitstreamBufferOffsetAlignment = 32;
118    pCapabilities->minBitstreamBufferSizeAlignment = 32;
119    pCapabilities->maxCodedExtent.width = 4096;
120    pCapabilities->maxCodedExtent.height = 4096;
121    pCapabilities->flags = VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
122 
123    struct VkVideoDecodeCapabilitiesKHR *dec_caps = (struct VkVideoDecodeCapabilitiesKHR *)
124       vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_CAPABILITIES_KHR);
125    if (dec_caps)
126       dec_caps->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR;
127 
128    /* H264 allows different luma and chroma bit depths */
129    if (pVideoProfile->lumaBitDepth != pVideoProfile->chromaBitDepth)
130       return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR;
131 
132    if (pVideoProfile->chromaSubsampling != VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR)
133       return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR;
134 
135    switch (pVideoProfile->videoCodecOperation) {
136    case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: {
137       struct VkVideoDecodeH264CapabilitiesKHR *ext = (struct VkVideoDecodeH264CapabilitiesKHR *)
138          vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_H264_CAPABILITIES_KHR);
139 
140       if (pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR)
141          return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR;
142 
143       pCapabilities->maxDpbSlots = 17;
144       pCapabilities->maxActiveReferencePictures = ANV_VIDEO_H264_MAX_NUM_REF_FRAME;
145       pCapabilities->pictureAccessGranularity.width = ANV_MB_WIDTH;
146       pCapabilities->pictureAccessGranularity.height = ANV_MB_HEIGHT;
147       pCapabilities->minCodedExtent.width = ANV_MB_WIDTH;
148       pCapabilities->minCodedExtent.height = ANV_MB_HEIGHT;
149 
150       ext->fieldOffsetGranularity.x = 0;
151       ext->fieldOffsetGranularity.y = 0;
152       ext->maxLevelIdc = STD_VIDEO_H264_LEVEL_IDC_5_1;
153       strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME);
154       pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION;
155       break;
156    }
157    case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: {
158       struct VkVideoDecodeH265CapabilitiesKHR *ext = (struct VkVideoDecodeH265CapabilitiesKHR *)
159          vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_H265_CAPABILITIES_KHR);
160 
161       const struct VkVideoDecodeH265ProfileInfoKHR *h265_profile =
162          vk_find_struct_const(pVideoProfile->pNext,
163                               VIDEO_DECODE_H265_PROFILE_INFO_KHR);
164 
165       /* No hardware supports the scc extension profile */
166       if (h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN &&
167           h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_10 &&
168           h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE &&
169           h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS)
170          return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR;
171 
172       /* Skylake only supports the main profile */
173       if (h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN &&
174           h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE &&
175           pdevice->info.platform <= INTEL_PLATFORM_SKL)
176          return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR;
177 
178       /* Gfx10 and under don't support the range extension profile */
179       if (h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN &&
180           h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_10 &&
181           h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE &&
182           pdevice->info.ver <= 10)
183          return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR;
184 
185       if (pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR &&
186           pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR)
187          return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR;
188 
189       pCapabilities->pictureAccessGranularity.width = ANV_MAX_H265_CTB_SIZE;
190       pCapabilities->pictureAccessGranularity.height = ANV_MAX_H265_CTB_SIZE;
191       pCapabilities->minCodedExtent.width = ANV_MAX_H265_CTB_SIZE;
192       pCapabilities->minCodedExtent.height = ANV_MAX_H265_CTB_SIZE;
193       pCapabilities->maxDpbSlots = ANV_VIDEO_H265_MAX_NUM_REF_FRAME;
194       pCapabilities->maxActiveReferencePictures = ANV_VIDEO_H265_HCP_NUM_REF_FRAME;
195 
196       ext->maxLevelIdc = STD_VIDEO_H265_LEVEL_IDC_6_2;
197 
198       strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME);
199       pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION;
200       break;
201    }
202    default:
203       break;
204    }
205 
206    struct VkVideoEncodeCapabilitiesKHR *enc_caps = (struct VkVideoEncodeCapabilitiesKHR *)
207       vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_CAPABILITIES_KHR);
208 
209    if (enc_caps) {
210       enc_caps->flags = 0;
211       enc_caps->rateControlModes = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR;
212       enc_caps->maxRateControlLayers = 1;
213       enc_caps->maxQualityLevels = 1;
214       enc_caps->encodeInputPictureGranularity.width = 32;
215       enc_caps->encodeInputPictureGranularity.height = 32;
216       enc_caps->supportedEncodeFeedbackFlags =
217          VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR |
218          VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
219    }
220 
221    switch (pVideoProfile->videoCodecOperation) {
222    case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR: {
223       struct VkVideoEncodeH264CapabilitiesKHR *ext = (struct VkVideoEncodeH264CapabilitiesKHR *)
224          vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_H264_CAPABILITIES_KHR);
225 
226       if (ext) {
227          ext->flags = VK_VIDEO_ENCODE_H264_CAPABILITY_HRD_COMPLIANCE_BIT_KHR;
228          ext->maxLevelIdc = STD_VIDEO_H264_LEVEL_IDC_5_1;
229          ext->maxSliceCount = 1;
230          ext->maxPPictureL0ReferenceCount = 8;
231          ext->maxBPictureL0ReferenceCount = 8;
232          ext->maxL1ReferenceCount = 0;
233          ext->maxTemporalLayerCount = 0;
234          ext->expectDyadicTemporalLayerPattern = false;
235          ext->prefersGopRemainingFrames = 0;
236          ext->requiresGopRemainingFrames = 0;
237          ext->minQp = 10;
238          ext->maxQp = 51;
239       }
240 
241       pCapabilities->minBitstreamBufferOffsetAlignment = 32;
242       pCapabilities->minBitstreamBufferSizeAlignment = 4096;
243 
244       pCapabilities->maxDpbSlots = ANV_VIDEO_H264_MAX_NUM_REF_FRAME;
245       pCapabilities->maxActiveReferencePictures = ANV_VIDEO_H264_MAX_NUM_REF_FRAME;
246       pCapabilities->pictureAccessGranularity.width = ANV_MB_WIDTH;
247       pCapabilities->pictureAccessGranularity.height = ANV_MB_HEIGHT;
248       pCapabilities->minCodedExtent.width = ANV_MB_WIDTH;
249       pCapabilities->minCodedExtent.height = ANV_MB_HEIGHT;
250 
251       strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME);
252       pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION;
253       break;
254    }
255    case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR: {
256       struct VkVideoEncodeH265CapabilitiesKHR *ext = (struct VkVideoEncodeH265CapabilitiesKHR *)
257          vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_H265_CAPABILITIES_KHR);
258 
259       if (ext) {
260          ext->flags = 0;
261          ext->maxLevelIdc = STD_VIDEO_H265_LEVEL_IDC_5_1;
262          ext->ctbSizes = VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_KHR;
263          ext->transformBlockSizes = VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_KHR |
264                                     VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_KHR |
265                                     VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_KHR |
266                                     VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_KHR;
267          ext->maxPPictureL0ReferenceCount = 8;
268          ext->maxBPictureL0ReferenceCount = 8;
269          ext->maxL1ReferenceCount = 1;
270          ext->minQp = 10;
271          ext->maxQp = 51;
272          ext->maxSliceSegmentCount = 128;
273          ext->maxTiles.width = 1;
274          ext->maxTiles.height = 1;
275          ext->maxSubLayerCount = 1;
276          ext->expectDyadicTemporalSubLayerPattern = false;
277          ext->prefersGopRemainingFrames = 0;
278          ext->requiresGopRemainingFrames = 0;
279       }
280 
281       pCapabilities->minBitstreamBufferOffsetAlignment = 4096;
282       pCapabilities->minBitstreamBufferSizeAlignment = 4096;
283 
284       pCapabilities->maxDpbSlots = ANV_VIDEO_H265_MAX_NUM_REF_FRAME;
285       pCapabilities->maxActiveReferencePictures = ANV_VIDEO_H265_MAX_NUM_REF_FRAME;
286       pCapabilities->pictureAccessGranularity.width = ANV_MAX_H265_CTB_SIZE;
287       pCapabilities->pictureAccessGranularity.height = ANV_MAX_H265_CTB_SIZE;
288       pCapabilities->minCodedExtent.width = ANV_MAX_H265_CTB_SIZE;
289       pCapabilities->minCodedExtent.height = ANV_MAX_H265_CTB_SIZE;
290 
291       strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME);
292       pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION;
293       break;
294    }
295    default:
296       break;
297    }
298 
299    return VK_SUCCESS;
300 }
301 
302 VkResult
anv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceVideoFormatInfoKHR * pVideoFormatInfo,uint32_t * pVideoFormatPropertyCount,VkVideoFormatPropertiesKHR * pVideoFormatProperties)303 anv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
304                                                const VkPhysicalDeviceVideoFormatInfoKHR *pVideoFormatInfo,
305                                                uint32_t *pVideoFormatPropertyCount,
306                                                VkVideoFormatPropertiesKHR *pVideoFormatProperties)
307 {
308    VK_OUTARRAY_MAKE_TYPED(VkVideoFormatPropertiesKHR, out,
309                           pVideoFormatProperties,
310                           pVideoFormatPropertyCount);
311 
312    bool need_10bit = false;
313    const struct VkVideoProfileListInfoKHR *prof_list = (struct VkVideoProfileListInfoKHR *)
314       vk_find_struct_const(pVideoFormatInfo->pNext, VIDEO_PROFILE_LIST_INFO_KHR);
315 
316    if (prof_list) {
317       for (unsigned i = 0; i < prof_list->profileCount; i++) {
318          const VkVideoProfileInfoKHR *profile = &prof_list->pProfiles[i];
319          if (profile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR ||
320              profile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR)
321             need_10bit = true;
322       }
323    }
324 
325    vk_outarray_append_typed(VkVideoFormatPropertiesKHR, &out, p) {
326       p->format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
327       p->imageType = VK_IMAGE_TYPE_2D;
328       p->imageTiling = VK_IMAGE_TILING_OPTIMAL;
329       p->imageUsageFlags = pVideoFormatInfo->imageUsage;
330    }
331 
332    if (need_10bit) {
333       vk_outarray_append_typed(VkVideoFormatPropertiesKHR, &out, p) {
334          p->format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
335          p->imageType = VK_IMAGE_TYPE_2D;
336          p->imageTiling = VK_IMAGE_TILING_OPTIMAL;
337          p->imageUsageFlags = pVideoFormatInfo->imageUsage;
338       }
339    }
340 
341    return vk_outarray_status(&out);
342 }
343 
344 static uint64_t
get_h264_video_mem_size(struct anv_video_session * vid,uint32_t mem_idx)345 get_h264_video_mem_size(struct anv_video_session *vid, uint32_t mem_idx)
346 {
347    uint32_t width_in_mb =
348       align(vid->vk.max_coded.width, ANV_MB_WIDTH) / ANV_MB_WIDTH;
349 
350    switch (mem_idx) {
351    case ANV_VID_MEM_H264_INTRA_ROW_STORE:
352       return width_in_mb * 64;
353    case ANV_VID_MEM_H264_DEBLOCK_FILTER_ROW_STORE:
354       return width_in_mb * 64 * 4;
355    case ANV_VID_MEM_H264_BSD_MPC_ROW_SCRATCH:
356       return width_in_mb * 64 * 2;
357    case ANV_VID_MEM_H264_MPR_ROW_SCRATCH:
358       return width_in_mb * 64 * 2;
359    default:
360       unreachable("unknown memory");
361    }
362 }
363 
364 static uint64_t
get_h265_video_mem_size(struct anv_video_session * vid,uint32_t mem_idx)365 get_h265_video_mem_size(struct anv_video_session *vid, uint32_t mem_idx)
366 {
367    uint32_t bit_shift =
368       vid->vk.h265.profile_idc == STD_VIDEO_H265_PROFILE_IDC_MAIN_10 ? 2 : 3;
369 
370    /* TODO. these sizes can be determined dynamically depending on ctb sizes of each slice. */
371    uint32_t width_in_ctb =
372       align(vid->vk.max_coded.width, ANV_MAX_H265_CTB_SIZE) / ANV_MAX_H265_CTB_SIZE;
373    uint32_t height_in_ctb =
374       align(vid->vk.max_coded.height, ANV_MAX_H265_CTB_SIZE) / ANV_MAX_H265_CTB_SIZE;
375    uint64_t size;
376 
377    switch (mem_idx) {
378    case ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_LINE:
379    case ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_TILE_LINE:
380       size = align(vid->vk.max_coded.width, 32) >> bit_shift;
381       break;
382    case ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_TILE_COLUMN:
383       size = align(vid->vk.max_coded.height + 6 * height_in_ctb, 32) >> bit_shift;
384       break;
385    case ANV_VID_MEM_H265_METADATA_LINE:
386       size = (((vid->vk.max_coded.width + 15) >> 4) * 188 + width_in_ctb * 9 + 1023) >> 9;
387       break;
388    case ANV_VID_MEM_H265_METADATA_TILE_LINE:
389       size = (((vid->vk.max_coded.width + 15) >> 4) * 172 + width_in_ctb * 9 + 1023) >> 9;
390       break;
391    case ANV_VID_MEM_H265_METADATA_TILE_COLUMN:
392       size = (((vid->vk.max_coded.height + 15) >> 4) * 176 + height_in_ctb * 89 + 1023) >> 9;
393       break;
394    case ANV_VID_MEM_H265_SAO_LINE:
395       size = align((vid->vk.max_coded.width >> 1) + width_in_ctb * 3, 16) >> bit_shift;
396       break;
397    case ANV_VID_MEM_H265_SAO_TILE_LINE:
398       size = align((vid->vk.max_coded.width >> 1) + width_in_ctb * 6, 16) >> bit_shift;
399       break;
400    case ANV_VID_MEM_H265_SAO_TILE_COLUMN:
401       size = align((vid->vk.max_coded.height >> 1) + height_in_ctb * 6, 16) >> bit_shift;
402       break;
403    case ANV_VID_MEM_H265_SSE_SRC_PIX_ROW_STORE: {
404       /* Take the formula from media-driver */
405 #define CACHELINE_SIZE 64
406 #define HEVC_MIN_TILE_SIZE 128
407       uint32_t max_tile_cols = DIV_ROUND_UP(vid->vk.max_coded.width, HEVC_MIN_TILE_SIZE);
408       size = 2 * ((CACHELINE_SIZE * (4 + 4)) << 1) * (width_in_ctb + 3 * max_tile_cols);
409       return size;
410    }
411    default:
412       unreachable("unknown memory");
413    }
414 
415    return size << 6;
416 }
417 
418 static void
get_h264_video_session_mem_reqs(struct anv_video_session * vid,VkVideoSessionMemoryRequirementsKHR * mem_reqs,uint32_t * pVideoSessionMemoryRequirementsCount,uint32_t memory_types)419 get_h264_video_session_mem_reqs(struct anv_video_session *vid,
420                                 VkVideoSessionMemoryRequirementsKHR *mem_reqs,
421                                 uint32_t *pVideoSessionMemoryRequirementsCount,
422                                 uint32_t memory_types)
423 {
424    VK_OUTARRAY_MAKE_TYPED(VkVideoSessionMemoryRequirementsKHR,
425                           out,
426                           mem_reqs,
427                           pVideoSessionMemoryRequirementsCount);
428 
429    for (unsigned i = 0; i < ANV_VID_MEM_H264_MAX; i++) {
430       uint32_t bind_index = ANV_VID_MEM_H264_INTRA_ROW_STORE + i;
431       uint64_t size = get_h264_video_mem_size(vid, i);
432 
433       vk_outarray_append_typed(VkVideoSessionMemoryRequirementsKHR, &out, p) {
434          p->memoryBindIndex = bind_index;
435          p->memoryRequirements.size = size;
436          p->memoryRequirements.alignment = 4096;
437          p->memoryRequirements.memoryTypeBits = memory_types;
438       }
439    }
440 }
441 
442 static void
get_h265_video_session_mem_reqs(struct anv_video_session * vid,VkVideoSessionMemoryRequirementsKHR * mem_reqs,uint32_t * pVideoSessionMemoryRequirementsCount,uint32_t memory_types)443 get_h265_video_session_mem_reqs(struct anv_video_session *vid,
444                                 VkVideoSessionMemoryRequirementsKHR *mem_reqs,
445                                 uint32_t *pVideoSessionMemoryRequirementsCount,
446                                 uint32_t memory_types)
447 {
448    VK_OUTARRAY_MAKE_TYPED(VkVideoSessionMemoryRequirementsKHR,
449                           out,
450                           mem_reqs,
451                           pVideoSessionMemoryRequirementsCount);
452 
453    uint32_t mem_cnt = (vid->vk.op & VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) ?
454                        ANV_VID_MEM_H265_DEC_MAX : ANV_VID_MEM_H265_ENC_MAX;
455 
456    for (unsigned i = 0; i < mem_cnt; i++) {
457       uint32_t bind_index =
458          ANV_VID_MEM_H265_DEBLOCK_FILTER_ROW_STORE_LINE + i;
459       uint64_t size = get_h265_video_mem_size(vid, i);
460 
461       vk_outarray_append_typed(VkVideoSessionMemoryRequirementsKHR, &out, p) {
462          p->memoryBindIndex = bind_index;
463          p->memoryRequirements.size = size;
464          p->memoryRequirements.alignment = 4096;
465          p->memoryRequirements.memoryTypeBits = memory_types;
466       }
467    }
468 }
469 
470 VkResult
anv_GetVideoSessionMemoryRequirementsKHR(VkDevice _device,VkVideoSessionKHR videoSession,uint32_t * pVideoSessionMemoryRequirementsCount,VkVideoSessionMemoryRequirementsKHR * mem_reqs)471 anv_GetVideoSessionMemoryRequirementsKHR(VkDevice _device,
472                                          VkVideoSessionKHR videoSession,
473                                          uint32_t *pVideoSessionMemoryRequirementsCount,
474                                          VkVideoSessionMemoryRequirementsKHR *mem_reqs)
475 {
476    ANV_FROM_HANDLE(anv_device, device, _device);
477    ANV_FROM_HANDLE(anv_video_session, vid, videoSession);
478 
479    uint32_t memory_types =
480       (vid->vk.flags & VK_VIDEO_SESSION_CREATE_PROTECTED_CONTENT_BIT_KHR) ?
481       device->physical->memory.protected_mem_types :
482       device->physical->memory.default_buffer_mem_types;
483    switch (vid->vk.op) {
484    case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
485       get_h264_video_session_mem_reqs(vid,
486                                       mem_reqs,
487                                       pVideoSessionMemoryRequirementsCount,
488                                       memory_types);
489       break;
490    case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
491       get_h265_video_session_mem_reqs(vid,
492                                       mem_reqs,
493                                       pVideoSessionMemoryRequirementsCount,
494                                       memory_types);
495       break;
496    case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
497       get_h264_video_session_mem_reqs(vid,
498                                       mem_reqs,
499                                       pVideoSessionMemoryRequirementsCount,
500                                       memory_types);
501       break;
502    case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
503       get_h265_video_session_mem_reqs(vid,
504                                       mem_reqs,
505                                       pVideoSessionMemoryRequirementsCount,
506                                       memory_types);
507       break;
508    default:
509       unreachable("unknown codec");
510    }
511 
512    return VK_SUCCESS;
513 }
514 
515 VkResult
anv_UpdateVideoSessionParametersKHR(VkDevice _device,VkVideoSessionParametersKHR _params,const VkVideoSessionParametersUpdateInfoKHR * pUpdateInfo)516 anv_UpdateVideoSessionParametersKHR(VkDevice _device,
517                                      VkVideoSessionParametersKHR _params,
518                                      const VkVideoSessionParametersUpdateInfoKHR *pUpdateInfo)
519 {
520    ANV_FROM_HANDLE(anv_video_session_params, params, _params);
521    return vk_video_session_parameters_update(&params->vk, pUpdateInfo);
522 }
523 
524 static void
copy_bind(struct anv_vid_mem * dst,const VkBindVideoSessionMemoryInfoKHR * src)525 copy_bind(struct anv_vid_mem *dst,
526           const VkBindVideoSessionMemoryInfoKHR *src)
527 {
528    dst->mem = anv_device_memory_from_handle(src->memory);
529    dst->offset = src->memoryOffset;
530    dst->size = src->memorySize;
531 }
532 
533 VkResult
anv_BindVideoSessionMemoryKHR(VkDevice _device,VkVideoSessionKHR videoSession,uint32_t bind_mem_count,const VkBindVideoSessionMemoryInfoKHR * bind_mem)534 anv_BindVideoSessionMemoryKHR(VkDevice _device,
535                               VkVideoSessionKHR videoSession,
536                               uint32_t bind_mem_count,
537                               const VkBindVideoSessionMemoryInfoKHR *bind_mem)
538 {
539    ANV_FROM_HANDLE(anv_video_session, vid, videoSession);
540 
541    switch (vid->vk.op) {
542    case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
543    case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
544       for (unsigned i = 0; i < bind_mem_count; i++) {
545          copy_bind(&vid->vid_mem[bind_mem[i].memoryBindIndex], &bind_mem[i]);
546       }
547       break;
548    case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
549    case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
550       for (unsigned i = 0; i < bind_mem_count; i++) {
551          copy_bind(&vid->vid_mem[bind_mem[i].memoryBindIndex], &bind_mem[i]);
552       }
553       break;
554    default:
555       unreachable("unknown codec");
556    }
557    return VK_SUCCESS;
558 }
559 
560 VKAPI_ATTR VkResult VKAPI_CALL
anv_GetEncodedVideoSessionParametersKHR(VkDevice device,const VkVideoEncodeSessionParametersGetInfoKHR * pVideoSessionParametersInfo,VkVideoEncodeSessionParametersFeedbackInfoKHR * pFeedbackInfo,size_t * pDataSize,void * pData)561 anv_GetEncodedVideoSessionParametersKHR(VkDevice device,
562                                         const VkVideoEncodeSessionParametersGetInfoKHR* pVideoSessionParametersInfo,
563                                         VkVideoEncodeSessionParametersFeedbackInfoKHR* pFeedbackInfo,
564                                         size_t *pDataSize,
565                                         void *pData)
566 {
567    ANV_FROM_HANDLE(anv_video_session_params, params, pVideoSessionParametersInfo->videoSessionParameters);
568    size_t total_size = 0;
569    size_t size_limit = 0;
570 
571    if (pData)
572       size_limit = *pDataSize;
573 
574    switch (params->vk.op) {
575    case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR: {
576       const struct VkVideoEncodeH264SessionParametersGetInfoKHR *h264_get_info =
577          vk_find_struct_const(pVideoSessionParametersInfo->pNext, VIDEO_ENCODE_H264_SESSION_PARAMETERS_GET_INFO_KHR);
578       size_t sps_size = 0, pps_size = 0;
579       if (h264_get_info->writeStdSPS) {
580          for (unsigned i = 0; i < params->vk.h264_enc.h264_sps_count; i++)
581             if (params->vk.h264_enc.h264_sps[i].base.seq_parameter_set_id == h264_get_info->stdSPSId)
582                vk_video_encode_h264_sps(&params->vk.h264_enc.h264_sps[i].base, size_limit, &sps_size, pData);
583       }
584       if (h264_get_info->writeStdPPS) {
585          char *data_ptr = pData ? (char *)pData + sps_size : NULL;
586          for (unsigned i = 0; i < params->vk.h264_enc.h264_pps_count; i++)
587             if (params->vk.h264_enc.h264_pps[i].base.pic_parameter_set_id == h264_get_info->stdPPSId) {
588                vk_video_encode_h264_pps(&params->vk.h264_enc.h264_pps[i].base, false, size_limit, &pps_size, data_ptr);
589             }
590       }
591       total_size = sps_size + pps_size;
592       break;
593    }
594    case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR: {
595       const struct VkVideoEncodeH265SessionParametersGetInfoKHR *h265_get_info =
596          vk_find_struct_const(pVideoSessionParametersInfo->pNext, VIDEO_ENCODE_H265_SESSION_PARAMETERS_GET_INFO_KHR);
597       size_t sps_size = 0, pps_size = 0, vps_size = 0;
598       if (h265_get_info->writeStdVPS) {
599          for (unsigned i = 0; i < params->vk.h265_enc.h265_vps_count; i++)
600             if (params->vk.h265_enc.h265_vps[i].base.vps_video_parameter_set_id == h265_get_info->stdVPSId)
601                vk_video_encode_h265_vps(&params->vk.h265_enc.h265_vps[i].base, size_limit, &vps_size, pData);
602       }
603       if (h265_get_info->writeStdSPS) {
604          char *data_ptr = pData ? (char *)pData + vps_size : NULL;
605          for (unsigned i = 0; i < params->vk.h265_enc.h265_sps_count; i++)
606             if (params->vk.h265_enc.h265_sps[i].base.sps_seq_parameter_set_id == h265_get_info->stdSPSId) {
607                vk_video_encode_h265_sps(&params->vk.h265_enc.h265_sps[i].base, size_limit, &sps_size, data_ptr);
608             }
609       }
610       if (h265_get_info->writeStdPPS) {
611          char *data_ptr = pData ? (char *)pData + vps_size + sps_size : NULL;
612          for (unsigned i = 0; i < params->vk.h265_enc.h265_pps_count; i++)
613             if (params->vk.h265_enc.h265_pps[i].base.pps_seq_parameter_set_id == h265_get_info->stdPPSId) {
614                params->vk.h265_enc.h265_pps[i].base.flags.cu_qp_delta_enabled_flag = 0;
615                vk_video_encode_h265_pps(&params->vk.h265_enc.h265_pps[i].base, size_limit, &pps_size, data_ptr);
616             }
617       }
618       total_size = sps_size + pps_size + vps_size;
619       break;
620    }
621    default:
622       break;
623    }
624 
625    /* vk_video_encode_h26x functions support to be safe even if size_limit is not enough,
626     * so we could just confirm whether pDataSize is valid afterwards.
627     */
628    if (pData && *pDataSize < total_size) {
629       *pDataSize = 0;
630       return VK_INCOMPLETE;
631    }
632 
633    *pDataSize = total_size;
634    return VK_SUCCESS;
635 }
636 
637 VkResult
anv_GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR * pQualityLevelInfo,VkVideoEncodeQualityLevelPropertiesKHR * pQualityLevelProperties)638 anv_GetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR(VkPhysicalDevice physicalDevice,
639                                                           const VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR* pQualityLevelInfo,
640                                                           VkVideoEncodeQualityLevelPropertiesKHR* pQualityLevelProperties)
641 {
642    /* TODO. */
643    return VK_SUCCESS;
644 }
645