iris: Create, destroy and replace Xe engines

Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22172>
This commit is contained in:
José Roberto de Souza 2022-11-11 08:23:16 -08:00 committed by Marge Bot
parent 35d6e830c7
commit 17c7eb1d4f
6 changed files with 234 additions and 5 deletions

View file

@ -44,6 +44,7 @@
#include "iris_kmd_backend.h"
#include "iris_utrace.h"
#include "i915/iris_batch.h"
#include "xe/iris_batch.h"
#include "common/intel_aux_map.h"
#include "common/intel_defines.h"
@ -256,7 +257,20 @@ iris_init_batch(struct iris_context *ice,
void
iris_init_batches(struct iris_context *ice)
{
iris_i915_init_batches(ice);
struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
struct iris_bufmgr *bufmgr = screen->bufmgr;
const struct intel_device_info *devinfo = iris_bufmgr_get_device_info(bufmgr);
switch (devinfo->kmd_type) {
case INTEL_KMD_TYPE_I915:
iris_i915_init_batches(ice);
break;
case INTEL_KMD_TYPE_XE:
iris_xe_init_batches(ice);
break;
default:
unreachable("missing");
}
iris_foreach_batch(ice, batch)
iris_init_batch(ice, batch - &ice->batches[0]);
@ -480,6 +494,7 @@ iris_batch_free(const struct iris_context *ice, struct iris_batch *batch)
{
struct iris_screen *screen = batch->screen;
struct iris_bufmgr *bufmgr = screen->bufmgr;
const struct intel_device_info *devinfo = iris_bufmgr_get_device_info(bufmgr);
for (int i = 0; i < batch->exec_count; i++) {
iris_bo_unreference(batch->exec_bos[i]);
@ -503,7 +518,16 @@ iris_batch_free(const struct iris_context *ice, struct iris_batch *batch)
batch->map = NULL;
batch->map_next = NULL;
iris_i915_destroy_batch(batch);
switch (devinfo->kmd_type) {
case INTEL_KMD_TYPE_I915:
iris_i915_destroy_batch(batch);
break;
case INTEL_KMD_TYPE_XE:
iris_xe_destroy_batch(batch);
break;
default:
unreachable("missing");
}
iris_destroy_batch_measure(batch->measure);
batch->measure = NULL;
@ -653,7 +677,19 @@ iris_finish_batch(struct iris_batch *batch)
static bool
replace_kernel_ctx(struct iris_batch *batch)
{
return iris_i915_replace_batch(batch);
struct iris_screen *screen = batch->screen;
struct iris_bufmgr *bufmgr = screen->bufmgr;
const struct intel_device_info *devinfo = iris_bufmgr_get_device_info(bufmgr);
switch (devinfo->kmd_type) {
case INTEL_KMD_TYPE_I915:
return iris_i915_replace_batch(batch);
case INTEL_KMD_TYPE_XE:
return iris_xe_replace_batch(batch);
default:
unreachable("missing");
return false;
}
}
enum pipe_reset_status
@ -814,7 +850,9 @@ _iris_batch_flush(struct iris_batch *batch, const char *file, int line)
if (basefile)
file = basefile + 5;
uint32_t batch_ctx_id = batch->i915.ctx_id;
enum intel_kmd_type kmd_type = iris_bufmgr_get_device_info(bufmgr)->kmd_type;
uint32_t batch_ctx_id = kmd_type == INTEL_KMD_TYPE_I915 ?
batch->i915.ctx_id : batch->xe.engine_id;
fprintf(stderr, "%19s:%-3d: %s batch [%u] flush with %5db (%0.1f%%) "
"(cmds), %4d BOs (%0.1fMb aperture)\n",
file, line, iris_batch_name_to_string(batch->name),

View file

@ -98,6 +98,9 @@ struct iris_batch {
uint32_t ctx_id;
uint32_t exec_flags;
} i915;
struct {
uint32_t engine_id;
} xe;
};
/** A list of all BOs referenced by this batch */

View file

@ -649,7 +649,7 @@ struct iris_context {
struct iris_batch batches[IRIS_BATCH_COUNT];
enum iris_context_priority priority;
bool has_engines_context;
bool has_engines_context; /* i915 specific */
struct u_upload_mgr *query_buffer_uploader;

View file

@ -24,6 +24,8 @@ files_libiris = files(
'i915/iris_bufmgr.c',
'i915/iris_bufmgr.h',
'i915/iris_kmd_backend.c',
'xe/iris_batch.c',
'xe/iris_batch.h',
'xe/iris_bufmgr.c',
'xe/iris_bufmgr.h',
'xe/iris_kmd_backend.c',

View file

@ -0,0 +1,154 @@
/*
* Copyright © 2023 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "xe/iris_batch.h"
#include "iris_batch.h"
#include "iris_context.h"
#include "iris_screen.h"
#include "common/intel_gem.h"
#include "common/intel_engine.h"
#include "common/xe/intel_engine.h"
#include "drm-uapi/xe_drm.h"
static bool
iris_xe_init_batch(struct iris_bufmgr *bufmgr,
struct intel_query_engine_info *engines_info,
enum intel_engine_class engine_class, uint32_t *engine_id)
{
struct drm_xe_engine_class_instance *instances;
instances = malloc(sizeof(*instances) *
intel_engines_count(engines_info, engine_class));
if (!instances)
return false;
uint32_t count = 0;
for (uint32_t i = 0; i < engines_info->num_engines; i++) {
const struct intel_engine_class_instance engine = engines_info->engines[i];
if (engine.engine_class != engine_class)
continue;
instances[count].engine_class = intel_engine_class_to_xe(engine.engine_class);
instances[count].engine_instance = engine.engine_instance;
/* TODO: handle gt_id, MTL and newer platforms will need it */
instances[count++].gt_id = 0;
}
struct drm_xe_engine_create create = {
.instances = (uintptr_t)instances,
.vm_id = iris_bufmgr_get_global_vm_id(bufmgr),
.width = 1,
.num_placements = count,
};
int ret = intel_ioctl(iris_bufmgr_get_fd(bufmgr),
DRM_IOCTL_XE_ENGINE_CREATE, &create);
free(instances);
if (ret == 0)
*engine_id = create.engine_id;
/* TODO: handle engine priority */
/* TODO: handle "protected" context/engine */
return ret == 0;
}
static void
iris_xe_map_intel_engine_class(const struct intel_query_engine_info *engines_info,
enum intel_engine_class *engine_classes)
{
engine_classes[IRIS_BATCH_RENDER] = INTEL_ENGINE_CLASS_RENDER;
engine_classes[IRIS_BATCH_COMPUTE] = INTEL_ENGINE_CLASS_RENDER;
engine_classes[IRIS_BATCH_BLITTER] = INTEL_ENGINE_CLASS_COPY;
STATIC_ASSERT(IRIS_BATCH_COUNT == 3);
if (debug_get_bool_option("INTEL_COMPUTE_CLASS", false) &&
intel_engines_count(engines_info, INTEL_ENGINE_CLASS_COMPUTE) > 0)
engine_classes[IRIS_BATCH_COMPUTE] = INTEL_ENGINE_CLASS_COMPUTE;
}
void iris_xe_init_batches(struct iris_context *ice)
{
struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
struct iris_bufmgr *bufmgr = screen->bufmgr;
const int fd = iris_bufmgr_get_fd(screen->bufmgr);
enum intel_engine_class engine_classes[IRIS_BATCH_COUNT];
struct intel_query_engine_info *engines_info;
engines_info = intel_engine_get_info(fd, INTEL_KMD_TYPE_XE);
assert(engines_info);
if (!engines_info)
return;
iris_xe_map_intel_engine_class(engines_info, engine_classes);
iris_foreach_batch(ice, batch) {
const enum iris_batch_name name = batch - &ice->batches[0];
ASSERTED bool ret;
ret = iris_xe_init_batch(bufmgr, engines_info, engine_classes[name],
&batch->xe.engine_id);
assert(ret);
}
free(engines_info);
}
void iris_xe_destroy_batch(struct iris_batch *batch)
{
struct iris_screen *screen = batch->screen;
struct iris_bufmgr *bufmgr = screen->bufmgr;
struct drm_xe_engine_destroy destroy = {
.engine_id = batch->xe.engine_id,
};
ASSERTED int ret;
ret = intel_ioctl(iris_bufmgr_get_fd(bufmgr), DRM_IOCTL_XE_ENGINE_DESTROY,
&destroy);
assert(ret == 0);
}
bool iris_xe_replace_batch(struct iris_batch *batch)
{
enum intel_engine_class engine_classes[IRIS_BATCH_COUNT];
struct iris_screen *screen = batch->screen;
struct iris_bufmgr *bufmgr = screen->bufmgr;
struct intel_query_engine_info *engines_info;
uint32_t new_engine_id;
bool ret;
engines_info = intel_engine_get_info(iris_bufmgr_get_fd(bufmgr),
INTEL_KMD_TYPE_XE);
if (!engines_info)
return false;
iris_xe_map_intel_engine_class(engines_info, engine_classes);
ret = iris_xe_init_batch(bufmgr, engines_info, engine_classes[batch->name],
&new_engine_id);
if (ret) {
iris_xe_destroy_batch(batch);
batch->xe.engine_id = new_engine_id;
}
free(engines_info);
return ret;
}

View file

@ -0,0 +1,32 @@
/*
* Copyright © 2023 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#pragma once
#include <stdbool.h>
struct iris_batch;
struct iris_context;
void iris_xe_init_batches(struct iris_context *ice);
bool iris_xe_replace_batch(struct iris_batch *batch);
void iris_xe_destroy_batch(struct iris_batch *batch);