From 9090058ed18077a529604cb656b817d39fe98fd1 Mon Sep 17 00:00:00 2001 From: Tony Ye Date: Thu, 14 Feb 2019 01:39:46 +0800 Subject: [PATCH 1/2] Synced i915 header i915_drm.h to drm-next commit 16065fcdd19ddb9e093192914ac863884f308766 to include the SSEU uAPI. --- .../linux/common/os/i915/include/uapi/README | 25 +++++-- .../linux/common/os/i915/include/uapi/drm.h | 1 - .../common/os/i915/include/uapi/drm_fourcc.h | 43 +++++++++++ .../common/os/i915/include/uapi/drm_mode.h | 19 +++++ .../common/os/i915/include/uapi/i915_drm.h | 72 +++++++++++++++++++ 5 files changed, 154 insertions(+), 6 deletions(-) diff --git a/media_driver/linux/common/os/i915/include/uapi/README b/media_driver/linux/common/os/i915/include/uapi/README index b45a1dc9040..59b4ad2b6fa 100644 --- a/media_driver/linux/common/os/i915/include/uapi/README +++ b/media_driver/linux/common/os/i915/include/uapi/README @@ -13,9 +13,24 @@ $ make headers_install INSTALL_HDR_PATH=/path/to/install The last update was done at the following kernel commit : -commit 9235dd441af43599b9cdcce599a3da4083fcad3c -Merge: d7563c5 36b486b -Author: Dave Airlie -Date: Mon Nov 19 11:07:52 2018 +1000 +commit 16065fcdd19ddb9e093192914ac863884f308766 +Author: Gerd Hoffmann +Date: Fri Feb 8 15:04:09 2019 +0100 - Merge branch 'drm-next-4.21' of git://people.freedesktop.org/~agd5f/linux into drm-next + drm/virtio: do NOT reuse resource ids + + Bisected guest kernel changes crashing qemu. Landed at + "6c1cd97bda drm/virtio: fix resource id handling". Looked again, and + noticed we where not only leaking *some* ids, but *all* ids. The old + code never ever called virtio_gpu_resource_id_put(). + + So, commit 6c1cd97bda effectively makes the linux kernel starting + re-using IDs after releasing them, and apparently virglrenderer can't + deal with that. Oops. + + This patch puts a temporary stopgap into place for the 5.0 release. + + Signed-off-by: Gerd Hoffmann + Reviewed-by: Dave Airlie + Signed-off-by: Dave Airlie + Link: https://patchwork.freedesktop.org/patch/msgid/20190208140409.15280-1-kraxel@redhat.com diff --git a/media_driver/linux/common/os/i915/include/uapi/drm.h b/media_driver/linux/common/os/i915/include/uapi/drm.h index 02b4169555a..85c685a2075 100644 --- a/media_driver/linux/common/os/i915/include/uapi/drm.h +++ b/media_driver/linux/common/os/i915/include/uapi/drm.h @@ -711,7 +711,6 @@ struct drm_prime_handle { struct drm_syncobj_create { __u32 handle; #define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0) -#define DRM_SYNCOBJ_CREATE_TYPE_TIMELINE (1 << 1) __u32 flags; }; diff --git a/media_driver/linux/common/os/i915/include/uapi/drm_fourcc.h b/media_driver/linux/common/os/i915/include/uapi/drm_fourcc.h index e7e48f1f4a7..93a341d278a 100644 --- a/media_driver/linux/common/os/i915/include/uapi/drm_fourcc.h +++ b/media_driver/linux/common/os/i915/include/uapi/drm_fourcc.h @@ -151,6 +151,7 @@ extern "C" { #define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */ #define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */ +#define DRM_FORMAT_XYUV8888 fourcc_code('X', 'Y', 'U', 'V') /* [31:0] X:Y:Cb:Cr 8:8:8:8 little endian */ /* * packed YCbCr420 2x2 tiled formats @@ -237,6 +238,8 @@ extern "C" { #define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06 #define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07 #define DRM_FORMAT_MOD_VENDOR_ARM 0x08 +#define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09 + /* add more to the end as needed */ #define DRM_FORMAT_RESERVED ((1ULL << 56) - 1) @@ -571,6 +574,9 @@ extern "C" { * AFBC has several features which may be supported and/or used, which are * represented using bits in the modifier. Not all combinations are valid, * and different devices or use-cases may support different combinations. + * + * Further information on the use of AFBC modifiers can be found in + * Documentation/gpu/afbc.rst */ #define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode) fourcc_mod_code(ARM, __afbc_mode) @@ -580,10 +586,18 @@ extern "C" { * Indicates the superblock size(s) used for the AFBC buffer. The buffer * size (in pixels) must be aligned to a multiple of the superblock size. * Four lowest significant bits(LSBs) are reserved for block size. + * + * Where one superblock size is specified, it applies to all planes of the + * buffer (e.g. 16x16, 32x8). When multiple superblock sizes are specified, + * the first applies to the Luma plane and the second applies to the Chroma + * plane(s). e.g. (32x8_64x4 means 32x8 Luma, with 64x4 Chroma). + * Multiple superblock sizes are only valid for multi-plane YCbCr formats. */ #define AFBC_FORMAT_MOD_BLOCK_SIZE_MASK 0xf #define AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 (1ULL) #define AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 (2ULL) +#define AFBC_FORMAT_MOD_BLOCK_SIZE_64x4 (3ULL) +#define AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4 (4ULL) /* * AFBC lossless colorspace transform @@ -643,6 +657,35 @@ extern "C" { */ #define AFBC_FORMAT_MOD_SC (1ULL << 9) +/* + * AFBC double-buffer + * + * Indicates that the buffer is allocated in a layout safe for front-buffer + * rendering. + */ +#define AFBC_FORMAT_MOD_DB (1ULL << 10) + +/* + * AFBC buffer content hints + * + * Indicates that the buffer includes per-superblock content hints. + */ +#define AFBC_FORMAT_MOD_BCH (1ULL << 11) + +/* + * Allwinner tiled modifier + * + * This tiling mode is implemented by the VPU found on all Allwinner platforms, + * codenamed sunxi. It is associated with a YUV format that uses either 2 or 3 + * planes. + * + * With this tiling, the luminance samples are disposed in tiles representing + * 32x32 pixels and the chrominance samples in tiles representing 32x64 pixels. + * The pixel order in each tile is linear and the tiles are disposed linearly, + * both in row-major order. + */ +#define DRM_FORMAT_MOD_ALLWINNER_TILED fourcc_mod_code(ALLWINNER, 1) + #if defined(__cplusplus) } #endif diff --git a/media_driver/linux/common/os/i915/include/uapi/drm_mode.h b/media_driver/linux/common/os/i915/include/uapi/drm_mode.h index d3e0fe31efc..a439c2e6789 100644 --- a/media_driver/linux/common/os/i915/include/uapi/drm_mode.h +++ b/media_driver/linux/common/os/i915/include/uapi/drm_mode.h @@ -888,6 +888,25 @@ struct drm_mode_revoke_lease { __u32 lessee_id; }; +/** + * struct drm_mode_rect - Two dimensional rectangle. + * @x1: Horizontal starting coordinate (inclusive). + * @y1: Vertical starting coordinate (inclusive). + * @x2: Horizontal ending coordinate (exclusive). + * @y2: Vertical ending coordinate (exclusive). + * + * With drm subsystem using struct drm_rect to manage rectangular area this + * export it to user-space. + * + * Currently used by drm_mode_atomic blob property FB_DAMAGE_CLIPS. + */ +struct drm_mode_rect { + __s32 x1; + __s32 y1; + __s32 x2; + __s32 y2; +}; + #if defined(__cplusplus) } #endif diff --git a/media_driver/linux/common/os/i915/include/uapi/i915_drm.h b/media_driver/linux/common/os/i915/include/uapi/i915_drm.h index 268b585f8a4..d2792ab3640 100644 --- a/media_driver/linux/common/os/i915/include/uapi/i915_drm.h +++ b/media_driver/linux/common/os/i915/include/uapi/i915_drm.h @@ -412,6 +412,14 @@ typedef struct drm_i915_irq_wait { int irq_seq; } drm_i915_irq_wait_t; +/* + * Different modes of per-process Graphics Translation Table, + * see I915_PARAM_HAS_ALIASING_PPGTT + */ +#define I915_GEM_PPGTT_NONE 0 +#define I915_GEM_PPGTT_ALIASING 1 +#define I915_GEM_PPGTT_FULL 2 + /* Ioctl to query kernel params: */ #define I915_PARAM_IRQ_ACTIVE 1 @@ -1478,9 +1486,73 @@ struct drm_i915_gem_context_param { #define I915_CONTEXT_MAX_USER_PRIORITY 1023 /* inclusive */ #define I915_CONTEXT_DEFAULT_PRIORITY 0 #define I915_CONTEXT_MIN_USER_PRIORITY -1023 /* inclusive */ + /* + * When using the following param, value should be a pointer to + * drm_i915_gem_context_param_sseu. + */ +#define I915_CONTEXT_PARAM_SSEU 0x7 __u64 value; }; +/** + * Context SSEU programming + * + * It may be necessary for either functional or performance reason to configure + * a context to run with a reduced number of SSEU (where SSEU stands for Slice/ + * Sub-slice/EU). + * + * This is done by configuring SSEU configuration using the below + * @struct drm_i915_gem_context_param_sseu for every supported engine which + * userspace intends to use. + * + * Not all GPUs or engines support this functionality in which case an error + * code -ENODEV will be returned. + * + * Also, flexibility of possible SSEU configuration permutations varies between + * GPU generations and software imposed limitations. Requesting such a + * combination will return an error code of -EINVAL. + * + * NOTE: When perf/OA is active the context's SSEU configuration is ignored in + * favour of a single global setting. + */ +struct drm_i915_gem_context_param_sseu { + /* + * Engine class & instance to be configured or queried. + */ + __u16 engine_class; + __u16 engine_instance; + + /* + * Unused for now. Must be cleared to zero. + */ + __u32 flags; + + /* + * Mask of slices to enable for the context. Valid values are a subset + * of the bitmask value returned for I915_PARAM_SLICE_MASK. + */ + __u64 slice_mask; + + /* + * Mask of subslices to enable for the context. Valid values are a + * subset of the bitmask value return by I915_PARAM_SUBSLICE_MASK. + */ + __u64 subslice_mask; + + /* + * Minimum/Maximum number of EUs to enable per subslice for the + * context. min_eus_per_subslice must be inferior or equal to + * max_eus_per_subslice. + */ + __u16 min_eus_per_subslice; + __u16 max_eus_per_subslice; + + /* + * Unused for now. Must be cleared to zero. + */ + __u32 rsvd; +}; + enum drm_i915_oa_format { I915_OA_FORMAT_A13 = 1, /* HSW only */ I915_OA_FORMAT_A29, /* HSW only */ From c0c34bf30eaa7d75d92b78cc6fd1617864920a43 Mon Sep 17 00:00:00 2001 From: Tony Ye Date: Tue, 11 Dec 2018 07:16:30 +0800 Subject: [PATCH 2/2] 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);