Skip to content

Commit

Permalink
Enable virtual engine (single pipe) on Gen11.
Browse files Browse the repository at this point in the history
  • Loading branch information
zxye committed Mar 4, 2019
1 parent 17dba8f commit b577916
Show file tree
Hide file tree
Showing 8 changed files with 386 additions and 13 deletions.
17 changes: 17 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 @@ -240,6 +240,23 @@ 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 class_instance {
uint16_t engine_class;
uint16_t engine_instance;
};

#define MAX_ENGINE_INSTANCE_NUM 8

int mos_query_engines(int fd,
__u16 engine_class,
__u64 caps,
unsigned int *nengine,
struct class_instance *ci);
int mos_set_context_param_load_balance(struct mos_linux_context *ctx,
const struct 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
156 changes: 156 additions & 0 deletions media_driver/linux/common/os/i915/mos_bufmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4648,3 +4648,159 @@ 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;
}


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

engines = (drm_i915_query_engine_info *)malloc(4096);
memset(engines,0,4096);
memclear(query_item);
query_item.query_id = DRM_I915_QUERY_ENGINE_INFO;
query_item.length = 0;
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;
}
len = query_item.length;

memset(engines,0,4096);
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_class
&& ((caps & engine->capabilities) || caps == 0))
{
ci->engine_class = engine_class;
ci->engine_instance = 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:
free(engines);
return ret;
}

int mos_set_context_param_load_balance(struct mos_linux_context *ctx,
const struct class_instance *ci,
unsigned int count)
{
int ret;

assert(ci);

struct balancer {
uint64_t next_extension;
uint64_t name;

uint64_t flags;
uint64_t mask;

uint64_t mbz[4];
} balancer;
memclear(balancer);
balancer.name = I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE;
balancer.mask = ~0ull;

/*
struct set_engines {
uint64_t extension;
struct class_instance engines[count];
} set_engines;
*/
uint32_t size = sizeof(uint64_t) + (count + 1) * sizeof(struct class_instance);
uint32_t* set_engines = (uint32_t*) malloc(size);
if (NULL == set_engines)
{
return -ENOMEM;
}

/* set_engines->extension */
*((uint64_t*)set_engines) = (uintptr_t)(&balancer);

/* set_engines->engines[0],
KMD requires the first entry of the engine map to be:
class=I915_ENGINE_CLASS_INVALID:instance=I915_ENGINE_CLASS_INVALID_NONE
*/
struct class_instance* ptr = (struct class_instance*)(set_engines+2);
ptr->engine_class = I915_ENGINE_CLASS_INVALID;
ptr->engine_instance = I915_ENGINE_CLASS_INVALID_NONE;

/* set_engines->engines[1]..[count], the "real" engine map */
memcpy(set_engines+3, ci, count * sizeof(struct class_instance));

ret = mos_set_context_param(ctx,
size,
I915_CONTEXT_PARAM_ENGINES,
(uintptr_t)set_engines);
free(set_engines);
return ret;
}
159 changes: 150 additions & 9 deletions media_driver/linux/common/os/mos_gpucontext_specific.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ GpuContextSpecific::~GpuContextSpecific()
Clear();
}

MOS_STATUS GpuContextSpecific::Init(OsContext *osContext)
MOS_STATUS GpuContextSpecific::Init(OsContext *osContext,
PMOS_INTERFACE osInterface,
MOS_GPU_NODE GpuNode,
PMOS_GPUCTX_CREATOPTIONS createOption)
{
MOS_OS_FUNCTION_ENTER;

Expand Down Expand Up @@ -112,6 +115,85 @@ MOS_STATUS GpuContextSpecific::Init(OsContext *osContext)

m_GPUStatusTag = 1;

m_createOptionEnhanced = (MOS_GPUCTX_CREATOPTIONS_ENHANCED*)MOS_AllocAndZeroMemory(sizeof(MOS_GPUCTX_CREATOPTIONS_ENHANCED));
m_createOptionEnhanced->SSEUValue = createOption->SSEUValue;

if (osInterface->ctxBasedScheduling)
{
m_i915Context = mos_gem_context_create_ext(osInterface->pOsContext->bufmgr,
I915_GEM_CONTEXT_SINGLE_TIMELINE);
if (m_i915Context == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to create context.\n");
return MOS_STATUS_UNKNOWN;
}
m_i915Context->pOsContext = osInterface->pOsContext;

m_i915ExecFlag = I915_EXEC_DEFAULT;
if (GpuNode == MOS_GPU_NODE_3D)
{
struct class_instance engine_map;
engine_map.engine_class = I915_ENGINE_CLASS_RENDER;
engine_map.engine_instance = 0;

if (mos_set_context_param_load_balance(m_i915Context,&engine_map, 1))
{
MOS_OS_ASSERTMESSAGE("Failed to set balancer extension.\n");
return MOS_STATUS_UNKNOWN;
}

if (createOption->SSEUValue != 0)
{
struct drm_i915_gem_context_param_sseu sseu;
MOS_ZeroMemory(&sseu, sizeof(sseu));
sseu.engine_class = I915_ENGINE_CLASS_RENDER;
sseu.engine_instance = 0;

if (mos_get_context_param_sseu(osInterface->pOsContext->intel_context, &sseu))
{
MOS_OS_ASSERTMESSAGE("Failed to get sseu configuration.");
return MOS_STATUS_UNKNOWN;
};

if (mos_hweight8(sseu.subslice_mask) > createOption->packed.SubSliceCount)
{
sseu.subslice_mask = mos_switch_off_n_bits(sseu.subslice_mask,
mos_hweight8(sseu.subslice_mask)-createOption->packed.SubSliceCount);
}

if (mos_set_context_param_sseu(m_i915Context, sseu))
{
MOS_OS_ASSERTMESSAGE("Failed to set sseu configuration.");
return MOS_STATUS_UNKNOWN;
};
}
}
else if (GpuNode == MOS_GPU_NODE_VIDEO || GpuNode == MOS_GPU_NODE_VIDEO2)
{
unsigned int nengine = MAX_ENGINE_INSTANCE_NUM;
struct class_instance engine_map[MAX_ENGINE_INSTANCE_NUM];
__u16 engine_class = I915_ENGINE_CLASS_VIDEO;
__u64 caps = 0;

if (m_createOptionEnhanced->UsingSFC)
{
caps |= I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC;
}

MOS_ZeroMemory(engine_map, sizeof(engine_map));
if (mos_query_engines(osInterface->pOsContext->fd,engine_class,caps,&nengine,engine_map))
{
MOS_OS_ASSERTMESSAGE("Failed to query engines.\n");
return MOS_STATUS_UNKNOWN;
}

if (mos_set_context_param_load_balance(m_i915Context, engine_map, nengine))
{
MOS_OS_ASSERTMESSAGE("Failed to set balancer extension.\n");
return MOS_STATUS_UNKNOWN;
}
}
}
return MOS_STATUS_SUCCESS;
}

Expand Down Expand Up @@ -154,6 +236,12 @@ void GpuContextSpecific::Clear()
MOS_SafeFreeMemory(m_patchLocationList);
MOS_SafeFreeMemory(m_attachedResources);
MOS_SafeFreeMemory(m_writeModeList);
MOS_SafeFreeMemory(m_createOptionEnhanced);
if (m_i915Context)
{
mos_gem_context_destroy(m_i915Context);
m_i915Context = nullptr;
}
}

MOS_STATUS GpuContextSpecific::RegisterResource(
Expand Down Expand Up @@ -326,6 +414,7 @@ MOS_STATUS GpuContextSpecific::GetCommandBuffer(

// zero comamnd buffer
MOS_ZeroMemory(comamndBuffer->pCmdBase, comamndBuffer->iRemaining);
MOS_ZeroMemory(&comamndBuffer->Attributes,sizeof(comamndBuffer->Attributes));

// update command buffer relared filed in GPU context
m_cmdBufFlushed = false;
Expand Down Expand Up @@ -655,7 +744,7 @@ MOS_STATUS GpuContextSpecific::SubmitCommandBuffer(
int32_t DR4 = osContext->uEnablePerfTag ? perfData : 0;

//Since CB2 command is not supported, remove it and set cliprects to nullprt as default.
if (gpuNode != I915_EXEC_RENDER)
if (gpuNode == MOS_GPU_NODE_VIDEO || gpuNode == MOS_GPU_NODE_VIDEO2)
{
if (osContext->bKMDHasVCS2)
{
Expand Down Expand Up @@ -785,13 +874,26 @@ MOS_STATUS GpuContextSpecific::SubmitCommandBuffer(
execFlag);
}
#else
ret = mos_gem_bo_context_exec2(cmd_bo,
m_commandBufferSize,
osContext->intel_context,
cliprects,
num_cliprects,
DR4,
execFlag);
if (osInterface->ctxBasedScheduling && m_i915Context != nullptr)
{
ret = mos_gem_bo_context_exec2(cmd_bo,
m_commandBufferSize,
m_i915Context,
cliprects,
num_cliprects,
DR4,
m_i915ExecFlag);
}
else
{
ret = mos_gem_bo_context_exec2(cmd_bo,
m_commandBufferSize,
osContext->intel_context,
cliprects,
num_cliprects,
DR4,
execFlag);
}
#endif

if (ret != 0)
Expand Down Expand Up @@ -905,3 +1007,42 @@ MOS_STATUS GpuContextSpecific::AllocateGPUStatusBuf()
m_statusBufferResource = graphicsResource;
return MOS_STATUS_SUCCESS;
}

MOS_STATUS GpuContextSpecific::SetContextParam(PMOS_GPUCTX_CREATOPTIONS_ENHANCED createOptionEnhanced)
{
MOS_OS_FUNCTION_ENTER;

if (m_createOptionEnhanced->UsingSFC != createOptionEnhanced->UsingSFC)
{
unsigned int nengine = MAX_ENGINE_INSTANCE_NUM;
struct class_instance engine_map[MAX_ENGINE_INSTANCE_NUM];
__u16 engine_class = I915_ENGINE_CLASS_VIDEO;
__u64 caps = 0;

if (createOptionEnhanced->UsingSFC)
{
caps |= I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC;
}

if (m_i915Context)
{
MOS_ZeroMemory(engine_map, sizeof(engine_map));
if (mos_query_engines(m_i915Context->pOsContext->fd,engine_class,caps,&nengine,engine_map))
{
MOS_OS_ASSERTMESSAGE("Failed to query engines.\n");
return MOS_STATUS_UNKNOWN;
}

if (mos_set_context_param_load_balance(m_i915Context, engine_map, nengine))
{
MOS_OS_ASSERTMESSAGE("Failed to set balancer extension.\n");
return MOS_STATUS_UNKNOWN;
}
}
}

m_createOptionEnhanced->Flags = createOptionEnhanced->Flags;
m_createOptionEnhanced->LRCACount = createOptionEnhanced->LRCACount;

return MOS_STATUS_SUCCESS;
}

0 comments on commit b577916

Please sign in to comment.