mesa/src/intel/vulkan/anv_video.c
Dave Airlie 53283bc26d anv/video: fix video memory bindings.
A break snuck in here.

Fixes: 98c58a16ef ("anv: add initial video decode support for h264.")
Acked-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21184>
2023-02-08 06:42:09 +00:00

267 lines
10 KiB
C

/*
* 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);
ANV_FROM_HANDLE(anv_video_session, vid, pCreateInfo->videoSession);
ANV_FROM_HANDLE(anv_video_session_params, templ, pCreateInfo->videoSessionParametersTemplate);
struct anv_video_session_params *params =
vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*params), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!params)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result = vk_video_session_parameters_init(&device->vk,
&params->vk,
&vid->vk,
templ ? &templ->vk : NULL,
pCreateInfo);
if (result != VK_SUCCESS) {
vk_free2(&device->vk.alloc, pAllocator, params);
return result;
}
*pVideoSessionParameters = anv_video_session_params_to_handle(params);
return VK_SUCCESS;
}
void
anv_DestroyVideoSessionParametersKHR(VkDevice _device,
VkVideoSessionParametersKHR _params,
const VkAllocationCallbacks *pAllocator)
{
ANV_FROM_HANDLE(anv_device, device, _device);
ANV_FROM_HANDLE(anv_video_session_params, params, _params);
if (!_params)
return;
vk_video_session_parameters_finish(&device->vk, &params->vk);
vk_free2(&device->vk.alloc, 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(&params->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;
default:
unreachable("unknown codec");
}
return VK_SUCCESS;
}