diff --git a/media_driver/agnostic/common/codec/hal/codechal_vdenc_vp9_base.cpp b/media_driver/agnostic/common/codec/hal/codechal_vdenc_vp9_base.cpp index dd2cc19e73..8e6821daf9 100644 --- a/media_driver/agnostic/common/codec/hal/codechal_vdenc_vp9_base.cpp +++ b/media_driver/agnostic/common/codec/hal/codechal_vdenc_vp9_base.cpp @@ -7934,3 +7934,150 @@ MOS_STATUS CodechalVdencVp9State::DumpSegmentParams( return MOS_STATUS_SUCCESS; } #endif + +void CodechalVdencVp9State::fill_pad_with_value(PMOS_SURFACE psSurface, uint32_t real_height, uint32_t aligned_height) +{ + CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(psSurface); + + // unaligned surfaces only + if (aligned_height <= real_height || aligned_height > psSurface->dwHeight) + { + return; + } + + // avoid DYS frames cases + if (m_dysRefFrameFlags != DYS_REF_NONE && m_dysVdencMultiPassEnabled) + { + return; + } + + if (psSurface->Format == Format_NV12 || psSurface->Format == Format_P010) + { + uint32_t pitch = psSurface->dwPitch; + uint32_t UVPlaneOffset = psSurface->UPlaneOffset.iSurfaceOffset; + uint32_t YPlaneOffset = psSurface->dwOffset; + uint32_t pad_rows = aligned_height - real_height; + uint32_t y_plane_size = pitch * real_height; + uint32_t uv_plane_size = pitch * real_height / 2; + + MOS_LOCK_PARAMS lockFlags; + MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); + lockFlags.WriteOnly = 1; + + // padding for the linear format buffer. + if (psSurface->OsResource.TileType == MOS_TILE_LINEAR) + { + uint8_t *src_data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags); + + if (!src_data) + return; + + uint8_t *src_data_y = src_data + YPlaneOffset; + uint8_t *src_data_y_end = src_data_y + y_plane_size; + for (uint32_t i = 0; i < pad_rows; i++) + { + MOS_SecureMemcpy(src_data_y_end + i * pitch, pitch, src_data_y_end - pitch, pitch); + } + + uint8_t *src_data_uv = src_data + UVPlaneOffset; + uint8_t *src_data_uv_end = src_data_uv + uv_plane_size; + for (uint32_t i = 0; i < pad_rows / 2; i++) + { + MOS_SecureMemcpy(src_data_uv_end + i * pitch, pitch, src_data_uv_end - pitch, pitch); + } + + m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource)); + } + else if (psSurface->OsResource.TileType == MOS_TILE_Y) + { + // we don't copy out the tiled buffer to linear and padding on the tiled buffer directly. + lockFlags.TiledAsTiled = 1; + + uint8_t *src_data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags); + if (!src_data) + return; + + uint8_t* padding_data = (uint8_t *)MOS_AllocMemory(pitch); + CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(padding_data); + + int32_t LinearOffset; + int32_t TileOffset; + int32_t x; + int32_t y; + + int32_t swizzleflags = 0; // 0 for MOS_TILE_Y + + // copy out the last Y row data. + y = (YPlaneOffset + y_plane_size - pitch) / pitch; + for (x = 0, LinearOffset = 0; x < static_cast(pitch); x++, LinearOffset++) + { + TileOffset = Mos_SwizzleOffsetWrapper( + x, + y, + pitch, + MOS_TILE_Y, + false, + swizzleflags); + if (TileOffset < psSurface->OsResource.iSize) + *(padding_data + LinearOffset) = *(src_data + TileOffset); + } + + // padding the unaligned region for Y. + y = (YPlaneOffset + y_plane_size) / pitch; + for (uint32_t i = 0; i < pad_rows; y++, i++) + { + LinearOffset = 0; + for (x = 0; x < static_cast(pitch); x++, LinearOffset++) + { + TileOffset = Mos_SwizzleOffsetWrapper( + x, + y, + pitch, + MOS_TILE_Y, + false, + swizzleflags); + if (TileOffset < psSurface->OsResource.iSize) + *(src_data + TileOffset) = *(padding_data + LinearOffset); + } + } + + // copy out the last UV row data. + y = (UVPlaneOffset + uv_plane_size - pitch) / pitch; + for (x = 0, LinearOffset = 0; x < static_cast(pitch); x++, LinearOffset++) + { + TileOffset = Mos_SwizzleOffsetWrapper( + x, + y, + pitch, + MOS_TILE_Y, + false, + swizzleflags); + if (TileOffset < psSurface->OsResource.iSize) + *(padding_data + LinearOffset) = *(src_data + TileOffset); + } + + // padding the unaligned region for UV. + y = (UVPlaneOffset + uv_plane_size) / pitch; + for (uint32_t i = 0; i < pad_rows / 2; y++, i++) + { + LinearOffset = 0; + for (x = 0; x < static_cast(pitch); x++, LinearOffset++) + { + TileOffset = Mos_SwizzleOffsetWrapper( + x, + y, + pitch, + MOS_TILE_Y, + false, + swizzleflags); + if (TileOffset < psSurface->OsResource.iSize) + *(src_data + TileOffset) = *(padding_data + LinearOffset); + } + } + + MOS_FreeMemory(padding_data); + padding_data = nullptr; + m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource)); + } + } +} \ No newline at end of file diff --git a/media_driver/agnostic/common/codec/hal/codechal_vdenc_vp9_base.h b/media_driver/agnostic/common/codec/hal/codechal_vdenc_vp9_base.h index 962b0bf82a..17114ee11e 100644 --- a/media_driver/agnostic/common/codec/hal/codechal_vdenc_vp9_base.h +++ b/media_driver/agnostic/common/codec/hal/codechal_vdenc_vp9_base.h @@ -2415,6 +2415,8 @@ class CodechalVdencVp9State : public CodechalEncoderState MOS_STATUS DumpPicParams( PCODEC_VP9_ENCODE_PIC_PARAMS picParams); #endif + + void fill_pad_with_value(PMOS_SURFACE psSurface, uint32_t real_height, uint32_t aligned_height); }; #endif // __CODECHAL_VDENC_VP9_BASE_H__ diff --git a/media_driver/agnostic/gen11/codec/hal/codechal_vdenc_vp9_g11.cpp b/media_driver/agnostic/gen11/codec/hal/codechal_vdenc_vp9_g11.cpp index 2a11e4b958..aa8fc943bd 100644 --- a/media_driver/agnostic/gen11/codec/hal/codechal_vdenc_vp9_g11.cpp +++ b/media_driver/agnostic/gen11/codec/hal/codechal_vdenc_vp9_g11.cpp @@ -4376,6 +4376,14 @@ MOS_STATUS CodechalVdencVp9StateG11::ExecutePictureLevel() CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID])); } + if (MEDIA_IS_WA(m_waTable, Wa_Vp9UnalignedHeight)) + { + uint32_t real_height = m_oriFrameHeight; + uint32_t aligned_height = MOS_ALIGN_CEIL(real_height, CODEC_VP9_MIN_BLOCK_HEIGHT); + + fill_pad_with_value(m_rawSurfaceToPak, real_height, aligned_height); + } + // Golden reference picture if (refSurface[1]) { diff --git a/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_vp9_g12.cpp b/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_vp9_g12.cpp index d273e5e5ba..6a58c9ce68 100644 --- a/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_vp9_g12.cpp +++ b/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_vp9_g12.cpp @@ -3452,153 +3452,6 @@ MOS_STATUS CodechalVdencVp9StateG12::SetPictureStructs() return eStatus; } -void CodechalVdencVp9StateG12::fill_pad_with_value(PMOS_SURFACE psSurface, uint32_t real_height, uint32_t aligned_height) -{ - CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(psSurface); - - // unaligned surfaces only - if (aligned_height <= real_height || aligned_height > psSurface->dwHeight) - { - return; - } - - // avoid DYS frames cases - if (m_dysRefFrameFlags != DYS_REF_NONE && m_dysVdencMultiPassEnabled) - { - return; - } - - if (psSurface->Format == Format_NV12 || psSurface->Format == Format_P010) - { - uint32_t pitch = psSurface->dwPitch; - uint32_t UVPlaneOffset = psSurface->UPlaneOffset.iSurfaceOffset; - uint32_t YPlaneOffset = psSurface->dwOffset; - uint32_t pad_rows = aligned_height - real_height; - uint32_t y_plane_size = pitch * real_height; - uint32_t uv_plane_size = pitch * real_height / 2; - - MOS_LOCK_PARAMS lockFlags; - MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); - lockFlags.WriteOnly = 1; - - // padding for the linear format buffer. - if (psSurface->OsResource.TileType == MOS_TILE_LINEAR) - { - uint8_t *src_data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags); - - if (!src_data) - return; - - uint8_t *src_data_y = src_data + YPlaneOffset; - uint8_t *src_data_y_end = src_data_y + y_plane_size; - for (uint32_t i = 0; i < pad_rows; i++) - { - MOS_SecureMemcpy(src_data_y_end + i * pitch, pitch, src_data_y_end - pitch, pitch); - } - - uint8_t *src_data_uv = src_data + UVPlaneOffset; - uint8_t *src_data_uv_end = src_data_uv + uv_plane_size; - for (uint32_t i = 0; i < pad_rows / 2; i++) - { - MOS_SecureMemcpy(src_data_uv_end + i * pitch, pitch, src_data_uv_end - pitch, pitch); - } - - m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource)); - } - else if (psSurface->OsResource.TileType == MOS_TILE_Y) - { - // we don't copy out the tiled buffer to linear and padding on the tiled buffer directly. - lockFlags.TiledAsTiled = 1; - - uint8_t *src_data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags); - if (!src_data) - return; - - uint8_t* padding_data = (uint8_t *)MOS_AllocMemory(pitch); - CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(padding_data); - - int32_t LinearOffset; - int32_t TileOffset; - int32_t x; - int32_t y; - - int32_t swizzleflags = 0; // 0 for MOS_TILE_Y - - // copy out the last Y row data. - y = (YPlaneOffset + y_plane_size - pitch) / pitch; - for (x = 0, LinearOffset = 0; x < static_cast(pitch); x++, LinearOffset++) - { - TileOffset = Mos_SwizzleOffsetWrapper( - x, - y, - pitch, - MOS_TILE_Y, - false, - swizzleflags); - if (TileOffset < psSurface->OsResource.iSize) - *(padding_data + LinearOffset) = *(src_data + TileOffset); - } - - // padding the unaligned region for Y. - y = (YPlaneOffset + y_plane_size) / pitch; - for (uint32_t i = 0; i < pad_rows; y++, i++) - { - LinearOffset = 0; - for (x = 0; x < static_cast(pitch); x++, LinearOffset++) - { - TileOffset = Mos_SwizzleOffsetWrapper( - x, - y, - pitch, - MOS_TILE_Y, - false, - swizzleflags); - if (TileOffset < psSurface->OsResource.iSize) - *(src_data + TileOffset) = *(padding_data + LinearOffset); - } - } - - // copy out the last UV row data. - y = (UVPlaneOffset + uv_plane_size - pitch) / pitch; - for (x = 0, LinearOffset = 0; x < static_cast(pitch); x++, LinearOffset++) - { - TileOffset = Mos_SwizzleOffsetWrapper( - x, - y, - pitch, - MOS_TILE_Y, - false, - swizzleflags); - if (TileOffset < psSurface->OsResource.iSize) - *(padding_data + LinearOffset) = *(src_data + TileOffset); - } - - // padding the unaligned region for UV. - y = (UVPlaneOffset + uv_plane_size) / pitch; - for (uint32_t i = 0; i < pad_rows / 2; y++, i++) - { - LinearOffset = 0; - for (x = 0; x < static_cast(pitch); x++, LinearOffset++) - { - TileOffset = Mos_SwizzleOffsetWrapper( - x, - y, - pitch, - MOS_TILE_Y, - false, - swizzleflags); - if (TileOffset < psSurface->OsResource.iSize) - *(src_data + TileOffset) = *(padding_data + LinearOffset); - } - } - - MOS_FreeMemory(padding_data); - padding_data = nullptr; - m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource)); - } - } -} - MOS_STATUS CodechalVdencVp9StateG12::ExecutePictureLevel() { MOS_STATUS eStatus = MOS_STATUS_SUCCESS; diff --git a/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_vp9_g12.h b/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_vp9_g12.h index b612e61a5c..393704a9a3 100644 --- a/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_vp9_g12.h +++ b/media_driver/agnostic/gen12/codec/hal/codechal_vdenc_vp9_g12.h @@ -1314,6 +1314,5 @@ class CodechalVdencVp9StateG12 : public CodechalVdencVp9State PMOS_COMMAND_BUFFER cmdBuffer, uint32_t currPass); - void fill_pad_with_value(PMOS_SURFACE psSurface, uint32_t real_height, uint32_t aligned_height); }; #endif // __CODECHAL_VDENC_VP9_G12_H__ diff --git a/media_driver/linux/gen11/ddi/media_sku_wa_g11.cpp b/media_driver/linux/gen11/ddi/media_sku_wa_g11.cpp index c0d8551f7d..2e26bd1c4d 100644 --- a/media_driver/linux/gen11/ddi/media_sku_wa_g11.cpp +++ b/media_driver/linux/gen11/ddi/media_sku_wa_g11.cpp @@ -421,6 +421,7 @@ static bool InitEhlMediaWa(struct GfxDeviceInfo *devInfo, MEDIA_WR_WA(waTable, Wa16KInputHeightNV12Planar420, 1); MEDIA_WR_WA(waTable, WaDisableCodecMmc, 1); + MEDIA_WR_WA(waTable, Wa_Vp9UnalignedHeight, 1); /*Software workaround to disable the UV offset calculation by gmmlib CPU blt call will add/remove padding on the platform*/