From 1705eec6a0cb254917b81ef34c179a3650c4687e Mon Sep 17 00:00:00 2001 From: Tony Ye Date: Mon, 13 Aug 2018 06:20:26 +0800 Subject: [PATCH] Set subslice mask according to the per-context option. Fixed #267. --- .../common/os/libdrm/include/mos_bufmgr.h | 7 +- .../linux/common/os/libdrm/mos_bufmgr.c | 74 ++++++++++++++++--- .../linux/common/os/mos_context_specific.cpp | 39 ++++++++-- .../linux/common/os/mos_context_specific.h | 2 +- .../linux/common/os/mos_os_specific.c | 34 +++++++++ .../linux/ult/libdrm_mock/xf86drm_mock.c | 2 +- 6 files changed, 137 insertions(+), 21 deletions(-) diff --git a/media_driver/linux/common/os/libdrm/include/mos_bufmgr.h b/media_driver/linux/common/os/libdrm/include/mos_bufmgr.h index 9ee4fe80f3e..cc3c07ff351 100644 --- a/media_driver/linux/common/os/libdrm/include/mos_bufmgr.h +++ b/media_driver/linux/common/os/libdrm/include/mos_bufmgr.h @@ -342,8 +342,6 @@ int mos_get_context_param_sseu(struct mos_linux_context *ctx, int mos_set_context_param_sseu(struct mos_linux_context *ctx, struct drm_i915_gem_context_param_sseu sseu); -int mos_get_slice_mask(uint32_t slice_count); - int mos_get_context_param(struct mos_linux_context *ctx, uint32_t size, uint64_t param, @@ -356,6 +354,11 @@ 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_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/libdrm/mos_bufmgr.c b/media_driver/linux/common/os/libdrm/mos_bufmgr.c index a759662eca2..09ad39c6f94 100644 --- a/media_driver/linux/common/os/libdrm/mos_bufmgr.c +++ b/media_driver/linux/common/os/libdrm/mos_bufmgr.c @@ -4527,23 +4527,42 @@ mos_get_reset_stats(struct mos_linux_context *ctx, return ret; } -int mos_get_slice_mask(uint32_t slice_count) +unsigned int mos_hweight8(uint8_t w) { - uint32_t bitflag = 1; - uint32_t bitmask = 0; - uint32_t count = 0; + uint32_t i, weight = 0; - while (count < slice_count) + for (i=0; i<8; i++) { - bitmask = bitflag; - bitflag = bitmask | (bitflag << 1); - count++; + 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; - return bitmask; + assert (n>0 && n<=8); + + out_mask = in_mask; + count = n; + for(i=0; i<8; i++) + { + bi = 1UL<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, @@ -4584,6 +4604,7 @@ mos_set_context_param_sseu(struct mos_linux_context *ctx, 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, @@ -4591,7 +4612,6 @@ mos_set_context_param_sseu(struct mos_linux_context *ctx, return ret; } -#endif int mos_get_context_param(struct mos_linux_context *ctx, @@ -4680,6 +4700,38 @@ mos_get_subslice_total(int fd, unsigned int *subslice_total) return 0; } +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_eu_total(int fd, unsigned int *eu_total) { diff --git a/media_driver/linux/common/os/mos_context_specific.cpp b/media_driver/linux/common/os/mos_context_specific.cpp index 7c20d941560..dc2077dac6f 100644 --- a/media_driver/linux/common/os/mos_context_specific.cpp +++ b/media_driver/linux/common/os/mos_context_specific.cpp @@ -475,24 +475,42 @@ void OsContextSpecific::SetSliceCount(uint32_t *pSliceCount) } } - struct drm_i915_gem_context_param_sseu sseu = { .flags = I915_EXEC_RENDER }; - sseu.value = m_sseu; - sliceMask = mos_get_slice_mask(sliceCount); + struct drm_i915_gem_context_param_sseu sseu; + MOS_ZeroMemory(&sseu, sizeof(sseu)); + sseu.engine_class = 0; + sseu.instance = 0; - if (sliceMask != sseu.packed.slice_mask) + if (sliceCount != mos_hweight8(m_sseu.slice_mask)) { if (mos_get_context_param_sseu(m_intelContext, &sseu)) { MOS_OS_ASSERTMESSAGE("Failed to get context parameter."); return ; }; - sseu.packed.slice_mask = sliceMask; + + unsigned int device_slice_mask; + if (mos_get_slice_mask(m_fd, &device_slice_mask)) + { + MOS_OS_ASSERTMESSAGE("Failed to get device slice mask."); + return ; + } + + if (mos_hweight8(device_slice_mask) > sliceCount) + { + sseu.slice_mask = mos_switch_off_n_bits((uint8_t)device_slice_mask, + mos_hweight8(device_slice_mask) - sliceCount); + } + else + { + sseu.slice_mask = device_slice_mask; + } + if (mos_set_context_param_sseu(m_intelContext, sseu)) { MOS_OS_ASSERTMESSAGE("Failed to set context parameter."); return ; } - m_sseu = sseu.value; + m_sseu = sseu; } *pSliceCount = sliceCount; @@ -589,6 +607,15 @@ MOS_STATUS OsContextSpecific::Init(PMOS_CONTEXT pOsDriverContext) MOS_OS_ASSERTMESSAGE("Failed to create drm intel context"); return MOS_STATUS_UNKNOWN; } + + MOS_ZeroMemory(&m_sseu, sizeof(m_sseu)); + m_sseu.engine_class = 0; + m_sseu.instance = 0; + if (mos_get_context_param_sseu(m_intelContext, &m_sseu)) + { + MOS_OS_ASSERTMESSAGE("Failed to get context parameter sseu."); + return MOS_STATUS_UNKNOWN; + }; #else m_intelContext = nullptr; #endif diff --git a/media_driver/linux/common/os/mos_context_specific.h b/media_driver/linux/common/os/mos_context_specific.h index 58890a4396e..a310ffa3f29 100644 --- a/media_driver/linux/common/os/mos_context_specific.h +++ b/media_driver/linux/common/os/mos_context_specific.h @@ -335,7 +335,7 @@ class OsContextSpecific : public OsContext //! //! \brief sseu for current context //! - uint64_t m_sseu = 0; + struct drm_i915_gem_context_param_sseu m_sseu; //! //! \brief Semophore ID for ruling SSEU configration //! diff --git a/media_driver/linux/common/os/mos_os_specific.c b/media_driver/linux/common/os/mos_os_specific.c index 01dd1ad0f79..665a8156da9 100644 --- a/media_driver/linux/common/os/mos_os_specific.c +++ b/media_driver/linux/common/os/mos_os_specific.c @@ -4111,6 +4111,40 @@ 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) + { + unsigned int subslice_mask; + 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_get_subslice_mask(pOsInterface->pOsContext->fd, &subslice_mask)) + { + MOS_OS_ASSERTMESSAGE("Failed to get subslice mask."); + return MOS_STATUS_UNKNOWN; + } + + if (mos_hweight8(sseu.subslice_mask) > createOption->packed.SubSliceCount) + { + sseu.subslice_mask = mos_switch_off_n_bits(subslice_mask, + mos_hweight8((uint8_t)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; } diff --git a/media_driver/linux/ult/libdrm_mock/xf86drm_mock.c b/media_driver/linux/ult/libdrm_mock/xf86drm_mock.c index c47b6c5ae49..615f634e312 100644 --- a/media_driver/linux/ult/libdrm_mock/xf86drm_mock.c +++ b/media_driver/linux/ult/libdrm_mock/xf86drm_mock.c @@ -341,7 +341,7 @@ mosdrmIoctl(int fd, unsigned long request, void *arg) case DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM: case DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM: { - ret = -1; + ret = 0; } break; default: