From 3e7b256564fe60c247cc1c09f332d418368c4699 Mon Sep 17 00:00:00 2001 From: Tony Ye Date: Tue, 11 Dec 2018 07:16:30 +0800 Subject: [PATCH] Set subslice mask according to the per-context sseu value. Fixes #267. --- .../linux/common/os/i915/include/mos_bufmgr.h | 10 ++ .../linux/common/os/i915/mos_bufmgr.c | 118 ++++++++++++++++++ .../linux/common/os/mos_os_specific.c | 27 ++++ 3 files changed, 155 insertions(+) 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 081522247f1..810e05ea09d 100644 --- a/media_driver/linux/common/os/i915/include/mos_bufmgr.h +++ b/media_driver/linux/common/os/i915/include/mos_bufmgr.h @@ -321,6 +321,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 6bc072c3ea8..ea70e7c81b5 100644 --- a/media_driver/linux/common/os/i915/mos_bufmgr.c +++ b/media_driver/linux/common/os/i915/mos_bufmgr.c @@ -4187,6 +4187,124 @@ mos_get_reset_stats(struct mos_linux_context *ctx, return ret; } +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 f07064c731c..d910c60675b 100644 --- a/media_driver/linux/common/os/mos_os_specific.c +++ b/media_driver/linux/common/os/mos_os_specific.c @@ -4062,6 +4062,33 @@ MOS_STATUS Mos_Specific_CreateGpuContext( auto cmdBufMgr = pOsContextSpecific->GetCmdBufMgr(); MOS_OS_CHK_NULL_RETURN(cmdBufMgr); + 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.engine_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; + }; + } + if (pOsContextSpecific->GetGpuContextHandle(mosGpuCxt) == MOS_GPU_CONTEXT_INVALID_HANDLE) { auto gpuContext = gpuContextMgr->CreateGpuContext(GpuNode, cmdBufMgr, mosGpuCxt);