diff --git a/media_driver/linux/common/ddi/media_libva.cpp b/media_driver/linux/common/ddi/media_libva.cpp index 19769e26f32..7c8eb6d3685 100644 --- a/media_driver/linux/common/ddi/media_libva.cpp +++ b/media_driver/linux/common/ddi/media_libva.cpp @@ -4327,6 +4327,41 @@ VAStatus DdiMedia_SetImagePalette( return VA_STATUS_ERROR_UNIMPLEMENTED; } +VAStatus SwizzleSurface(PDDI_MEDIA_CONTEXT mediaCtx, PGMM_RESOURCE_INFO pGmmResInfo, void *pLockedAddr, uint32_t TileType, uint8_t* pResourceBase, bool bUpload) +{ + uint32_t uiSize, uiPitch; + GMM_RES_COPY_BLT gmmResCopyBlt; + uint32_t uiPicHeight; + uint32_t ulSwizzledSize; + VAStatus vaStatus = VA_STATUS_SUCCESS; + + DDI_CHK_NULL(pGmmResInfo, "pGmmResInfo is NULL", VA_STATUS_ERROR_OPERATION_FAILED); + DDI_CHK_NULL(pLockedAddr, "pLockedAddr is NULL", VA_STATUS_ERROR_OPERATION_FAILED); + DDI_CHK_NULL(pResourceBase, "pResourceBase is NULL", VA_STATUS_ERROR_ALLOCATION_FAILED); + + memset(&gmmResCopyBlt, 0x0, sizeof(GMM_RES_COPY_BLT)); + uiPicHeight = pGmmResInfo->GetBaseHeight(); + uiSize = pGmmResInfo->GetSizeSurface(); + uiPitch = pGmmResInfo->GetRenderPitch(); + gmmResCopyBlt.Gpu.pData = pLockedAddr; + gmmResCopyBlt.Sys.pData = pResourceBase; + gmmResCopyBlt.Sys.RowPitch = uiPitch; + gmmResCopyBlt.Sys.BufferSize = uiSize; + gmmResCopyBlt.Sys.SlicePitch = uiSize; + gmmResCopyBlt.Blt.Slices = 1; + gmmResCopyBlt.Blt.Upload = bUpload; + + if(mediaCtx->pGmmClientContext->IsPlanar(pGmmResInfo->GetResourceFormat()) == true) + { + gmmResCopyBlt.Blt.Width = pGmmResInfo->GetBaseWidth(); + gmmResCopyBlt.Blt.Height = uiSize/uiPitch; + } + + pGmmResInfo->CpuBlt(&gmmResCopyBlt); + + return vaStatus; +} + //! //! \brief Retrive surface data into a VAImage //! \details Image must be in a format supported by the implementation @@ -4424,7 +4459,7 @@ VAStatus DdiMedia_GetImage( DDI_CHK_NULL(mediaSurface->bo, "nullptr mediaSurface->bo.", VA_STATUS_ERROR_INVALID_PARAMETER); //Lock Surface - void *surfData = DdiMediaUtil_LockSurface(mediaSurface, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY)); + void *surfData = DdiMediaUtil_LockSurface(mediaSurface, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_NO_SWIZZLE)); if (surfData == nullptr) { DDI_ASSERTMESSAGE("nullptr surfData."); @@ -4448,8 +4483,16 @@ VAStatus DdiMedia_GetImage( } //Copy data from surface to image - MOS_STATUS eStatus = MOS_SecureMemcpy(imageData, vaimg->data_size, surfData, vaimg->data_size); - if (eStatus != MOS_STATUS_SUCCESS) + if(mediaSurface->TileType == I915_TILING_NONE) + { + vaStatus = MOS_SecureMemcpy(imageData, vaimg->data_size, surfData, vaimg->data_size); + } + else + { + //Mos_SwizzleData((uint8_t*)surfData, (uint8_t *)imageData, (MOS_TILE_TYPE)mediaSurface->TileType, MOS_TILE_LINEAR, vaimg->data_size / mediaSurface->iPitch, mediaSurface->iPitch, mediaSurface->uiMapFlag); + vaStatus = SwizzleSurface(mediaSurface->pMediaCtx,mediaSurface->pGmmResourceInfo, surfData, (MOS_TILE_TYPE)mediaSurface->TileType, (uint8_t *)imageData, false); + } + if (vaStatus != MOS_STATUS_SUCCESS) { DDI_ASSERTMESSAGE("DDI:Failed to copy surface to image buffer data!"); DdiMediaUtil_UnlockSurface(mediaSurface); diff --git a/media_driver/linux/common/ddi/media_libva_common.h b/media_driver/linux/common/ddi/media_libva_common.h index 09f40f322c7..4072b9abd2c 100644 --- a/media_driver/linux/common/ddi/media_libva_common.h +++ b/media_driver/linux/common/ddi/media_libva_common.h @@ -274,6 +274,8 @@ typedef struct _DDI_MEDIA_SURFACE PMEDIA_SEM_T pReferenceFrameSemaphore; // to sync reference frame surface. when this semaphore is posted, the surface is not used as reference frame, and safe to be destroied uint8_t *pSystemShadow; // Shadow surface in system memory + + uint32_t uiMapFlag; } DDI_MEDIA_SURFACE, *PDDI_MEDIA_SURFACE; typedef struct _DDI_MEDIA_BUFFER diff --git a/media_driver/linux/common/ddi/media_libva_util.cpp b/media_driver/linux/common/ddi/media_libva_util.cpp index bd35a3ebd97..1c37ea3b1ca 100644 --- a/media_driver/linux/common/ddi/media_libva_util.cpp +++ b/media_driver/linux/common/ddi/media_libva_util.cpp @@ -884,12 +884,17 @@ void* DdiMediaUtil_LockSurface(DDI_MEDIA_SURFACE *surface, uint32_t flag) { mos_gem_bo_map_gtt(surface->bo); } + else if (flag & MOS_LOCKFLAG_NO_SWIZZLE) + { + mos_bo_map(surface->bo, flag & MOS_LOCKFLAG_READONLY); + } else { mos_gem_bo_map_unsynchronized(surface->bo); // only call mmap_gtt ioctl mos_gem_bo_start_gtt_access(surface->bo, 0); // set to GTT domain,0 means readonly } } + surface->uiMapFlag = flag; surface->pData = surface->pSystemShadow ? surface->pSystemShadow : (uint8_t*) surface->bo->virt; surface->bMapped = true; } @@ -944,6 +949,10 @@ void DdiMediaUtil_UnlockSurface(DDI_MEDIA_SURFACE *surface) mos_bo_unmap(surface->bo); } + else if(surface->uiMapFlag & MOS_LOCKFLAG_NO_SWIZZLE) + { + mos_bo_unmap(surface->bo); + } else { mos_gem_bo_unmap_gtt(surface->bo); diff --git a/media_driver/linux/common/os/mos_os_specific.h b/media_driver/linux/common/os/mos_os_specific.h index 4f74572cac3..ca1acf614b7 100644 --- a/media_driver/linux/common/os/mos_os_specific.h +++ b/media_driver/linux/common/os/mos_os_specific.h @@ -103,6 +103,7 @@ enum DdiSurfaceFormat #define MOS_LOCKFLAG_WRITEONLY OSKM_LOCKFLAG_WRITEONLY #define MOS_LOCKFLAG_READONLY OSKM_LOCKFLAG_READONLY #define MOS_LOCKFLAG_NOOVERWRITE OSKM_LOCKFLAG_NOOVERWRITE +#define MOS_LOCKFLAG_NO_SWIZZLE OSKM_LOCKFLAG_NO_SWIZZLE #define MOS_DIR_SEPERATOR '/' @@ -117,6 +118,7 @@ enum DdiSurfaceFormat #define OSKM_LOCKFLAG_WRITEONLY 0x00000001 #define OSKM_LOCKFLAG_READONLY 0x00000002 #define OSKM_LOCKFLAG_NOOVERWRITE 0x00000004 +#define OSKM_LOCKFLAG_NO_SWIZZLE 0x00000008 // should be defined in libdrm, this is a temporary solution to pass QuickBuild #define I915_EXEC_VEBOX (4<<0)