blob: 58c4de455e8acc57d5edef82ae7c2dc7679f138a [file] [log] [blame]
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//!
//! \file media_scalability.cpp
//! \brief Defines the common interface for media scalability
//! \details The media scalability interface is further sub-divided by component,
//! this file is for the base interface which is shared by all components.
//!
#include "media_scalability.h"
#include "mos_os_virtualengine.h"
MediaScalability::MediaScalability(MediaContext *mediaContext) :
m_mediaContext(mediaContext)
{
if (m_mediaContext == nullptr)
{
SCALABILITY_ASSERTMESSAGE("mediaContext is null ptr! Construct MediaScalability failed!");
}
}
bool MediaScalability::IsScalabilityModeMatched(ScalabilityPars *params)
{
bool isMatched = false;
#if (_DEBUG || _RELEASE_INTERNAL)
if (m_osInterface == nullptr)
{
return false;
}
if (m_osInterface->bEnableDbgOvrdInVE)
{
isMatched = true;
}
else
#endif
{
isMatched = m_scalabilityOption->IsScalabilityOptionMatched(params);
}
return isMatched;
}
bool MediaScalability::IsScalabilityModeMatched(MediaScalabilityOption &scalabOption)
{
#if (_DEBUG || _RELEASE_INTERNAL)
if (m_osInterface == nullptr)
{
return false;
}
if (m_osInterface->bEnableDbgOvrdInVE)
{
return true;
}
else
#endif
{
return m_scalabilityOption->IsScalabilityOptionMatched(scalabOption);
}
}
bool MediaScalability::IsGpuCtxCreateOptionMatched(PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreateOption1, PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreateOption2)
{
bool isMatched = false;
//Current only need new GpuCtxCreateOption when LRCACount changed.
//It can be improved if needed.
if (gpuCtxCreateOption1->LRCACount == gpuCtxCreateOption2->LRCACount)
{
isMatched = true;
}
return isMatched;
}
MOS_STATUS MediaScalability::VerifySpaceAvailable(uint32_t requestedSize, uint32_t requestedPatchListSize, bool &singleTaskPhaseSupportedInPak)
{
SCALABILITY_FUNCTION_ENTER;
SCALABILITY_CHK_NULL_RETURN(m_osInterface);
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MOS_STATUS statusPatchList = MOS_STATUS_SUCCESS;
MOS_STATUS statusCmdBuf = MOS_STATUS_SUCCESS;
// Try a maximum of 3 attempts to request the required sizes from OS
// OS could reset the sizes if necessary, therefore, requires to re-verify
for (auto i = 0; i < 3; i++)
{
//Experiment shows resizing CmdBuf size and PatchList size in two calls one after the other would cause previously
//successfully requested size to fallback to wrong value, hence never satisfying the requirement. So we call pfnResize()
//only once depending on whether CmdBuf size not enough, or PatchList size not enough, or both.
if (requestedPatchListSize)
{
statusPatchList = (MOS_STATUS)m_osInterface->pfnVerifyPatchListSize(
m_osInterface,
requestedPatchListSize);
}
statusCmdBuf = (MOS_STATUS)m_osInterface->pfnVerifyCommandBufferSize(
m_osInterface,
requestedSize,
0);
if (statusPatchList != MOS_STATUS_SUCCESS && statusCmdBuf != MOS_STATUS_SUCCESS)
{
SCALABILITY_CHK_STATUS_RETURN(ResizeCommandBufferAndPatchList(requestedSize + COMMAND_BUFFER_RESERVED_SPACE, requestedPatchListSize));
}
else if (statusPatchList != MOS_STATUS_SUCCESS)
{
SCALABILITY_CHK_STATUS_RETURN(ResizeCommandBufferAndPatchList(0, requestedPatchListSize));
}
else if (statusCmdBuf != MOS_STATUS_SUCCESS)
{
SCALABILITY_CHK_STATUS_RETURN(ResizeCommandBufferAndPatchList(requestedSize + COMMAND_BUFFER_RESERVED_SPACE, 0));
}
else
{
// This flag is just a hint for encode, decode/vpp don't use this flag.
singleTaskPhaseSupportedInPak = true;
return eStatus;
}
}
if (requestedPatchListSize)
{
statusPatchList = (MOS_STATUS)m_osInterface->pfnVerifyPatchListSize(
m_osInterface,
requestedPatchListSize);
}
statusCmdBuf = (MOS_STATUS)m_osInterface->pfnVerifyCommandBufferSize(
m_osInterface,
requestedSize,
0);
if(statusPatchList != MOS_STATUS_SUCCESS || statusCmdBuf != MOS_STATUS_SUCCESS)
{
eStatus = MOS_STATUS_NO_SPACE;
}
return eStatus;
}
MOS_STATUS MediaScalability::Destroy()
{
if (m_osInterface->apoMosEnabled)
{
if (m_veState)
{
SCALABILITY_CHK_STATUS_RETURN(MosInterface::SetVirtualEngineState(m_osInterface->osStreamState, m_veState));
return MosInterface::DestroyVirtualEngineState(m_osInterface->osStreamState);
}
// No VE state to destroy in some scalability instances
return MOS_STATUS_SUCCESS;
}
if (m_veInterface)
{
if(m_veInterface->pfnVEDestroy)
{
m_veInterface->pfnVEDestroy(m_veInterface);
}
MOS_FreeMemAndSetNull(m_veInterface);
}
else
{
// For VE not enabled/supported case, such as vp vebox on some platform, m_veInterface is nullptr.
// MOS_STATUS_SUCCESS should be returned for such case.
if (MOS_VE_SUPPORTED(m_osInterface))
{
SCALABILITY_CHK_NULL_RETURN(m_veInterface);
}
}
return MOS_STATUS_SUCCESS;
}