Skip to content

Commit

Permalink
[Encode] Fix AVC page fault issue
Browse files Browse the repository at this point in the history
Fix AVC page fault issue due to input surface is 16-unaligned.
  • Loading branch information
walter-bai authored and intel-mediadev committed Oct 20, 2023
1 parent 9124262 commit ac85904
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ class AvcBasicFeatureXe_Lpm_Plus_Base : public AvcBasicFeature
CodechalHwInterfaceNext *hwInterface,
TrackedBuffer *trackedBuf,
RecycleResource *recycleBuf,
MediaCopyWrapper *mediaCopyWrapper,
void *constSettings = nullptr) :
AvcBasicFeature(allocator, hwInterface, trackedBuf, recycleBuf, constSettings) {}
AvcBasicFeature(allocator, hwInterface, trackedBuf, recycleBuf, mediaCopyWrapper, constSettings) {}

virtual ~AvcBasicFeatureXe_Lpm_Plus_Base() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ MOS_STATUS EncodeAvcVdencFeatureManagerXe_Lpm_Plus_Base::CreateFeatures(void *co
ENCODE_CHK_NULL_RETURN(setting);
setting->SetOsInterface(m_hwInterface->GetOsInterface());

EncodeBasicFeature *encBasic = MOS_New(AvcBasicFeatureXe_Lpm_Plus_Base, m_allocator, m_hwInterface, m_trackedBuf, m_recycleResource, constSettings);
EncodeBasicFeature *encBasic = MOS_New(AvcBasicFeatureXe_Lpm_Plus_Base, m_allocator, m_hwInterface, m_trackedBuf, m_recycleResource, m_mediaCopyWrapper, constSettings);
ENCODE_CHK_STATUS_RETURN(RegisterFeatures(AvcFeatureIDs::basicFeature, encBasic, {AvcVdencPipeline::encodePreEncPacket}));

AvcVdencStreamInFeature *streamInFeature = MOS_New(AvcVdencStreamInFeature, this, m_allocator, m_hwInterface, constSettings);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ class EncodeAvcVdencFeatureManagerXe_Lpm_Plus_Base : public EncodeAvcVdencFeatur
EncodeAllocator *allocator,
CodechalHwInterfaceNext *hwInterface,
TrackedBuffer *trackedBuf,
RecycleResource *recycleBuf) :
EncodeAvcVdencFeatureManager(allocator, hwInterface, trackedBuf, recycleBuf) {}
RecycleResource *recycleBuf,
MediaCopyWrapper *mediaCopyWrapper) :
EncodeAvcVdencFeatureManager(allocator, hwInterface, trackedBuf, recycleBuf, mediaCopyWrapper) {}

virtual ~EncodeAvcVdencFeatureManagerXe_Lpm_Plus_Base() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ MOS_STATUS AvcVdencPipelineXe_Lpm_Plus_Base::CreateFeatureManager()
{
ENCODE_FUNC_CALL();

m_featureManager = MOS_New(EncodeAvcVdencFeatureManagerXe_Lpm_Plus_Base, m_allocator, m_hwInterface, m_trackedBuf, m_recycleBuf);
m_featureManager = MOS_New(EncodeAvcVdencFeatureManagerXe_Lpm_Plus_Base, m_allocator, m_hwInterface, m_trackedBuf, m_recycleBuf, m_mediaCopyWrapper);
ENCODE_CHK_NULL_RETURN(m_featureManager);

return MOS_STATUS_SUCCESS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,47 @@ MOS_STATUS AvcBasicFeature::PackPictureHeader()
return MOS_STATUS_SUCCESS;
}

bool AvcBasicFeature::InputSurfaceNeedsExtraCopy(const MOS_SURFACE &input)
{
#if _DEBUG || _RELEASE_INTERNAL
static int8_t supported = -1;

if (supported == -1)
{
MediaUserSetting::Value outValue{};

ReadUserSettingForDebug(
m_userSettingPtr,
outValue,
"DisableInputSurfaceCopy",
MediaUserSetting::Group::Sequence);

supported = !outValue.Get<bool>();
}

if (!supported)
{
return false;
}
#endif

uint32_t alignedSize = 0;
switch (input.Format)
{
case Format_NV12:
alignedSize = (m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH) * (m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT) * 3 / 2;
break;
case Format_A8R8G8B8:
alignedSize = (m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH) * (m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT) * 4;
break;
default:
alignedSize = 0;
break;
}

return input.dwSize < alignedSize;
}

MOS_STATUS AvcBasicFeature::UpdateTrackedBufferParameters()
{
uint32_t fieldNumMBs = (uint32_t)m_picWidthInMb * ((m_picHeightInMb + 1) >> 1);
Expand Down Expand Up @@ -655,6 +696,19 @@ MOS_STATUS AvcBasicFeature::UpdateTrackedBufferParameters()
m_allocator->UnLock(m_colocatedMVBufferForIFrames);
}

// Input surface copy is needed if height is not MB aligned
if (InputSurfaceNeedsExtraCopy(m_rawSurface))
{
MOS_ALLOC_GFXRES_PARAMS allocParamsForAlignedRawSurface{};
allocParamsForAlignedRawSurface.Type = MOS_GFXRES_2D;
allocParamsForAlignedRawSurface.Format = m_rawSurface.Format;
allocParamsForAlignedRawSurface.TileType = MOS_TILE_Y;
allocParamsForAlignedRawSurface.dwWidth = m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH;
allocParamsForAlignedRawSurface.dwHeight = m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
allocParamsForAlignedRawSurface.pBufName = "Aligned Raw Surface";
ENCODE_CHK_STATUS_RETURN(m_trackedBuf->RegisterParam(BufferType::AlignedRawSurface, allocParamsForAlignedRawSurface));
}

ENCODE_CHK_STATUS_RETURN(EncodeBasicFeature::UpdateTrackedBufferParameters());

return MOS_STATUS_SUCCESS;
Expand Down Expand Up @@ -886,6 +940,31 @@ MOS_STATUS AvcBasicFeature::GetTrackedBuffers()
ENCODE_CHK_NULL_RETURN(m_4xDSSurface);
ENCODE_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(m_4xDSSurface));

// Input surface copy is needed if height is not MB aligned
if (InputSurfaceNeedsExtraCopy(m_rawSurface))
{
auto alignedRawSurf = m_trackedBuf->GetSurface(BufferType::AlignedRawSurface, m_trackedBuf->GetCurrIndex());
ENCODE_CHK_NULL_RETURN(alignedRawSurf);
m_allocator->GetSurfaceInfo(alignedRawSurf);
alignedRawSurf->OsResource.pGmmResInfo->GetSetCpSurfTag(true, m_rawSurface.OsResource.pGmmResInfo->GetSetCpSurfTag(false, 0));
ENCODE_CHK_STATUS_RETURN(m_allocator->UpdateResourceUsageType(&alignedRawSurf->OsResource, MOS_HW_RESOURCE_USAGE_ENCODE_INPUT_RAW));

if (m_mediaCopyWrapper)
{
ENCODE_CHK_STATUS_RETURN(m_mediaCopyWrapper->MediaCopy(
&m_rawSurface.OsResource,
&alignedRawSurf->OsResource,
MCPY_METHOD_DEFAULT));

m_rawSurface = *alignedRawSurf;
m_rawSurfaceToEnc = m_rawSurfaceToPak = &m_rawSurface;
}
else
{
ENCODE_ASSERTMESSAGE("Input surface height %d is not 16-aligned, needs extra copy but MediaCopy is not avaliable.", m_rawSurface.dwHeight);
}
}

return MOS_STATUS_SUCCESS;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "mhw_vdbox_mfx_itf.h"
#include "mhw_vdbox_huc_itf.h"
#include "encode_mem_compression.h"
#include "media_copy_wrapper.h"
#include "codechal_debug.h"

namespace encode
Expand Down Expand Up @@ -103,8 +104,10 @@ class AvcBasicFeature : public EncodeBasicFeature,
CodechalHwInterfaceNext *hwInterface,
TrackedBuffer *trackedBuf,
RecycleResource *recycleBuf,
MediaCopyWrapper *mediaCopyWrapper,
void *constSettings = nullptr) :
EncodeBasicFeature(allocator, hwInterface, trackedBuf, recycleBuf) {m_constSettings = constSettings;}
EncodeBasicFeature(allocator, hwInterface, trackedBuf, recycleBuf),
m_mediaCopyWrapper(mediaCopyWrapper) { m_constSettings = constSettings; }

virtual ~AvcBasicFeature();

Expand Down Expand Up @@ -246,6 +249,7 @@ class AvcBasicFeature : public EncodeBasicFeature,
MOS_STATUS SetSliceStructs();
void CheckResolutionChange();
MOS_STATUS PackPictureHeader();
bool InputSurfaceNeedsExtraCopy(const MOS_SURFACE& input);

virtual MOS_STATUS UpdateTrackedBufferParameters() override;
virtual MOS_STATUS GetTrackedBuffers() override;
Expand Down Expand Up @@ -292,6 +296,8 @@ class AvcBasicFeature : public EncodeBasicFeature,
uint32_t m_seiDataOffset = false; //!< Encode SEI data offset.
uint8_t * m_seiParamBuffer = nullptr; //!< Encode SEI data buffer.

MediaCopyWrapper *m_mediaCopyWrapper = nullptr;

MEDIA_CLASS_DEFINE_END(encode__AvcBasicFeature)
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "encode_recycle_resource.h"
#include "encode_tracked_buffer.h"
#include "codec_def_encode_avc.h"
#include "media_copy_wrapper.h"

namespace encode
{
Expand All @@ -55,11 +56,13 @@ class EncodeAvcVdencFeatureManager : public EncodeFeatureManager
EncodeAvcVdencFeatureManager(EncodeAllocator *allocator,
CodechalHwInterfaceNext *hwInterface,
TrackedBuffer *trackedBuf,
RecycleResource *recycleBuf):
RecycleResource *recycleBuf,
MediaCopyWrapper *mediaCopyWrapper) :
m_allocator(allocator),
m_hwInterface(hwInterface),
m_recycleResource(recycleBuf),
m_trackedBuf(trackedBuf) {}
m_trackedBuf(trackedBuf),
m_mediaCopyWrapper(mediaCopyWrapper) {}

//!
//! \brief EncodeAvcVdencFeatureManager deconstructor
Expand Down Expand Up @@ -93,6 +96,7 @@ class EncodeAvcVdencFeatureManager : public EncodeFeatureManager
CodechalHwInterfaceNext *m_hwInterface = nullptr;
RecycleResource *m_recycleResource = nullptr;
TrackedBuffer *m_trackedBuf = nullptr;
MediaCopyWrapper *m_mediaCopyWrapper = nullptr;

MEDIA_CLASS_DEFINE_END(encode__EncodeAvcVdencFeatureManager)
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ MOS_STATUS AvcVdencPipeline::InitUserSetting(MediaUserSettingSharedPtr userSetti
MediaUserSetting::Group::Sequence,
"",
false);

DeclareUserSettingKeyForDebug(
userSettingPtr,
"DisableInputSurfaceCopy",
MediaUserSetting::Group::Sequence,
"",
false);
#endif
return MOS_STATUS_SUCCESS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ enum class BufferType
superResRef8xDsScaled,
preencRef0,
preencRef1,
AlignedRawSurface,
};

struct MapBufferResourceType
Expand Down Expand Up @@ -231,6 +232,7 @@ class TrackedBuffer
{BufferType::superResRefScaled, ResourceType::surfaceResource},
{BufferType::superResRef4xDsScaled, ResourceType::surfaceResource},
{BufferType::superResRef8xDsScaled, ResourceType::surfaceResource},
{BufferType::AlignedRawSurface, ResourceType::surfaceResource},
};

uint8_t m_maxSlotCnt = 0; //!< max slot count in the tracked buffer
Expand Down

0 comments on commit ac85904

Please sign in to comment.