mirror of
https://github.com/elwrcl/intel-hard-graphics.git
synced 2026-10-31 19:08:03 +03:00
hasvk: add initial video decode support for h264.
This just adds the files with the programming info, it doesn't enable the extensions etc [dancingmirrors: A few forward port fixes.]
This commit is contained in:
1 parent
4d12fc3ec6
commit
1db147a9ce
4 files changed
+678
No files matched your search
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "anv_private.h"
|
||||
|
||||
#include "vk_video/vulkan_video_codecs_common.h"
|
||||
|
||||
VkResult
|
||||
anv_CreateVideoSessionKHR(VkDevice _device,
|
||||
const VkVideoSessionCreateInfoKHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkVideoSessionKHR *pVideoSession)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||
|
||||
struct anv_video_session *vid =
|
||||
vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*vid), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!vid)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
memset(vid, 0, sizeof(struct anv_video_session));
|
||||
|
||||
VkResult result = vk_video_session_init(&device->vk,
|
||||
&vid->vk,
|
||||
pCreateInfo);
|
||||
if (result != VK_SUCCESS) {
|
||||
vk_free2(&device->vk.alloc, pAllocator, vid);
|
||||
return result;
|
||||
}
|
||||
|
||||
*pVideoSession = anv_video_session_to_handle(vid);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
anv_DestroyVideoSessionKHR(VkDevice _device,
|
||||
VkVideoSessionKHR _session,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||
ANV_FROM_HANDLE(anv_video_session, vid, _session);
|
||||
if (!_session)
|
||||
return;
|
||||
|
||||
vk_object_base_finish(&vid->vk.base);
|
||||
vk_free2(&device->vk.alloc, pAllocator, vid);
|
||||
}
|
||||
|
||||
VkResult
|
||||
anv_CreateVideoSessionParametersKHR(VkDevice _device,
|
||||
const
|
||||
VkVideoSessionParametersCreateInfoKHR
|
||||
*pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkVideoSessionParametersKHR
|
||||
*pVideoSessionParameters)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||
|
||||
struct vk_video_session_parameters *params =
|
||||
vk_video_session_parameters_create(&device->vk, pCreateInfo, pAllocator,
|
||||
sizeof(struct
|
||||
anv_video_session_params));
|
||||
if (!params)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
*pVideoSessionParameters = vk_video_session_parameters_to_handle(params);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
anv_DestroyVideoSessionParametersKHR(VkDevice _device,
|
||||
VkVideoSessionParametersKHR _params,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||
VK_FROM_HANDLE(vk_video_session_parameters, params, _params);
|
||||
|
||||
vk_video_session_parameters_destroy(&device->vk, pAllocator, params);
|
||||
}
|
||||
|
||||
VkResult
|
||||
anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice,
|
||||
const VkVideoProfileInfoKHR *pVideoProfile,
|
||||
VkVideoCapabilitiesKHR *pCapabilities)
|
||||
{
|
||||
pCapabilities->minBitstreamBufferOffsetAlignment = 32;
|
||||
pCapabilities->minBitstreamBufferSizeAlignment = 32;
|
||||
pCapabilities->pictureAccessGranularity.width = ANV_MB_WIDTH;
|
||||
pCapabilities->pictureAccessGranularity.height = ANV_MB_HEIGHT;
|
||||
pCapabilities->minCodedExtent.width = ANV_MB_WIDTH;
|
||||
pCapabilities->minCodedExtent.height = ANV_MB_HEIGHT;
|
||||
pCapabilities->maxCodedExtent.width = 4096;
|
||||
pCapabilities->maxCodedExtent.height = 4096;
|
||||
pCapabilities->flags = VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
|
||||
|
||||
struct VkVideoDecodeCapabilitiesKHR *dec_caps = (struct VkVideoDecodeCapabilitiesKHR *)
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_CAPABILITIES_KHR);
|
||||
if (dec_caps)
|
||||
dec_caps->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR;
|
||||
|
||||
switch (pVideoProfile->videoCodecOperation) {
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: {
|
||||
struct VkVideoDecodeH264CapabilitiesKHR *ext = (struct VkVideoDecodeH264CapabilitiesKHR *)
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_H264_CAPABILITIES_KHR);
|
||||
pCapabilities->maxDpbSlots = 17;
|
||||
pCapabilities->maxActiveReferencePictures = 16;
|
||||
|
||||
ext->fieldOffsetGranularity.x = 0;
|
||||
ext->fieldOffsetGranularity.y = 0;
|
||||
ext->maxLevelIdc = 51;
|
||||
strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME);
|
||||
pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
anv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
|
||||
const VkPhysicalDeviceVideoFormatInfoKHR *pVideoFormatInfo,
|
||||
uint32_t *pVideoFormatPropertyCount,
|
||||
VkVideoFormatPropertiesKHR *pVideoFormatProperties)
|
||||
{
|
||||
*pVideoFormatPropertyCount = 1;
|
||||
|
||||
if (!pVideoFormatProperties)
|
||||
return VK_SUCCESS;
|
||||
|
||||
pVideoFormatProperties[0].format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
|
||||
pVideoFormatProperties[0].imageType = VK_IMAGE_TYPE_2D;
|
||||
pVideoFormatProperties[0].imageTiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
pVideoFormatProperties[0].imageUsageFlags = pVideoFormatInfo->imageUsage;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
get_h264_video_session_mem_reqs(struct anv_video_session *vid,
|
||||
VkVideoSessionMemoryRequirementsKHR *mem_reqs,
|
||||
uint32_t memory_types)
|
||||
{
|
||||
uint32_t width_in_mb = align(vid->vk.max_coded.width, ANV_MB_WIDTH) / ANV_MB_WIDTH;
|
||||
/* intra row store is width in macroblocks * 64 */
|
||||
mem_reqs[0].memoryBindIndex = ANV_VID_MEM_H264_INTRA_ROW_STORE;
|
||||
mem_reqs[0].memoryRequirements.size = width_in_mb * 64;
|
||||
mem_reqs[0].memoryRequirements.alignment = 4096;
|
||||
mem_reqs[0].memoryRequirements.memoryTypeBits = memory_types;
|
||||
|
||||
/* deblocking filter row store is width in macroblocks * 64 * 4*/
|
||||
mem_reqs[1].memoryBindIndex = ANV_VID_MEM_H264_DEBLOCK_FILTER_ROW_STORE;
|
||||
mem_reqs[1].memoryRequirements.size = width_in_mb * 64 * 4;
|
||||
mem_reqs[1].memoryRequirements.alignment = 4096;
|
||||
mem_reqs[1].memoryRequirements.memoryTypeBits = memory_types;
|
||||
|
||||
/* bsd mpc row scratch is width in macroblocks * 64 * 2 */
|
||||
mem_reqs[2].memoryBindIndex = ANV_VID_MEM_H264_BSD_MPC_ROW_SCRATCH;
|
||||
mem_reqs[2].memoryRequirements.size = width_in_mb * 64 * 2;
|
||||
mem_reqs[2].memoryRequirements.alignment = 4096;
|
||||
mem_reqs[2].memoryRequirements.memoryTypeBits = memory_types;
|
||||
|
||||
/* mpr row scratch is width in macroblocks * 64 * 2 */
|
||||
mem_reqs[3].memoryBindIndex = ANV_VID_MEM_H264_MPR_ROW_SCRATCH;
|
||||
mem_reqs[3].memoryRequirements.size = width_in_mb * 64 * 2;
|
||||
mem_reqs[3].memoryRequirements.alignment = 4096;
|
||||
mem_reqs[3].memoryRequirements.memoryTypeBits = memory_types;
|
||||
}
|
||||
|
||||
VkResult
|
||||
anv_GetVideoSessionMemoryRequirementsKHR(VkDevice _device,
|
||||
VkVideoSessionKHR videoSession,
|
||||
uint32_t *pVideoSessionMemoryRequirementsCount,
|
||||
VkVideoSessionMemoryRequirementsKHR *mem_reqs)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||
ANV_FROM_HANDLE(anv_video_session, vid, videoSession);
|
||||
|
||||
switch (vid->vk.op) {
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
|
||||
*pVideoSessionMemoryRequirementsCount = ANV_VIDEO_MEM_REQS_H264;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("unknown codec");
|
||||
}
|
||||
if (!mem_reqs)
|
||||
return VK_SUCCESS;
|
||||
|
||||
uint32_t memory_types = (1ull << device->physical->memory.type_count) - 1;
|
||||
switch (vid->vk.op) {
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
|
||||
get_h264_video_session_mem_reqs(vid, mem_reqs, memory_types);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("unknown codec");
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
anv_UpdateVideoSessionParametersKHR(VkDevice _device,
|
||||
VkVideoSessionParametersKHR _params,
|
||||
const VkVideoSessionParametersUpdateInfoKHR *pUpdateInfo)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_video_session_params, params, _params);
|
||||
return vk_video_session_parameters_update(¶ms->vk, pUpdateInfo);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_bind(struct anv_vid_mem *dst,
|
||||
const VkBindVideoSessionMemoryInfoKHR *src)
|
||||
{
|
||||
dst->mem = anv_device_memory_from_handle(src->memory);
|
||||
dst->offset = src->memoryOffset;
|
||||
dst->size = src->memorySize;
|
||||
}
|
||||
|
||||
VkResult
|
||||
anv_BindVideoSessionMemoryKHR(VkDevice _device,
|
||||
VkVideoSessionKHR videoSession,
|
||||
uint32_t bind_mem_count,
|
||||
const VkBindVideoSessionMemoryInfoKHR *bind_mem)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_video_session, vid, videoSession);
|
||||
|
||||
assert(bind_mem_count == 4);
|
||||
switch (vid->vk.op) {
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
|
||||
for (unsigned i = 0; i < bind_mem_count; i++) {
|
||||
copy_bind(&vid->vid_mem[bind_mem[i].memoryBindIndex], &bind_mem[i]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("unknown codec");
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
Reference in new issue
Block a user