diff --git a/src/amd/vulkan/radv_debug.h b/src/amd/vulkan/radv_debug.h index 3c5c1a209ca..bd0e53c4a2d 100644 --- a/src/amd/vulkan/radv_debug.h +++ b/src/amd/vulkan/radv_debug.h @@ -86,6 +86,7 @@ enum { RADV_PERFTEST_RT_WAVE_64 = 1u << 12, RADV_PERFTEST_GPL = 1u << 13, RADV_PERFTEST_NGG_STREAMOUT = 1u << 14, + RADV_PERFTEST_VIDEO_DECODE = 1u << 15, }; bool radv_init_trace(struct radv_device *device); diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 56649b55622..3fdf14fe3b4 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -574,6 +574,8 @@ radv_physical_device_get_supported_extensions(const struct radv_physical_device .KHR_timeline_semaphore = true, .KHR_uniform_buffer_standard_layout = true, .KHR_variable_pointers = true, + .KHR_video_queue = !!(device->instance->perftest_flags & RADV_PERFTEST_VIDEO_DECODE), + .KHR_video_decode_queue = !!(device->instance->perftest_flags & RADV_PERFTEST_VIDEO_DECODE), .KHR_vulkan_memory_model = true, .KHR_workgroup_memory_explicit_layout = true, .KHR_zero_initialize_workgroup_memory = true, @@ -718,6 +720,18 @@ radv_physical_device_init_queue_table(struct radv_physical_device *pdevice) pdevice->vk_queue_to_radv[idx] = RADV_QUEUE_COMPUTE; idx++; } + + if (pdevice->instance->perftest_flags & RADV_PERFTEST_VIDEO_DECODE) { + if (pdevice->rad_info.ip[AMD_IP_VCN_DEC].num_queues > 0) { + pdevice->vk_queue_to_radv[idx] = RADV_QUEUE_VIDEO_DEC; + idx++; + } + + if (radv_has_uvd(pdevice)) { + pdevice->vk_queue_to_radv[idx] = RADV_QUEUE_VIDEO_DEC; + idx++; + } + } pdevice->num_queues = idx; } @@ -1113,6 +1127,7 @@ static const struct debug_control radv_perftest_options[] = {{"localbos", RADV_P {"rtwave64", RADV_PERFTEST_RT_WAVE_64}, {"gpl", RADV_PERFTEST_GPL}, {"ngg_streamout", RADV_PERFTEST_NGG_STREAMOUT}, + {"video_decode", RADV_PERFTEST_VIDEO_DECODE}, {NULL, 0}}; const char * @@ -2840,6 +2855,14 @@ radv_get_physical_device_queue_family_properties(struct radv_physical_device *pd !(pdevice->instance->debug_flags & RADV_DEBUG_NO_COMPUTE_QUEUE)) num_queue_families++; + if (pdevice->instance->perftest_flags & RADV_PERFTEST_VIDEO_DECODE) { + if (pdevice->rad_info.ip[AMD_IP_VCN_DEC].num_queues > 0) + num_queue_families++; + + if (radv_has_uvd(pdevice)) + num_queue_families++; + } + if (pQueueFamilyProperties == NULL) { *pCount = num_queue_families; return; @@ -2873,6 +2896,33 @@ radv_get_physical_device_queue_family_properties(struct radv_physical_device *pd idx++; } } + + if (pdevice->instance->perftest_flags & RADV_PERFTEST_VIDEO_DECODE) { + if (pdevice->rad_info.ip[AMD_IP_VCN_DEC].num_queues > 0) { + if (*pCount > idx) { + *pQueueFamilyProperties[idx] = (VkQueueFamilyProperties){ + .queueFlags = VK_QUEUE_VIDEO_DECODE_BIT_KHR, + .queueCount = pdevice->rad_info.ip[AMD_IP_VCN_DEC].num_queues, + .timestampValidBits = 64, + .minImageTransferGranularity = (VkExtent3D){1, 1, 1}, + }; + idx++; + } + } + + if (radv_has_uvd(pdevice)) { + if (*pCount > idx) { + *pQueueFamilyProperties[idx] = (VkQueueFamilyProperties){ + .queueFlags = VK_QUEUE_VIDEO_DECODE_BIT_KHR, + .queueCount = pdevice->rad_info.ip[AMD_IP_UVD].num_queues, + .timestampValidBits = 64, + .minImageTransferGranularity = (VkExtent3D){1, 1, 1}, + }; + idx++; + } + } + } + *pCount = idx; } @@ -2918,6 +2968,13 @@ radv_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, ui prop->queryResultStatusSupport = VK_FALSE; break; } + case VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR: { + VkQueueFamilyVideoPropertiesKHR *prop = + (VkQueueFamilyVideoPropertiesKHR *)ext; + if (pQueueFamilyProperties[i].queueFamilyProperties.queueFlags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) + prop->videoCodecOperations = VK_VIDEO_CODEC_OPERATION_NONE_KHR; + break; + } default: break; } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 4e9d5a8eb06..db2257c6578 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -68,6 +68,7 @@ #include "vk_util.h" #include "vk_image.h" #include "vk_ycbcr_conversion.h" +#include "vk_video.h" #include "rmv/vk_rmv_common.h" #include "rmv/vk_rmv_tokens.h" @@ -1704,6 +1705,11 @@ struct radv_cmd_buffer { * Bitmask of pending active query flushes. */ enum radv_cmd_flush_bits active_query_flush_bits; + + struct { + struct radv_video_session *vid; + struct radv_video_session_params *params; + } video; }; extern const struct vk_command_buffer_ops radv_cmd_buffer_ops; @@ -2834,6 +2840,31 @@ void radv_pc_end_query(struct radv_cmd_buffer *cmd_buffer, struct radv_pc_query_ uint64_t va); void radv_pc_get_results(const struct radv_pc_query_pool *pc_pool, const uint64_t *data, void *out); +struct radv_vid_mem { + struct radv_device_memory *mem; + VkDeviceSize offset; + VkDeviceSize size; +}; + +struct radv_video_session { + struct vk_video_session vk; +}; + +struct radv_video_session_params { + struct vk_video_session_parameters vk; +}; + +/* needed for ac_gpu_info codecs */ +#define RADV_VIDEO_FORMAT_UNKNOWN 0 +#define RADV_VIDEO_FORMAT_MPEG12 1 /**< MPEG1, MPEG2 */ +#define RADV_VIDEO_FORMAT_MPEG4 2 /**< DIVX, XVID */ +#define RADV_VIDEO_FORMAT_VC1 3 /**< WMV */ +#define RADV_VIDEO_FORMAT_MPEG4_AVC 4/**< H.264 */ +#define RADV_VIDEO_FORMAT_HEVC 5 /**< H.265 */ +#define RADV_VIDEO_FORMAT_JPEG 6 /**< JPEG */ +#define RADV_VIDEO_FORMAT_VP9 7 /**< VP9 */ +#define RADV_VIDEO_FORMAT_AV1 8 /**< AV1 */ + bool radv_queue_internal_submit(struct radv_queue *queue, struct radeon_cmdbuf *cs); int radv_queue_init(struct radv_device *device, struct radv_queue *queue, int idx, @@ -3523,6 +3554,9 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(radv_query_pool, base, VkQueryPool, VK_DEFINE_NONDISP_HANDLE_CASTS(radv_sampler, base, VkSampler, VK_OBJECT_TYPE_SAMPLER) +VK_DEFINE_NONDISP_HANDLE_CASTS(radv_video_session, vk.base, VkVideoSessionKHR, VK_OBJECT_TYPE_VIDEO_SESSION_KHR) +VK_DEFINE_NONDISP_HANDLE_CASTS(radv_video_session_params, vk.base, VkVideoSessionParametersKHR, VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR) + #ifdef __cplusplus } #endif diff --git a/src/amd/vulkan/radv_video.c b/src/amd/vulkan/radv_video.c index 16dc3f5745c..84e2c21d2c6 100644 --- a/src/amd/vulkan/radv_video.c +++ b/src/amd/vulkan/radv_video.c @@ -81,3 +81,157 @@ radv_init_physical_device_decoder(struct radv_physical_device *pdevice) break; } } + +VkResult +radv_CreateVideoSessionKHR(VkDevice _device, + const VkVideoSessionCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkVideoSessionKHR *pVideoSession) +{ + RADV_FROM_HANDLE(radv_device, device, _device); + + struct radv_video_session *vid = + vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*vid), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!vid) + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + memset(vid, 0, sizeof(struct radv_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 = radv_video_session_to_handle(vid); + return VK_SUCCESS; +} + +void +radv_DestroyVideoSessionKHR(VkDevice _device, + VkVideoSessionKHR _session, + const VkAllocationCallbacks *pAllocator) +{ + RADV_FROM_HANDLE(radv_device, device, _device); + RADV_FROM_HANDLE(radv_video_session, vid, _session); + if (!_session) + return; + + vk_object_base_finish(&vid->vk.base); + vk_free2(&device->vk.alloc, pAllocator, vid); +} + + +VkResult +radv_CreateVideoSessionParametersKHR(VkDevice _device, + const VkVideoSessionParametersCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkVideoSessionParametersKHR *pVideoSessionParameters) +{ + RADV_FROM_HANDLE(radv_device, device, _device); + RADV_FROM_HANDLE(radv_video_session, vid, pCreateInfo->videoSession); + RADV_FROM_HANDLE(radv_video_session_params, templ, pCreateInfo->videoSessionParametersTemplate); + struct radv_video_session_params *params = + vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*params), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!params) + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + VkResult result = vk_video_session_parameters_init(&device->vk, + ¶ms->vk, + &vid->vk, + templ ? &templ->vk : NULL, + pCreateInfo); + if (result != VK_SUCCESS) { + vk_free2(&device->vk.alloc, pAllocator, params); + return result; + } + + *pVideoSessionParameters = radv_video_session_params_to_handle(params); + return VK_SUCCESS; +} + +void +radv_DestroyVideoSessionParametersKHR(VkDevice _device, + VkVideoSessionParametersKHR _params, + const VkAllocationCallbacks *pAllocator) +{ + RADV_FROM_HANDLE(radv_device, device, _device); + RADV_FROM_HANDLE(radv_video_session_params, params, _params); + + vk_video_session_parameters_finish(&device->vk, ¶ms->vk); + vk_free2(&device->vk.alloc, pAllocator, params); +} + +VkResult +radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, + const VkVideoProfileInfoKHR *pVideoProfile, + VkVideoCapabilitiesKHR *pCapabilities) +{ + RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice); + + pCapabilities->flags = 0; + return VK_SUCCESS; +} + +VkResult +radv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceVideoFormatInfoKHR *pVideoFormatInfo, + uint32_t *pVideoFormatPropertyCount, + VkVideoFormatPropertiesKHR *pVideoFormatProperties) +{ + return VK_SUCCESS; +} + +VkResult +radv_GetVideoSessionMemoryRequirementsKHR(VkDevice _device, + VkVideoSessionKHR videoSession, + uint32_t *pMemoryRequirementsCount, + VkVideoSessionMemoryRequirementsKHR *pMemoryRequirements) +{ + return VK_SUCCESS; +} + +VkResult +radv_UpdateVideoSessionParametersKHR(VkDevice _device, + VkVideoSessionParametersKHR videoSessionParameters, + const VkVideoSessionParametersUpdateInfoKHR *pUpdateInfo) +{ + RADV_FROM_HANDLE(radv_video_session_params, params, videoSessionParameters); + + return vk_video_session_parameters_update(¶ms->vk, pUpdateInfo); +} + +VkResult +radv_BindVideoSessionMemoryKHR(VkDevice _device, + VkVideoSessionKHR videoSession, + uint32_t videoSessionBindMemoryCount, + const VkBindVideoSessionMemoryInfoKHR *pBindSessionMemoryInfos) +{ + return VK_SUCCESS; +} + +void +radv_CmdBeginVideoCodingKHR(VkCommandBuffer commandBuffer, + const VkVideoBeginCodingInfoKHR *pBeginInfo) +{ +} + +void +radv_CmdControlVideoCodingKHR(VkCommandBuffer commandBuffer, + const VkVideoCodingControlInfoKHR *pCodingControlInfo) +{ +} + +void +radv_CmdEndVideoCodingKHR(VkCommandBuffer commandBuffer, + const VkVideoEndCodingInfoKHR *pEndCodingInfo) +{ +} + +void +radv_CmdDecodeVideoKHR(VkCommandBuffer commandBuffer, + const VkVideoDecodeInfoKHR *frame_info) +{ +}