Skip to content

Commit

Permalink
Enable virtual engine on Gen11 Linux.
Browse files Browse the repository at this point in the history
  • Loading branch information
zxye authored and intel-mediadev committed May 28, 2019
1 parent b19cf78 commit 1f15f04
Show file tree
Hide file tree
Showing 9 changed files with 478 additions and 16 deletions.
22 changes: 22 additions & 0 deletions media_driver/linux/common/os/i915/include/mos_bufmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct mos_linux_context {
#ifndef ANDROID
struct _MOS_OS_CONTEXT *pOsContext;
#endif
struct drm_i915_gem_vm_control* vm;
};

struct mos_linux_bo {
Expand Down Expand Up @@ -240,6 +241,27 @@ int mos_get_aperture_sizes(int fd, size_t *mappable, size_t *total);
int mos_bufmgr_gem_get_devid(struct mos_bufmgr *bufmgr);

struct mos_linux_context *mos_gem_context_create(struct mos_bufmgr *bufmgr);
struct mos_linux_context *mos_gem_context_create_ext(
struct mos_bufmgr *bufmgr,
__u32 flags);
struct mos_linux_context *mos_gem_context_create_shared(
struct mos_bufmgr *bufmgr,
mos_linux_context* ctx,
__u32 flags);
struct drm_i915_gem_vm_control* mos_gem_vm_create(struct mos_bufmgr *bufmgr);
void mos_gem_vm_destroy(struct mos_bufmgr *bufmgr, struct drm_i915_gem_vm_control* vm);

#define MAX_ENGINE_INSTANCE_NUM 8

int mos_query_engines(int fd,
__u16 engine_class,
__u64 caps,
unsigned int *nengine,
struct i915_engine_class_instance *ci);
int mos_set_context_param_load_balance(struct mos_linux_context *ctx,
struct i915_engine_class_instance *ci,
unsigned int count);

void mos_gem_context_destroy(struct mos_linux_context *ctx);
int mos_gem_bo_context_exec(struct mos_linux_bo *bo, struct mos_linux_context *ctx,
int used, unsigned int flags);
Expand Down
222 changes: 222 additions & 0 deletions media_driver/linux/common/os/i915/mos_bufmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4691,3 +4691,225 @@ mos_bufmgr_gem_init(int fd, int batch_size)

return bufmgr_gem != nullptr ? &bufmgr_gem->bufmgr : nullptr;
}

struct mos_linux_context *
mos_gem_context_create_ext(struct mos_bufmgr *bufmgr, __u32 flags)
{
struct mos_bufmgr_gem *bufmgr_gem = (struct mos_bufmgr_gem *)bufmgr;
struct drm_i915_gem_context_create_ext create;
struct mos_linux_context *context = nullptr;
int ret;

context = (struct mos_linux_context *)calloc(1, sizeof(*context));
if (!context)
return nullptr;

memclear(create);
create.flags = flags;
create.extensions = 0;
ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT, &create);
if (ret != 0) {
MOS_DBG("DRM_IOCTL_I915_GEM_CONTEXT_CREATE failed: %s\n",
strerror(errno));
free(context);
return nullptr;
}

context->ctx_id = create.ctx_id;
context->bufmgr = bufmgr;

return context;
}

struct drm_i915_gem_vm_control* mos_gem_vm_create(struct mos_bufmgr *bufmgr)
{
struct mos_bufmgr_gem *bufmgr_gem = (struct mos_bufmgr_gem *)bufmgr;
struct drm_i915_gem_vm_control *vm = nullptr;
int ret;

vm = (struct drm_i915_gem_vm_control *)calloc(1, sizeof(*vm));
memset(vm, 0, sizeof(*vm));

ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_VM_CREATE, vm);
if (ret != 0) {
MOS_DBG("DRM_IOCTL_I915_GEM_VM_CREATE failed: %s\n",
strerror(errno));
return nullptr;
}

return vm;
}

void mos_gem_vm_destroy(struct mos_bufmgr *bufmgr, struct drm_i915_gem_vm_control* vm)
{
struct mos_bufmgr_gem *bufmgr_gem = (struct mos_bufmgr_gem *)bufmgr;
assert(vm);
int ret;

ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_VM_DESTROY, vm);
if (ret != 0) {
MOS_DBG("DRM_IOCTL_I915_GEM_VM_DESTROY failed: %s\n",
strerror(errno));
}
free(vm);
}

struct mos_linux_context *
mos_gem_context_create_shared(struct mos_bufmgr *bufmgr, mos_linux_context* ctx, __u32 flags)
{
struct mos_bufmgr_gem *bufmgr_gem = (struct mos_bufmgr_gem *)bufmgr;
struct drm_i915_gem_context_create_ext create;
struct mos_linux_context *context = nullptr;
int ret;

if (ctx == nullptr || ctx->vm == nullptr)
return nullptr;

context = (struct mos_linux_context *)calloc(1, sizeof(*context));
if (!context)
return nullptr;

memclear(create);
create.flags = flags;
create.extensions = 0;
ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT, &create);
if (ret != 0) {
MOS_DBG("DRM_IOCTL_I915_GEM_CONTEXT_CREATE failed: %s\n",
strerror(errno));
free(context);
return nullptr;
}

context->ctx_id = create.ctx_id;
context->bufmgr = bufmgr;

ret = mos_set_context_param(context,
0,
I915_CONTEXT_PARAM_VM,
ctx->vm->vm_id);
if(ret != 0) {
MOS_DBG("I915_CONTEXT_PARAM_VM failed: %s\n",
strerror(errno));
free(context);
return nullptr;
}

return context;
}

int mos_query_engines(int fd,
__u16 engine_class,
__u64 caps,
unsigned int *nengine,
struct i915_engine_class_instance *ci)
{
struct drm_i915_query query;
struct drm_i915_query_item query_item;
struct drm_i915_query_engine_info *engines = nullptr;
int ret, len;

memclear(query_item);
query_item.query_id = DRM_I915_QUERY_ENGINE_INFO;
query_item.length = 0;
memclear(query);
query.num_items = 1;
query.items_ptr = (uintptr_t)&query_item;

ret = drmIoctl(fd, DRM_IOCTL_I915_QUERY, &query);
if (ret)
{
goto fini;
}
len = query_item.length;

engines = (drm_i915_query_engine_info *)malloc(len);
memset(engines,0,len);
memclear(query_item);
query_item.query_id = DRM_I915_QUERY_ENGINE_INFO;
query_item.length = len;
query_item.data_ptr = (uintptr_t)engines;
memclear(query);
query.num_items = 1;
query.items_ptr = (uintptr_t)&query_item;

ret = drmIoctl(fd, DRM_IOCTL_I915_QUERY, &query);
if (ret)
{
goto fini;
}

int i, num;
for (i = 0, num = 0; i < engines->num_engines; i++) {
struct drm_i915_engine_info *engine =
(struct drm_i915_engine_info *)&engines->engines[i];
if ( engine_class == engine->engine.engine_class
&& ((caps & engine->capabilities) == caps ))
{
ci->engine_class = engine_class;
ci->engine_instance = engine->engine.engine_instance;
ci++;
num++;
}
if (num > *nengine)
{
fprintf(stderr,"%s: Number of engine instances out of range, %d,%d\n",
__FUNCTION__, num, *nengine);
goto fini;
}
}
*nengine = num;


fini:
if (engines)
free(engines);
return ret;
}

int mos_set_context_param_load_balance(struct mos_linux_context *ctx,
struct i915_engine_class_instance *ci,
unsigned int count)
{
int ret;
uint32_t size;
struct i915_context_engines_load_balance* balancer = nullptr;
struct i915_context_param_engines* set_engines = nullptr;

assert(ci);

/* I915_DEFINE_CONTEXT_ENGINES_LOAD_BALANCE */
size = sizeof(struct i915_context_engines_load_balance) + count * sizeof(*ci);
balancer = (struct i915_context_engines_load_balance*)malloc(size);
if (NULL == balancer)
{
ret = -ENOMEM;
goto fini;
}
memset(balancer, 0, size);
balancer->base.name = I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE;
balancer->num_siblings = count;
memcpy(balancer->engines, ci, count * sizeof(*ci));

/* I915_DEFINE_CONTEXT_PARAM_ENGINES */
size = sizeof(uint64_t) + sizeof(*ci);
set_engines = (struct i915_context_param_engines*) malloc(size);
if (NULL == set_engines)
{
ret = -ENOMEM;
goto fini;
}
set_engines->extensions = (uintptr_t)(balancer);
set_engines->engines[0].engine_class = I915_ENGINE_CLASS_INVALID;
set_engines->engines[0].engine_instance = I915_ENGINE_CLASS_INVALID_NONE;

ret = mos_set_context_param(ctx,
size,
I915_CONTEXT_PARAM_ENGINES,
(uintptr_t)set_engines);
fini:
if (set_engines)
free(set_engines);
if (balancer)
free(balancer);
return ret;
}
25 changes: 23 additions & 2 deletions media_driver/linux/common/os/mos_context_specific.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,25 @@ MOS_STATUS OsContextSpecific::Init(PMOS_CONTEXT pOsDriverContext)
m_tileYFlag = MEDIA_IS_SKU(&m_skuTable, FtrTileY);

#ifndef ANDROID
m_intelContext = mos_gem_context_create(pOsDriverContext->bufmgr);

if (MEDIA_IS_SKU(&m_skuTable,FtrContextBasedScheduling))
{
m_intelContext = mos_gem_context_create_ext(pOsDriverContext->bufmgr,0);
if (m_intelContext)
{
m_intelContext->vm = mos_gem_vm_create(pOsDriverContext->bufmgr);
if (m_intelContext->vm == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to create vm.\n");
return MOS_STATUS_UNKNOWN;
}
}
}
else //use legacy context create ioctl for pre-gen11 platforms
{
m_intelContext = mos_gem_context_create(pOsDriverContext->bufmgr);
m_intelContext->vm = nullptr;
}

if (m_intelContext == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to create drm intel context");
Expand Down Expand Up @@ -555,6 +572,10 @@ void OsContextSpecific::Destroy()
#endif
m_skuTable.reset();
m_waTable.reset();
if (m_intelContext->vm)
{
mos_gem_vm_destroy(m_intelContext->bufmgr, m_intelContext->vm);
}
if (m_intelContext)
{
mos_gem_context_destroy(m_intelContext);
Expand Down

0 comments on commit 1f15f04

Please sign in to comment.