diff --git a/docs/features.txt b/docs/features.txt index 07a981c1ea4..080f8768e11 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -526,7 +526,7 @@ Khronos extensions that are not part of any Vulkan version: VK_KHR_fragment_shading_rate DONE (anv/gen11+, nvk/Turing+, radv/gfx10.3+, vn) VK_KHR_get_display_properties2 DONE (anv, nvk, pvr, radv, tu, v3dv) VK_KHR_get_surface_capabilities2 DONE (anv, lvp, nvk, pvr, radv, tu, v3dv, vn) - VK_KHR_global_priority DONE (anv, radv, tu) + VK_KHR_global_priority DONE (anv, panvk, radv, tu) VK_KHR_incremental_present DONE (anv, hasvk, lvp, nvk, radv, tu, v3dv, vn) VK_KHR_index_type_uint8 DONE (anv, nvk, pvr, radv, tu, v3dv) VK_KHR_line_rasterization DONE (anv, nvk, radv, tu, v3dv) @@ -598,8 +598,8 @@ Khronos extensions that are not part of any Vulkan version: VK_EXT_filter_cubic DONE (tu/a650+) VK_EXT_fragment_density_map DONE (tu) VK_EXT_fragment_shader_interlock DONE (anv, radv/gfx9+, vn) - VK_EXT_global_priority DONE (anv, hasvk, radv, tu) - VK_EXT_global_priority_query DONE (anv, hasvk, radv, tu) + VK_EXT_global_priority DONE (anv, hasvk, panvk, radv, tu) + VK_EXT_global_priority_query DONE (anv, hasvk, panvk, radv, tu) VK_EXT_graphics_pipeline_library DONE (anv, lvp, nvk, panvk, radv, tu, vn) VK_EXT_headless_surface DONE (anv, dzn, hasvk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn) VK_EXT_host_image_copy DONE (nvk/Turing+) diff --git a/src/panfrost/ci/panfrost-g52-fails.txt b/src/panfrost/ci/panfrost-g52-fails.txt index 25c3c358347..41f5e272e29 100644 --- a/src/panfrost/ci/panfrost-g52-fails.txt +++ b/src/panfrost/ci/panfrost-g52-fails.txt @@ -2665,6 +2665,12 @@ dEQP-VK.texture.filtering.3d.formats.d32_sfloat_s8_uint_stencil.d32_sfloat_s8_ui dEQP-VK.api.device_init.create_device_unsupported_features.shader_draw_parameters_features,Fail dEQP-VK.api.device_init.create_device_unsupported_features.protected_memory_features,Fail +# CTS bug, works fine if Vulkan 1.1 is forced +dEQP-VK.api.device_init.create_device_global_priority.basic,Fail +dEQP-VK.api.device_init.create_device_global_priority_khr.basic,Fail +dEQP-VK.api.device_init.create_device_global_priority_query.basic,Fail +dEQP-VK.api.device_init.create_device_global_priority_query_khr.basic,Fail + # CmdDrawIndirect not supported yet dEQP-VK.api.command_buffers.many_indirect_draws_on_secondary,Crash diff --git a/src/panfrost/vulkan/csf/panvk_vX_queue.c b/src/panfrost/vulkan/csf/panvk_vX_queue.c index a091cbd8f7f..9fda798327b 100644 --- a/src/panfrost/vulkan/csf/panvk_vX_queue.c +++ b/src/panfrost/vulkan/csf/panvk_vX_queue.c @@ -361,7 +361,8 @@ err_cleanup_queue: } static VkResult -create_group(struct panvk_queue *queue) +create_group(struct panvk_queue *queue, + enum drm_panthor_group_priority group_priority) { const struct panvk_device *dev = to_panvk_device(queue->vk.base.device); const struct panvk_physical_device *phys_dev = @@ -393,7 +394,7 @@ create_group(struct panvk_queue *queue) .max_fragment_cores = util_bitcount64(phys_dev->kmod.props.shader_present), .max_tiler_cores = 1, - .priority = PANTHOR_GROUP_PRIORITY_MEDIUM, + .priority = group_priority, .queues = DRM_PANTHOR_OBJ_ARRAY(ARRAY_SIZE(qc), qc), .vm_id = pan_kmod_vm_handle(dev->kmod.vm), }; @@ -699,6 +700,30 @@ out: return result; } +static enum drm_panthor_group_priority +get_panthor_group_priority(const VkDeviceQueueCreateInfo *create_info) +{ + const VkDeviceQueueGlobalPriorityCreateInfoKHR *priority_info = + vk_find_struct_const(create_info->pNext, + DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR); + const enum VkQueueGlobalPriorityKHR priority = + priority_info ? priority_info->globalPriority + : VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR; + + switch (priority) { + case VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR: + return PANTHOR_GROUP_PRIORITY_LOW; + case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR: + return PANTHOR_GROUP_PRIORITY_MEDIUM; + case VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR: + return PANTHOR_GROUP_PRIORITY_HIGH; + case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR: + return PANTHOR_GROUP_PRIORITY_REALTIME; + default: + unreachable("Invalid global priority"); + } +} + VkResult panvk_per_arch(queue_init)(struct panvk_device *dev, struct panvk_queue *queue, int idx, const VkDeviceQueueCreateInfo *create_info) @@ -718,7 +743,7 @@ panvk_per_arch(queue_init)(struct panvk_device *dev, struct panvk_queue *queue, if (result != VK_SUCCESS) goto err_destroy_syncobj; - result = create_group(queue); + result = create_group(queue, get_panthor_group_priority(create_info)); if (result != VK_SUCCESS) goto err_cleanup_tiler; diff --git a/src/panfrost/vulkan/jm/panvk_vX_queue.c b/src/panfrost/vulkan/jm/panvk_vX_queue.c index 8b59eb4c831..f9b924ac52e 100644 --- a/src/panfrost/vulkan/jm/panvk_vX_queue.c +++ b/src/panfrost/vulkan/jm/panvk_vX_queue.c @@ -310,6 +310,16 @@ panvk_per_arch(queue_init)(struct panvk_device *device, struct panvk_queue *queue, int idx, const VkDeviceQueueCreateInfo *create_info) { + ASSERTED const VkDeviceQueueGlobalPriorityCreateInfoKHR *priority_info = + vk_find_struct_const(create_info->pNext, + DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR); + ASSERTED const enum VkQueueGlobalPriorityKHR priority = + priority_info ? priority_info->globalPriority + : VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR; + + /* XXX: Panfrost kernel module doesn't support priorities so far */ + assert(priority == VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR); + VkResult result = vk_queue_init(&queue->vk, &device->vk, create_info, idx); if (result != VK_SUCCESS) return result; diff --git a/src/panfrost/vulkan/panvk_physical_device.c b/src/panfrost/vulkan/panvk_physical_device.c index 0d8413c16e3..45e230a35dc 100644 --- a/src/panfrost/vulkan/panvk_physical_device.c +++ b/src/panfrost/vulkan/panvk_physical_device.c @@ -201,6 +201,7 @@ get_device_extensions(const struct panvk_physical_device *device, .KHR_external_semaphore = true, .KHR_external_semaphore_fd = true, .KHR_get_memory_requirements2 = true, + .KHR_global_priority = true, .KHR_image_format_list = true, .KHR_maintenance1 = true, .KHR_maintenance2 = true, @@ -222,6 +223,8 @@ get_device_extensions(const struct panvk_physical_device *device, .EXT_custom_border_color = true, .EXT_depth_clip_enable = true, .EXT_external_memory_dma_buf = true, + .EXT_global_priority = true, + .EXT_global_priority_query = true, .EXT_graphics_pipeline_library = true, .EXT_image_drm_format_modifier = true, .EXT_index_type_uint8 = true, @@ -344,6 +347,9 @@ get_features(const struct panvk_physical_device *device, /* VK_EXT_graphics_pipeline_library */ .graphicsPipelineLibrary = true, + /* VK_KHR_global_priority */ + .globalPriorityQuery = true, + /* VK_EXT_index_type_uint8 */ .indexTypeUint8 = true, @@ -895,17 +901,46 @@ static const VkQueueFamilyProperties panvk_queue_family_properties = { .minImageTransferGranularity = {1, 1, 1}, }; +static void +panvk_fill_global_priority(const struct panvk_physical_device *physical_device, + VkQueueFamilyGlobalPriorityPropertiesKHR *prio) +{ + enum pan_kmod_group_allow_priority_flags prio_mask = + physical_device->kmod.props.allowed_group_priorities_mask; + uint32_t prio_idx = 0; + + if (prio_mask & PAN_KMOD_GROUP_ALLOW_PRIORITY_LOW) + prio->priorities[prio_idx++] = VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR; + + if (prio_mask & PAN_KMOD_GROUP_ALLOW_PRIORITY_MEDIUM) + prio->priorities[prio_idx++] = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR; + + if (prio_mask & PAN_KMOD_GROUP_ALLOW_PRIORITY_HIGH) + prio->priorities[prio_idx++] = VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR; + + if (prio_mask & PAN_KMOD_GROUP_ALLOW_PRIORITY_REALTIME) + prio->priorities[prio_idx++] = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR; + + prio->priorityCount = prio_idx; +} + VKAPI_ATTR void VKAPI_CALL panvk_GetPhysicalDeviceQueueFamilyProperties2( VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2 *pQueueFamilyProperties) { + VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice); VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties2, out, pQueueFamilyProperties, pQueueFamilyPropertyCount); vk_outarray_append_typed(VkQueueFamilyProperties2, &out, p) { p->queueFamilyProperties = panvk_queue_family_properties; + + VkQueueFamilyGlobalPriorityPropertiesKHR *prio = + vk_find_struct(p->pNext, QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR); + if (prio) + panvk_fill_global_priority(physical_device, prio); } } diff --git a/src/panfrost/vulkan/panvk_vX_device.c b/src/panfrost/vulkan/panvk_vX_device.c index 97398a2302d..e756d6212ad 100644 --- a/src/panfrost/vulkan/panvk_vX_device.c +++ b/src/panfrost/vulkan/panvk_vX_device.c @@ -153,6 +153,46 @@ panvk_meta_cleanup(struct panvk_device *device) /* Always reserve the lower 32MB. */ #define PANVK_VA_RESERVE_BOTTOM 0x2000000ull +static enum pan_kmod_group_allow_priority_flags +global_priority_to_group_allow_priority_flag( + enum VkQueueGlobalPriorityKHR priority) +{ + switch (priority) { + case VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR: + return PAN_KMOD_GROUP_ALLOW_PRIORITY_LOW; + case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR: + return PAN_KMOD_GROUP_ALLOW_PRIORITY_MEDIUM; + case VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR: + return PAN_KMOD_GROUP_ALLOW_PRIORITY_HIGH; + case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR: + return PAN_KMOD_GROUP_ALLOW_PRIORITY_REALTIME; + default: + unreachable("Invalid global priority"); + } +} + +static VkResult +check_global_priority(const struct panvk_physical_device *phys_dev, + const VkDeviceQueueCreateInfo *create_info) +{ + const VkDeviceQueueGlobalPriorityCreateInfoKHR *priority_info = + vk_find_struct_const(create_info->pNext, + DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR); + const enum VkQueueGlobalPriorityKHR priority = + priority_info ? priority_info->globalPriority + : VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR; + + enum pan_kmod_group_allow_priority_flags requested_prio = + global_priority_to_group_allow_priority_flag(priority); + enum pan_kmod_group_allow_priority_flags allowed_prio_mask = + phys_dev->kmod.props.allowed_group_priorities_mask; + + if (requested_prio & allowed_prio_mask) + return VK_SUCCESS; + + return VK_ERROR_NOT_PERMITTED_KHR; +} + VkResult panvk_per_arch(create_device)(struct panvk_physical_device *physical_device, const VkDeviceCreateInfo *pCreateInfo, @@ -280,6 +320,11 @@ panvk_per_arch(create_device)(struct panvk_physical_device *physical_device, for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { const VkDeviceQueueCreateInfo *queue_create = &pCreateInfo->pQueueCreateInfos[i]; + + result = check_global_priority(physical_device, queue_create); + if (result != VK_SUCCESS) + goto err_finish_queues; + uint32_t qfi = queue_create->queueFamilyIndex; device->queues[qfi] = vk_alloc(&device->vk.alloc,