From 4be2d4485e111fd2adace4013e81955def48c723 Mon Sep 17 00:00:00 2001 From: Zhizhen Tang Date: Tue, 6 Aug 2019 16:27:22 +0800 Subject: [PATCH] Add bo tile to linear switch by BLT engine on UMD Signed-off-by: Zhizhen Tang --- media_driver/linux/common/ddi/media_libva.cpp | 38 ++++++++++++++++--- .../linux/common/ddi/media_libva_common.h | 2 + .../linux/common/ddi/media_libva_util.cpp | 13 +++++++ .../linux/common/os/libdrm/include/i915_drm.h | 10 +++++ .../common/os/libdrm/include/mos_bufmgr.h | 2 +- .../linux/common/os/libdrm/mos_bufmgr.c | 20 ++++++++++ 6 files changed, 78 insertions(+), 7 deletions(-) diff --git a/media_driver/linux/common/ddi/media_libva.cpp b/media_driver/linux/common/ddi/media_libva.cpp index 19769e26f32..c1d941115ff 100644 --- a/media_driver/linux/common/ddi/media_libva.cpp +++ b/media_driver/linux/common/ddi/media_libva.cpp @@ -5770,13 +5770,9 @@ VAStatus DdiMedia_ExportSurfaceHandle( DDI_CHK_NULL(mediaSurface->bo, "nullptr mediaSurface->bo", VA_STATUS_ERROR_INVALID_SURFACE); DDI_CHK_NULL(mediaSurface->pGmmResourceInfo, "nullptr mediaSurface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_SURFACE); - int32_t ret = mos_bo_gem_export_to_prime(mediaSurface->bo, (int32_t*)&mediaSurface->name); - if (ret) - { - //LOGE("Failed drm_intel_gem_export_to_prime operation!!!\n"); - return VA_STATUS_ERROR_OPERATION_FAILED; - } uint32_t tiling, swizzle; + int32_t ret; + if(mos_bo_get_tiling(mediaSurface->bo,&tiling, &swizzle)) { tiling = I915_TILING_NONE; @@ -5787,6 +5783,36 @@ VAStatus DdiMedia_ExportSurfaceHandle( { return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; } + + if (mediaSurface->pBoShadow && (desc->fourcc == VA_FOURCC_NV12)) + { + drm_intel_bo_switch(mediaSurface->bo, mediaSurface->pBoShadow, mediaSurface->pGmmResourceInfo->GetBaseHeight() * 3 / 2, mediaSurface->pGmmResourceInfo->GetRenderPitch()); + mos_bo_map(mediaSurface->pBoShadow, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY)); + mediaSurface->bBoShadowMapped = true; + +#if 0 + FILE *fp = fopen("umd_dump_boshadow.yuv", "ab+"); + fwrite(mediaSurface->pBoShadow->virt, mediaSurface->pGmmResourceInfo->GetBaseHeight() * mediaSurface->pGmmResourceInfo->GetRenderPitch() * 3 / 2, 1, fp); + fclose(fp); +#endif + ret = mos_bo_gem_export_to_prime(mediaSurface->pBoShadow, (int32_t*)&mediaSurface->name); + if (ret) + { + DDI_ASSERTMESSAGE("Failed drm_intel_gem_export_to_prime bo shadow operation!!!"); + return VA_STATUS_ERROR_OPERATION_FAILED; + } + } + else + { + + ret = mos_bo_gem_export_to_prime(mediaSurface->bo, (int32_t*)&mediaSurface->name); + if (ret) + { + DDI_ASSERTMESSAGE("Failed drm_intel_gem_export_to_prime bo operation!!!") + return VA_STATUS_ERROR_OPERATION_FAILED; + } + } + desc->width = mediaSurface->iWidth; desc->height = mediaSurface->iHeight; diff --git a/media_driver/linux/common/ddi/media_libva_common.h b/media_driver/linux/common/ddi/media_libva_common.h index 09f40f322c7..18338b5ece2 100644 --- a/media_driver/linux/common/ddi/media_libva_common.h +++ b/media_driver/linux/common/ddi/media_libva_common.h @@ -255,7 +255,9 @@ typedef struct _DDI_MEDIA_SURFACE uint32_t isTiled; uint32_t TileType; uint32_t bMapped; + uint32_t bBoShadowMapped; MOS_LINUX_BO *bo; + MOS_LINUX_BO *pBoShadow; uint32_t name; uint32_t surfaceUsageHint; PDDI_MEDIA_SURFACE_DESCRIPTOR pSurfDesc; // nullptr means surface was allocated by media driver diff --git a/media_driver/linux/common/ddi/media_libva_util.cpp b/media_driver/linux/common/ddi/media_libva_util.cpp index bd35a3ebd97..670e6cbf092 100644 --- a/media_driver/linux/common/ddi/media_libva_util.cpp +++ b/media_driver/linux/common/ddi/media_libva_util.cpp @@ -291,6 +291,7 @@ VAStatus DdiMediaUtil_AllocateSurface( { int32_t pitch = 0; MOS_LINUX_BO *bo = nullptr; + MOS_LINUX_BO *boShadow = nullptr; GMM_RESCREATE_PARAMS gmmParams; GMM_RESOURCE_INFO *gmmResourceInfo; bool grallocAllocation; @@ -556,6 +557,8 @@ VAStatus DdiMediaUtil_AllocateSurface( { bo = mos_bo_alloc_tiled(mediaDrvCtx->pDrmBufMgr, "MEDIA", gmmPitch, gmmSize/gmmPitch, 1, &tileformat, (unsigned long *)&ulPitch, 0); pitch = (int32_t)ulPitch; + + boShadow = mos_bo_alloc(mediaDrvCtx->pDrmBufMgr, "MEDIA", gmmSize, 4096); } } } @@ -592,6 +595,8 @@ VAStatus DdiMediaUtil_AllocateSurface( } mediaSurface->bMapped = false; + mediaSurface->bBoShadowMapped = false; + if (bo) { mediaSurface->format = format; @@ -601,6 +606,7 @@ VAStatus DdiMediaUtil_AllocateSurface( mediaSurface->iPitch = pitch; mediaSurface->iRefCount = 0; mediaSurface->bo = bo; + mediaSurface->pBoShadow = boShadow; mediaSurface->TileType = tileformat; mediaSurface->isTiled = (tileformat != I915_TILING_NONE) ? 1 : 0; mediaSurface->pData = (uint8_t*) bo->virt; @@ -1090,7 +1096,14 @@ void DdiMediaUtil_FreeSurface(DDI_MEDIA_SURFACE *surface) DdiMediaUtil_UnlockSurface(surface); DDI_VERBOSEMESSAGE("DDI: try to free a locked surface."); } + if (surface->bBoShadowMapped) + { + mos_bo_unmap(surface->pBoShadow); + surface->pBoShadow->virt = nullptr; + } + mos_bo_unreference(surface->pBoShadow); mos_bo_unreference(surface->bo); + surface->pBoShadow = nullptr; surface->bo = nullptr; } diff --git a/media_driver/linux/common/os/libdrm/include/i915_drm.h b/media_driver/linux/common/os/libdrm/include/i915_drm.h index 28d815ef293..f44b27ed7af 100644 --- a/media_driver/linux/common/os/libdrm/include/i915_drm.h +++ b/media_driver/linux/common/os/libdrm/include/i915_drm.h @@ -268,6 +268,7 @@ struct drm_i915_cmd_parser_append { #define DRM_I915_GEM_CONTEXT_GETPARAM 0x34 #define DRM_I915_GEM_CONTEXT_SETPARAM 0x35 #define DRM_I915_PERFMON 0x3e +#define DRM_I915_GEM_BO_SWITCH 0x40 #ifndef ANDROID #define DRM_I915_LOAD_BALANCING_HINT 0x3f @@ -329,6 +330,7 @@ struct drm_i915_cmd_parser_append { #define DRM_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr) #define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param) #define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param) +#define DRM_IOCTL_I915_GEM_BO_SWITCH DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BO_SWITCH, struct drm_i915_bo_switch) #ifndef ANDROID #define DRM_IOCTL_I915_LOAD_BALANCING_HINT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_LOAD_BALANCING_HINT, struct drm_i915_ring_load_query) @@ -1375,4 +1377,12 @@ typedef struct drm_i915_ring_load_query drm_i915_ring_load_info *load_info; } drm_i915_ring_load_query; +struct drm_i915_bo_switch { + __u32 handle_tiled; + __u32 handle_linear; + __u32 flags; + __u32 height; + __u32 width; +}; + #endif /* _I915_DRM_H_ */ 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 70fe3dae7f6..c48facee408 100644 --- a/media_driver/linux/common/os/libdrm/include/mos_bufmgr.h +++ b/media_driver/linux/common/os/libdrm/include/mos_bufmgr.h @@ -310,7 +310,7 @@ int mos_gem_bo_context_fence_exec(struct mos_linux_bo *bo, struct mos_linux_cont int mos_bo_gem_export_to_prime(struct mos_linux_bo *bo, int *prime_fd); struct mos_linux_bo *mos_bo_gem_create_from_prime(struct mos_bufmgr *bufmgr, int prime_fd, int size); - +int drm_intel_bo_switch(struct mos_linux_bo *bo_tiled, struct mos_linux_bo *bo_linear, uint32_t height, uint32_t width); /* drm_intel_bufmgr_fake.c */ struct mos_bufmgr *mos_bufmgr_fake_init(int fd, unsigned long low_offset, diff --git a/media_driver/linux/common/os/libdrm/mos_bufmgr.c b/media_driver/linux/common/os/libdrm/mos_bufmgr.c index 9aea16873a5..c4e17baa7c9 100644 --- a/media_driver/linux/common/os/libdrm/mos_bufmgr.c +++ b/media_driver/linux/common/os/libdrm/mos_bufmgr.c @@ -4111,6 +4111,26 @@ mos_bo_gem_export_to_prime(struct mos_linux_bo *bo, int *prime_fd) return 0; } +int drm_intel_bo_switch(struct mos_linux_bo *bo_tiled, struct mos_linux_bo *bo_linear, uint32_t height, uint32_t width) +{ + struct mos_bufmgr_gem *bufmgr_gem_tiled = (struct mos_bufmgr_gem *) bo_tiled->bufmgr; + struct mos_bo_gem *bo_gem_tiled = (struct mos_bo_gem *) bo_tiled; + struct mos_bo_gem *bo_gem_linear = (struct mos_bo_gem *) bo_linear; + struct drm_i915_bo_switch args; + int ret; + + args.handle_tiled = bo_gem_tiled->gem_handle; + args.handle_linear = bo_gem_linear->gem_handle; + args.flags = 0; //will use in later + args.height = height; + args.width = width; + ret = drmIoctl(bufmgr_gem_tiled->fd, DRM_IOCTL_I915_GEM_BO_SWITCH, &args); + if (ret) + return ret; + + return 0; +} + static int mos_gem_bo_flink(struct mos_linux_bo *bo, uint32_t * name) {