Module: Mesa Branch: main Commit: b37530257663f32b41567c0b0e019d86b5451252 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b37530257663f32b41567c0b0e019d86b5451252
Author: Sagar Ghuge <sagar.gh...@intel.com> Date: Sat Jun 10 22:13:08 2023 -0700 anv: Create companion RCS engine We need to create companion RCS engine when there is CCS/BCS engine creation requested. v2: - Factor out anv_xe_create_engine code in create_engine (Jose) Signed-off-by: Sagar Ghuge <sagar.gh...@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwer...@intel.com> Reviewed-by: José Roberto de Souza <jose.so...@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23661> --- src/intel/vulkan/anv_device.c | 1 + src/intel/vulkan/anv_private.h | 3 +++ src/intel/vulkan/i915/anv_device.c | 8 ++++++ src/intel/vulkan/i915/anv_queue.c | 35 +++++++++++++++++++----- src/intel/vulkan/xe/anv_device.c | 36 ++++++++++++++++++------- src/intel/vulkan/xe/anv_queue.c | 55 +++++++++++++++++++++++++++++++------- 6 files changed, 112 insertions(+), 26 deletions(-) diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 9dd15fa919c..92b1e7f771a 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -65,6 +65,7 @@ #include "i915/anv_device.h" #include "xe/anv_device.h" +#include "xe/anv_queue.h" #include "genxml/gen7_pack.h" #include "genxml/genX_bits.h" diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 1fff2bd3e09..ea3bfb6e9e0 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1075,6 +1075,9 @@ struct anv_queue { uint32_t exec_queue_id; /* Xe */ }; + /** Context/Engine id which executes companion RCS command buffer */ + uint32_t companion_rcs_id; + /** Synchronization object for debug purposes (DEBUG_SYNC) */ struct vk_sync *sync; diff --git a/src/intel/vulkan/i915/anv_device.c b/src/intel/vulkan/i915/anv_device.c index d16dc3b4c0a..392d9eeb688 100644 --- a/src/intel/vulkan/i915/anv_device.c +++ b/src/intel/vulkan/i915/anv_device.c @@ -342,6 +342,14 @@ anv_i915_device_check_status(struct vk_device *vk_device) device->queues[i].context_id); if (result != VK_SUCCESS) return result; + + if (device->queues[i].companion_rcs_id != 0) { + uint32_t context_id = device->queues[i].companion_rcs_id; + result = anv_gem_context_get_reset_stats(device, context_id); + if (result != VK_SUCCESS) { + return result; + } + } } } else { result = anv_gem_context_get_reset_stats(device, device->context_id); diff --git a/src/intel/vulkan/i915/anv_queue.c b/src/intel/vulkan/i915/anv_queue.c index 59c918be234..f2b8f848b8d 100644 --- a/src/intel/vulkan/i915/anv_queue.c +++ b/src/intel/vulkan/i915/anv_queue.c @@ -57,19 +57,32 @@ anv_i915_create_engine(struct anv_device *device, } } else if (device->physical->has_vm_control) { assert(pCreateInfo->queueFamilyIndex < physical->queue.family_count); - enum intel_engine_class engine_classes[2]; - int engine_count = 0; - - engine_classes[engine_count++] = queue_family->engine_class; - + enum intel_engine_class engine_classes[1]; + engine_classes[0] = queue_family->engine_class; if (!intel_gem_create_context_engines(device->fd, 0 /* flags */, physical->engine_info, - engine_count, engine_classes, + 1, engine_classes, device->vm_id, (uint32_t *)&queue->context_id)) return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, "engine creation failed"); + /* Create a companion RCS logical engine to support MSAA copy/clear + * operation on compute/copy engine. + */ + if (queue_family->engine_class == INTEL_ENGINE_CLASS_COPY || + queue_family->engine_class == INTEL_ENGINE_CLASS_COMPUTE) { + uint32_t *context_id = (uint32_t *)&queue->companion_rcs_id; + engine_classes[0] = INTEL_ENGINE_CLASS_RENDER; + if (!intel_gem_create_context_engines(device->fd, 0 /* flags */, + physical->engine_info, + 1, engine_classes, + device->vm_id, + context_id)) + return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, + "companion RCS engine creation failed"); + } + /* Check if client specified queue priority. */ const VkDeviceQueueGlobalPriorityCreateInfoKHR *queue_priority = vk_find_struct_const(pCreateInfo->pNext, @@ -80,6 +93,9 @@ anv_i915_create_engine(struct anv_device *device, queue_priority); if (result != VK_SUCCESS) { intel_gem_destroy_context(device->fd, queue->context_id); + if (queue->companion_rcs_id != 0) { + intel_gem_destroy_context(device->fd, queue->companion_rcs_id); + } return result; } } else { @@ -95,6 +111,11 @@ anv_i915_create_engine(struct anv_device *device, void anv_i915_destroy_engine(struct anv_device *device, struct anv_queue *queue) { - if (device->physical->has_vm_control) + if (device->physical->has_vm_control) { intel_gem_destroy_context(device->fd, queue->context_id); + + if (queue->companion_rcs_id != 0) { + intel_gem_destroy_context(device->fd, queue->companion_rcs_id); + } + } } diff --git a/src/intel/vulkan/xe/anv_device.c b/src/intel/vulkan/xe/anv_device.c index d13c4ee1393..bdd4202d410 100644 --- a/src/intel/vulkan/xe/anv_device.c +++ b/src/intel/vulkan/xe/anv_device.c @@ -157,6 +157,23 @@ anv_xe_physical_device_init_memory_types(struct anv_physical_device *device) return VK_SUCCESS; } +static VkResult +anv_xe_get_device_status(struct anv_device *device, uint32_t exec_queue_id) +{ + VkResult result = VK_SUCCESS; + struct drm_xe_exec_queue_get_property exec_queue_get_property = { + .exec_queue_id = exec_queue_id, + .property = XE_EXEC_QUEUE_GET_PROPERTY_BAN, + }; + int ret = intel_ioctl(device->fd, DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY, + &exec_queue_get_property); + + if (ret || exec_queue_get_property.value) + result = vk_device_set_lost(&device->vk, "One or more queues banned"); + + return result; +} + VkResult anv_xe_device_check_status(struct vk_device *vk_device) { @@ -164,16 +181,15 @@ anv_xe_device_check_status(struct vk_device *vk_device) VkResult result = VK_SUCCESS; for (uint32_t i = 0; i < device->queue_count; i++) { - struct drm_xe_exec_queue_get_property exec_queue_get_property = { - .exec_queue_id = device->queues[i].exec_queue_id, - .property = XE_EXEC_QUEUE_GET_PROPERTY_BAN, - }; - int ret = intel_ioctl(device->fd, DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY, - &exec_queue_get_property); - - if (ret || exec_queue_get_property.value) { - result = vk_device_set_lost(&device->vk, "One or more queues banned"); - break; + result = anv_xe_get_device_status(device, device->queues[i].exec_queue_id); + if (result != VK_SUCCESS) + return result; + + if (device->queues[i].companion_rcs_id != 0) { + uint32_t exec_queue_id = device->queues[i].companion_rcs_id; + result = anv_xe_get_device_status(device, exec_queue_id); + if (result != VK_SUCCESS) + return result; } } diff --git a/src/intel/vulkan/xe/anv_queue.c b/src/intel/vulkan/xe/anv_queue.c index 7ded1cc87ef..2c51b22b721 100644 --- a/src/intel/vulkan/xe/anv_queue.c +++ b/src/intel/vulkan/xe/anv_queue.c @@ -48,14 +48,19 @@ anv_vk_priority_to_drm_sched_priority(VkQueueGlobalPriorityKHR vk_priority) } } -VkResult -anv_xe_create_engine(struct anv_device *device, - struct anv_queue *queue, - const VkDeviceQueueCreateInfo *pCreateInfo) +static VkResult +create_engine(struct anv_device *device, + struct anv_queue *queue, + const VkDeviceQueueCreateInfo *pCreateInfo, + bool create_companion_rcs_engine) { struct anv_physical_device *physical = device->physical; + uint32_t queue_family_index = + create_companion_rcs_engine ? + anv_get_first_render_queue_index(physical) : + pCreateInfo->queueFamilyIndex; struct anv_queue_family *queue_family = - &physical->queue.families[pCreateInfo->queueFamilyIndex]; + &physical->queue.families[queue_family_index]; const struct intel_query_engine_info *engines = physical->engine_info; struct drm_xe_engine_class_instance *instances; @@ -90,7 +95,10 @@ anv_xe_create_engine(struct anv_device *device, if (ret) return vk_errorf(device, VK_ERROR_UNKNOWN, "Unable to create exec queue"); - queue->exec_queue_id = create.exec_queue_id; + if (create_companion_rcs_engine) + queue->companion_rcs_id = create.exec_queue_id; + else + queue->exec_queue_id = create.exec_queue_id; const VkDeviceQueueGlobalPriorityCreateInfoKHR *queue_priority = vk_find_struct_const(pCreateInfo->pNext, @@ -126,11 +134,40 @@ priority_error: return vk_error(device, VK_ERROR_NOT_PERMITTED_KHR); } -void -anv_xe_destroy_engine(struct anv_device *device, struct anv_queue *queue) +VkResult +anv_xe_create_engine(struct anv_device *device, + struct anv_queue *queue, + const VkDeviceQueueCreateInfo *pCreateInfo) +{ + VkResult result = create_engine(device, queue, pCreateInfo, + false /* create_companion_rcs_engine */); + + if (result != VK_SUCCESS) + return result; + + if (queue->family->engine_class == INTEL_ENGINE_CLASS_COPY || + queue->family->engine_class == INTEL_ENGINE_CLASS_COMPUTE) { + result = create_engine(device, queue, pCreateInfo, + true /* create_companion_rcs_engine */); + } + + return result; +} + +static void +destroy_engine(struct anv_device *device, uint32_t exec_queue_id) { struct drm_xe_exec_queue_destroy destroy = { - .exec_queue_id = queue->exec_queue_id, + .exec_queue_id = exec_queue_id, }; intel_ioctl(device->fd, DRM_IOCTL_XE_EXEC_QUEUE_DESTROY, &destroy); } + +void +anv_xe_destroy_engine(struct anv_device *device, struct anv_queue *queue) +{ + destroy_engine(device, queue->exec_queue_id); + + if (queue->companion_rcs_id != 0) + destroy_engine(device, queue->companion_rcs_id); +}