mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 13:50:11 +01:00
iris/batch: Add support for engines contexts
As described in "intel: Add intel_gem_create_context_engines", this
should make it easier to support an I915_ENGINE_CLASS_FOO engine in
the future. For example, maybe something like:
98c3bbd5b5
Reworks:
* Tweak engine counting logic (s-b Ken)
* Tweak init of engine_classes in iris_init_engines_context (s-b Ken)
* Add STATIC_ASSERT on engine_classes (Jordan)
* Paulo: Call iris_hw_context_set_unrecoverable() for engines context
* Rename to has_engines_context (s-b Paulo)
* Jordan: Handle creating a new engines context when the context needs
to be replaced.
* Ken: Tweak context destroy code paths.
* Call iris_lost_context_state on every batch. (s-b Ken)
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12692>
This commit is contained in:
parent
9f0070e9e8
commit
5c4c8bdc4c
2 changed files with 105 additions and 12 deletions
|
|
@ -180,6 +180,12 @@ iris_init_batch(struct iris_context *ice,
|
||||||
struct iris_batch *batch = &ice->batches[name];
|
struct iris_batch *batch = &ice->batches[name];
|
||||||
struct iris_screen *screen = (void *) ice->ctx.screen;
|
struct iris_screen *screen = (void *) ice->ctx.screen;
|
||||||
|
|
||||||
|
/* Note: ctx_id, exec_flags and has_engines_context fields are initialized
|
||||||
|
* at an earlier phase when contexts are created.
|
||||||
|
*
|
||||||
|
* Ref: iris_init_engines_context(), iris_init_non_engine_contexts()
|
||||||
|
*/
|
||||||
|
|
||||||
batch->screen = screen;
|
batch->screen = screen;
|
||||||
batch->dbg = &ice->dbg;
|
batch->dbg = &ice->dbg;
|
||||||
batch->reset = &ice->reset;
|
batch->reset = &ice->reset;
|
||||||
|
|
@ -243,14 +249,74 @@ iris_init_non_engine_contexts(struct iris_context *ice, int priority)
|
||||||
struct iris_batch *batch = &ice->batches[i];
|
struct iris_batch *batch = &ice->batches[i];
|
||||||
batch->ctx_id = iris_create_hw_context(screen->bufmgr);
|
batch->ctx_id = iris_create_hw_context(screen->bufmgr);
|
||||||
batch->exec_flags = I915_EXEC_RENDER;
|
batch->exec_flags = I915_EXEC_RENDER;
|
||||||
|
batch->has_engines_context = false;
|
||||||
assert(batch->ctx_id);
|
assert(batch->ctx_id);
|
||||||
iris_hw_context_set_priority(screen->bufmgr, batch->ctx_id, priority);
|
iris_hw_context_set_priority(screen->bufmgr, batch->ctx_id, priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
iris_create_engines_context(struct iris_context *ice, int priority)
|
||||||
|
{
|
||||||
|
struct iris_screen *screen = (void *) ice->ctx.screen;
|
||||||
|
int fd = iris_bufmgr_get_fd(screen->bufmgr);
|
||||||
|
|
||||||
|
struct drm_i915_query_engine_info *engines_info =
|
||||||
|
intel_i915_query_alloc(fd, DRM_I915_QUERY_ENGINE_INFO);
|
||||||
|
|
||||||
|
if (!engines_info)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (intel_gem_count_engines(engines_info, I915_ENGINE_CLASS_RENDER) < 1) {
|
||||||
|
free(engines_info);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC_ASSERT(IRIS_BATCH_COUNT == 2);
|
||||||
|
uint16_t engine_classes[IRIS_BATCH_COUNT] = {
|
||||||
|
[IRIS_BATCH_RENDER] = I915_ENGINE_CLASS_RENDER,
|
||||||
|
[IRIS_BATCH_COMPUTE] = I915_ENGINE_CLASS_RENDER,
|
||||||
|
};
|
||||||
|
|
||||||
|
int engines_ctx =
|
||||||
|
intel_gem_create_context_engines(fd, engines_info, IRIS_BATCH_COUNT,
|
||||||
|
engine_classes);
|
||||||
|
|
||||||
|
if (engines_ctx < 0) {
|
||||||
|
free(engines_info);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
iris_hw_context_set_unrecoverable(screen->bufmgr, engines_ctx);
|
||||||
|
|
||||||
|
free(engines_info);
|
||||||
|
return engines_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
iris_init_engines_context(struct iris_context *ice, int priority)
|
||||||
|
{
|
||||||
|
int engines_ctx = iris_create_engines_context(ice, priority);
|
||||||
|
if (engines_ctx < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
struct iris_screen *screen = (void *) ice->ctx.screen;
|
||||||
|
iris_hw_context_set_priority(screen->bufmgr, engines_ctx, priority);
|
||||||
|
|
||||||
|
for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
|
||||||
|
struct iris_batch *batch = &ice->batches[i];
|
||||||
|
batch->ctx_id = engines_ctx;
|
||||||
|
batch->exec_flags = i;
|
||||||
|
batch->has_engines_context = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
iris_init_batches(struct iris_context *ice, int priority)
|
iris_init_batches(struct iris_context *ice, int priority)
|
||||||
{
|
{
|
||||||
|
if (!iris_init_engines_context(ice, priority))
|
||||||
iris_init_non_engine_contexts(ice, priority);
|
iris_init_non_engine_contexts(ice, priority);
|
||||||
for (int i = 0; i < IRIS_BATCH_COUNT; i++)
|
for (int i = 0; i < IRIS_BATCH_COUNT; i++)
|
||||||
iris_init_batch(ice, (enum iris_batch_name) i);
|
iris_init_batch(ice, (enum iris_batch_name) i);
|
||||||
|
|
@ -488,6 +554,8 @@ iris_batch_free(struct iris_batch *batch)
|
||||||
batch->map = NULL;
|
batch->map = NULL;
|
||||||
batch->map_next = NULL;
|
batch->map_next = NULL;
|
||||||
|
|
||||||
|
/* iris_destroy_batches() will destroy engines contexts. */
|
||||||
|
if (!batch->has_engines_context)
|
||||||
iris_destroy_kernel_context(bufmgr, batch->ctx_id);
|
iris_destroy_kernel_context(bufmgr, batch->ctx_id);
|
||||||
|
|
||||||
iris_destroy_batch_measure(batch->measure);
|
iris_destroy_batch_measure(batch->measure);
|
||||||
|
|
@ -502,6 +570,15 @@ iris_batch_free(struct iris_batch *batch)
|
||||||
void
|
void
|
||||||
iris_destroy_batches(struct iris_context *ice)
|
iris_destroy_batches(struct iris_context *ice)
|
||||||
{
|
{
|
||||||
|
/* If we are using an engines context, then a single kernel context is
|
||||||
|
* created, with multiple hardware contexts. So, we only need to destroy
|
||||||
|
* the context on the first batch.
|
||||||
|
*/
|
||||||
|
if (ice->batches[0].has_engines_context) {
|
||||||
|
iris_destroy_kernel_context(ice->batches[0].screen->bufmgr,
|
||||||
|
ice->batches[0].ctx_id);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < IRIS_BATCH_COUNT; i++)
|
for (int i = 0; i < IRIS_BATCH_COUNT; i++)
|
||||||
iris_batch_free(&ice->batches[i]);
|
iris_batch_free(&ice->batches[i]);
|
||||||
}
|
}
|
||||||
|
|
@ -616,11 +693,25 @@ iris_finish_batch(struct iris_batch *batch)
|
||||||
* Replace our current GEM context with a new one (in case it got banned).
|
* Replace our current GEM context with a new one (in case it got banned).
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
replace_hw_ctx(struct iris_batch *batch)
|
replace_kernel_ctx(struct iris_batch *batch)
|
||||||
{
|
{
|
||||||
struct iris_screen *screen = batch->screen;
|
struct iris_screen *screen = batch->screen;
|
||||||
struct iris_bufmgr *bufmgr = screen->bufmgr;
|
struct iris_bufmgr *bufmgr = screen->bufmgr;
|
||||||
|
|
||||||
|
if (batch->has_engines_context) {
|
||||||
|
struct iris_context *ice = batch->ice;
|
||||||
|
int priority = iris_kernel_context_get_priority(bufmgr, batch->ctx_id);
|
||||||
|
uint32_t old_ctx = batch->ctx_id;
|
||||||
|
int new_ctx = iris_create_engines_context(ice, priority);
|
||||||
|
if (new_ctx < 0)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
|
||||||
|
ice->batches[i].ctx_id = new_ctx;
|
||||||
|
/* Notify the context that state must be re-initialized. */
|
||||||
|
iris_lost_context_state(&ice->batches[i]);
|
||||||
|
}
|
||||||
|
iris_destroy_kernel_context(bufmgr, old_ctx);
|
||||||
|
} else {
|
||||||
uint32_t new_ctx = iris_clone_hw_context(bufmgr, batch->ctx_id);
|
uint32_t new_ctx = iris_clone_hw_context(bufmgr, batch->ctx_id);
|
||||||
if (!new_ctx)
|
if (!new_ctx)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -630,6 +721,7 @@ replace_hw_ctx(struct iris_batch *batch)
|
||||||
|
|
||||||
/* Notify the context that state must be re-initialized. */
|
/* Notify the context that state must be re-initialized. */
|
||||||
iris_lost_context_state(batch);
|
iris_lost_context_state(batch);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -662,7 +754,7 @@ iris_batch_check_for_reset(struct iris_batch *batch)
|
||||||
* Throw it away and start with a fresh context. Ideally this may
|
* Throw it away and start with a fresh context. Ideally this may
|
||||||
* catch the problem before our next execbuf fails with -EIO.
|
* catch the problem before our next execbuf fails with -EIO.
|
||||||
*/
|
*/
|
||||||
replace_hw_ctx(batch);
|
replace_kernel_ctx(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
@ -970,7 +1062,7 @@ _iris_batch_flush(struct iris_batch *batch, const char *file, int line)
|
||||||
* dubiously claim success...
|
* dubiously claim success...
|
||||||
* Also handle ENOMEM here.
|
* Also handle ENOMEM here.
|
||||||
*/
|
*/
|
||||||
if ((ret == -EIO || ret == -ENOMEM) && replace_hw_ctx(batch)) {
|
if ((ret == -EIO || ret == -ENOMEM) && replace_kernel_ctx(batch)) {
|
||||||
if (batch->reset->reset) {
|
if (batch->reset->reset) {
|
||||||
/* Tell gallium frontends the device is lost and it was our fault. */
|
/* Tell gallium frontends the device is lost and it was our fault. */
|
||||||
batch->reset->reset(batch->reset->data, PIPE_GUILTY_CONTEXT_RESET);
|
batch->reset->reset(batch->reset->data, PIPE_GUILTY_CONTEXT_RESET);
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ struct iris_batch {
|
||||||
|
|
||||||
uint32_t ctx_id;
|
uint32_t ctx_id;
|
||||||
uint32_t exec_flags;
|
uint32_t exec_flags;
|
||||||
|
bool has_engines_context;
|
||||||
|
|
||||||
/** A list of all BOs referenced by this batch */
|
/** A list of all BOs referenced by this batch */
|
||||||
struct iris_bo **exec_bos;
|
struct iris_bo **exec_bos;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue