radv/video: add initial frameworking.

This just adds the basic commands and objects, and hooks up some
of the queues and extensions.

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20388>
This commit is contained in:
Dave Airlie 2022-03-14 11:11:26 +10:00
parent 3253340916
commit 9477f117f4
4 changed files with 246 additions and 0 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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,
&params->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, &params->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(&params->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)
{
}