diff --git a/src/intel/common/intel_gem.c b/src/intel/common/intel_gem.c index 8634486be15..267d0657315 100644 --- a/src/intel/common/intel_gem.c +++ b/src/intel/common/intel_gem.c @@ -68,3 +68,89 @@ intel_gem_count_engines(const struct drm_i915_query_engine_info *info, } return count; } + +int +intel_gem_create_context_engines(int fd, + const struct drm_i915_query_engine_info *info, + int num_engines, uint16_t *engine_classes) +{ + assert(info != NULL); + const size_t engine_inst_sz = 2 * sizeof(__u16); /* 1 class, 1 instance */ + const size_t engines_param_size = + sizeof(__u64) /* extensions */ + num_engines * engine_inst_sz; + + void *engines_param = malloc(engines_param_size); + assert(engines_param); + *(__u64*)engines_param = 0; + __u16 *class_inst_ptr = (__u16*)(((__u64*)engines_param) + 1); + + /* For each type of drm_i915_gem_engine_class of interest, we keep track of + * the previous engine instance used. + */ + int last_engine_idx[] = { + [I915_ENGINE_CLASS_RENDER] = -1, + }; + + int i915_engine_counts[] = { + [I915_ENGINE_CLASS_RENDER] = + intel_gem_count_engines(info, I915_ENGINE_CLASS_RENDER), + }; + + /* For each queue, we look for the next instance that matches the class we + * need. + */ + for (int i = 0; i < num_engines; i++) { + uint16_t engine_class = engine_classes[i]; + assert(engine_class == I915_ENGINE_CLASS_RENDER); + if (i915_engine_counts[engine_class] <= 0) { + free(engines_param); + return -1; + } + + /* Run through the engines reported by the kernel looking for the next + * matching instance. We loop in case we want to create multiple + * contexts on an engine instance. + */ + int engine_instance = -1; + for (int i = 0; i < info->num_engines; i++) { + int *idx = &last_engine_idx[engine_class]; + if (++(*idx) >= info->num_engines) + *idx = 0; + if (info->engines[*idx].engine.engine_class == engine_class) { + engine_instance = info->engines[*idx].engine.engine_instance; + break; + } + } + if (engine_instance < 0) { + free(engines_param); + return -1; + } + + *class_inst_ptr++ = engine_class; + *class_inst_ptr++ = engine_instance; + } + + assert((uintptr_t)engines_param + engines_param_size == + (uintptr_t)class_inst_ptr); + + struct drm_i915_gem_context_create_ext_setparam set_engines = { + .base = { + .name = I915_CONTEXT_CREATE_EXT_SETPARAM, + }, + .param = { + .param = I915_CONTEXT_PARAM_ENGINES, + .value = (uintptr_t)engines_param, + .size = engines_param_size, + } + }; + struct drm_i915_gem_context_create_ext create = { + .flags = I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS, + .extensions = (uintptr_t)&set_engines, + }; + int ret = intel_ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT, &create); + free(engines_param); + if (ret == -1) + return -1; + + return create.ctx_id; +} diff --git a/src/intel/common/intel_gem.h b/src/intel/common/intel_gem.h index 31380b714a9..12481e2dad6 100644 --- a/src/intel/common/intel_gem.h +++ b/src/intel/common/intel_gem.h @@ -148,5 +148,8 @@ bool intel_gem_supports_syncobj_wait(int fd); int intel_gem_count_engines(const struct drm_i915_query_engine_info *info, enum drm_i915_gem_engine_class engine_class); +int intel_gem_create_context_engines(int fd, + const struct drm_i915_query_engine_info *info, + int num_engines, uint16_t *engine_classes); #endif /* INTEL_GEM_H */ diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index d6fc0268bdd..bcaddf88a99 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -3063,9 +3063,9 @@ VkResult anv_CreateDevice( engine_classes[engine_count++] = queue_family->engine_class; } device->context_id = - anv_gem_create_context_engines(device, - physical_device->engine_info, - engine_count, engine_classes); + intel_gem_create_context_engines(device->fd, + physical_device->engine_info, + engine_count, engine_classes); } else { assert(num_queues == 1); device->context_id = anv_gem_create_context(device); diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c index cabce04e123..cdfac0b1786 100644 --- a/src/intel/vulkan/anv_gem.c +++ b/src/intel/vulkan/anv_gem.c @@ -337,90 +337,6 @@ anv_gem_create_context(struct anv_device *device) return create.ctx_id; } -int -anv_gem_create_context_engines(struct anv_device *device, - const struct drm_i915_query_engine_info *info, - int num_engines, uint16_t *engine_classes) -{ - const size_t engine_inst_sz = 2 * sizeof(__u16); /* 1 class, 1 instance */ - const size_t engines_param_size = - sizeof(__u64) /* extensions */ + num_engines * engine_inst_sz; - - void *engines_param = malloc(engines_param_size); - assert(engines_param); - *(__u64*)engines_param = 0; - __u16 *class_inst_ptr = (__u16*)(((__u64*)engines_param) + 1); - - /* For each type of drm_i915_gem_engine_class of interest, we keep track of - * the previous engine instance used. - */ - int last_engine_idx[] = { - [I915_ENGINE_CLASS_RENDER] = -1, - }; - - int i915_engine_counts[] = { - [I915_ENGINE_CLASS_RENDER] = - intel_gem_count_engines(info, I915_ENGINE_CLASS_RENDER), - }; - - /* For each queue, we look for the next instance that matches the class we - * need. - */ - for (int i = 0; i < num_engines; i++) { - uint16_t engine_class = engine_classes[i]; - if (i915_engine_counts[engine_class] <= 0) { - free(engines_param); - return -1; - } - - /* Run through the engines reported by the kernel looking for the next - * matching instance. We loop in case we want to create multiple - * contexts on an engine instance. - */ - int engine_instance = -1; - for (int i = 0; i < info->num_engines; i++) { - int *idx = &last_engine_idx[engine_class]; - if (++(*idx) >= info->num_engines) - *idx = 0; - if (info->engines[*idx].engine.engine_class == engine_class) { - engine_instance = info->engines[*idx].engine.engine_instance; - break; - } - } - if (engine_instance < 0) { - free(engines_param); - return -1; - } - - *class_inst_ptr++ = engine_class; - *class_inst_ptr++ = engine_instance; - } - - assert((uintptr_t)engines_param + engines_param_size == - (uintptr_t)class_inst_ptr); - - struct drm_i915_gem_context_create_ext_setparam set_engines = { - .base = { - .name = I915_CONTEXT_CREATE_EXT_SETPARAM, - }, - .param = { - .param = I915_CONTEXT_PARAM_ENGINES, - .value = (uintptr_t)engines_param, - .size = engines_param_size, - } - }; - struct drm_i915_gem_context_create_ext create = { - .flags = I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS, - .extensions = (uintptr_t)&set_engines, - }; - int ret = intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT, &create); - free(engines_param); - if (ret == -1) - return -1; - - return create.ctx_id; -} - int anv_gem_destroy_context(struct anv_device *device, int context) { diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c index 7f4a7960c02..6dc971522af 100644 --- a/src/intel/vulkan/anv_gem_stubs.c +++ b/src/intel/vulkan/anv_gem_stubs.c @@ -193,15 +193,6 @@ anv_i915_query(int fd, uint64_t query_id, void *buffer, unreachable("Unused"); } -int -anv_gem_create_context_engines(struct anv_device *device, - const struct drm_i915_query_engine_info *info, - int num_engines, - uint16_t *engine_classes) -{ - unreachable("Unused"); -} - struct drm_i915_query_engine_info * anv_gem_get_engine_info(int fd) { diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 45813225e06..d91339d8a3f 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1365,10 +1365,6 @@ int anv_gem_execbuffer(struct anv_device *device, int anv_gem_set_tiling(struct anv_device *device, uint32_t gem_handle, uint32_t stride, uint32_t tiling); int anv_gem_create_context(struct anv_device *device); -int anv_gem_create_context_engines(struct anv_device *device, - const struct drm_i915_query_engine_info *info, - int num_engines, - uint16_t *engine_classes); bool anv_gem_has_context_priority(int fd, int priority); int anv_gem_destroy_context(struct anv_device *device, int context); int anv_gem_set_context_param(int fd, int context, uint32_t param,