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 ¶ms->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, ¶ms->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(¶ms->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(¶ms->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(¶ms->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(¶ms->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(¶ms->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(¶ms->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