diff --git a/media_driver/linux/common/os/i915/include/mos_bufmgr.h b/media_driver/linux/common/os/i915/include/mos_bufmgr.h index 4dfd729c5f..8591e1f3b9 100644 --- a/media_driver/linux/common/os/i915/include/mos_bufmgr.h +++ b/media_driver/linux/common/os/i915/include/mos_bufmgr.h @@ -322,6 +322,16 @@ int mos_set_context_param(struct mos_linux_context *ctx, int mos_get_subslice_total(int fd, unsigned int *subslice_total); int mos_get_eu_total(int fd, unsigned int *eu_total); + +int mos_get_context_param_sseu(struct mos_linux_context *ctx, + struct drm_i915_gem_context_param_sseu *sseu); +int mos_set_context_param_sseu(struct mos_linux_context *ctx, + struct drm_i915_gem_context_param_sseu sseu); +int mos_get_subslice_mask(int fd, unsigned int *subslice_mask); +int mos_get_slice_mask(int fd, unsigned int *slice_mask); +uint8_t mos_switch_off_n_bits(uint8_t in_mask, int n); +unsigned int mos_hweight8(uint8_t w); + #if defined(__cplusplus) extern "C" { #endif diff --git a/media_driver/linux/common/os/i915/mos_bufmgr.c b/media_driver/linux/common/os/i915/mos_bufmgr.c index 1d70b5a7e9..ccfade6751 100644 --- a/media_driver/linux/common/os/i915/mos_bufmgr.c +++ b/media_driver/linux/common/os/i915/mos_bufmgr.c @@ -4181,6 +4181,124 @@ int mos_get_slice_mask(uint32_t slice_count) return bitmask; } +unsigned int mos_hweight8(uint8_t w) +{ + uint32_t i, weight = 0; + + for (i=0; i<8; i++) + { + weight += !!((w) & (1UL << i)); + } + return weight; +} + +uint8_t mos_switch_off_n_bits(uint8_t in_mask, int n) +{ + int i,count; + uint8_t bi,out_mask; + + assert (n>0 && n<=8); + + out_mask = in_mask; + count = n; + for(i=0; i<8; i++) + { + bi = 1UL<bufmgr; + memset(&context_param, 0, sizeof(context_param)); + context_param.ctx_id = ctx->ctx_id; + context_param.param = I915_CONTEXT_PARAM_SSEU; + context_param.value = (uint64_t) sseu; + context_param.size = sizeof(struct drm_i915_gem_context_param_sseu); + + ret = drmIoctl(bufmgr_gem->fd, + DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, + &context_param); + + return ret; +} + +int +mos_set_context_param_sseu(struct mos_linux_context *ctx, + struct drm_i915_gem_context_param_sseu sseu) +{ + struct mos_bufmgr_gem *bufmgr_gem; + struct drm_i915_gem_context_param context_param; + int ret; + + if (ctx == nullptr) + return -EINVAL; + + bufmgr_gem = (struct mos_bufmgr_gem *)ctx->bufmgr; + memset(&context_param, 0, sizeof(context_param)); + context_param.ctx_id = ctx->ctx_id; + context_param.param = I915_CONTEXT_PARAM_SSEU; + context_param.value = (uint64_t) &sseu; + context_param.size = sizeof(struct drm_i915_gem_context_param_sseu); + + ret = drmIoctl(bufmgr_gem->fd, + DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, + &context_param); + + return ret; +} + +int +mos_get_subslice_mask(int fd, unsigned int *subslice_mask) +{ + drm_i915_getparam_t gp; + int ret; + + memclear(gp); + gp.value = (int*)subslice_mask; + gp.param = I915_PARAM_SUBSLICE_MASK; + ret = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + if (ret) + return -errno; + + return 0; +} + +int +mos_get_slice_mask(int fd, unsigned int *slice_mask) +{ + drm_i915_getparam_t gp; + int ret; + + memclear(gp); + gp.value = (int*)slice_mask; + gp.param = I915_PARAM_SLICE_MASK; + ret = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + if (ret) + return -errno; + + return 0; +} + int mos_get_context_param(struct mos_linux_context *ctx, uint32_t size, diff --git a/media_driver/linux/common/os/mos_os_specific.c b/media_driver/linux/common/os/mos_os_specific.c index bb6207552d..cbecbb6c9c 100644 --- a/media_driver/linux/common/os/mos_os_specific.c +++ b/media_driver/linux/common/os/mos_os_specific.c @@ -4075,6 +4075,33 @@ MOS_STATUS Mos_Specific_CreateGpuContext( pOsContextSpecific->SetGpuContextHandle(mosGpuCxt, gpuContextSpecific->GetGpuContextHandle()); } + MOS_OS_CHK_NULL_RETURN(createOption); + if (GpuNode == MOS_GPU_NODE_3D && createOption->SSEUValue != 0) + { + struct drm_i915_gem_context_param_sseu sseu; + MOS_ZeroMemory(&sseu, sizeof(sseu)); + sseu.engine_class = I915_ENGINE_CLASS_RENDER; + sseu.instance = 0; + + if (mos_get_context_param_sseu(pOsInterface->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(pOsInterface->pOsContext->intel_context, sseu)) + { + MOS_OS_ASSERTMESSAGE("Failed to set sseu configuration."); + return MOS_STATUS_UNKNOWN; + }; + } + return MOS_STATUS_SUCCESS; }