blob: 3025a5311ac6ba1246286625c38804aaad1b0046 [file] [log] [blame]
/*
* Copyright (c) 2020, 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 vp_render_cmd_packet.cpp
//! \brief render packet which used in by mediapipline.
//! \details render packet provide the structures and generate the cmd buffer which mediapipline will used.
//!
#include "vp_render_cmd_packet.h"
#include "vp_platform_interface.h"
#include "vp_pipeline_common.h"
#include "vp_render_kernel_obj.h"
namespace vp {
static inline RENDERHAL_SURFACE_TYPE InitRenderHalSurfType(VPHAL_SURFACE_TYPE vpSurfType)
{
switch (vpSurfType)
{
case SURF_IN_BACKGROUND:
return RENDERHAL_SURF_IN_BACKGROUND;
case SURF_IN_PRIMARY:
return RENDERHAL_SURF_IN_PRIMARY;
case SURF_IN_SUBSTREAM:
return RENDERHAL_SURF_IN_SUBSTREAM;
case SURF_IN_REFERENCE:
return RENDERHAL_SURF_IN_REFERENCE;
case SURF_OUT_RENDERTARGET:
return RENDERHAL_SURF_OUT_RENDERTARGET;
case SURF_NONE:
default:
return RENDERHAL_SURF_NONE;
}
}
VpRenderCmdPacket::VpRenderCmdPacket(MediaTask* task, PVP_MHWINTERFACE hwInterface, PVpAllocator& allocator, VPMediaMemComp* mmc, VpKernelSet* kernelSet) :
CmdPacket(task),
RenderCmdPacket(task, hwInterface->m_osInterface, hwInterface->m_renderHal),
VpCmdPacket(task, hwInterface, allocator, mmc, VP_PIPELINE_PACKET_RENDER),
m_filter(nullptr),
m_firstFrame(true),
m_kernelSet(kernelSet)
{
}
MOS_STATUS VpRenderCmdPacket::Prepare()
{
VP_RENDER_CHK_NULL_RETURN(m_hwInterface);
VP_RENDER_CHK_NULL_RETURN(m_hwInterface->m_vpPlatformInterface);
m_PacketId = VP_PIPELINE_PACKET_RENDER;
//m_kernelCount = IDR_VP_TOTAL_NUM_KERNELS;
RENDER_KERNEL_PARAMS kernelParams;
MOS_ZeroMemory(&kernelParams, sizeof(RENDER_KERNEL_PARAMS));
kernelParams.kernelId = &m_kernelId;
kernelParams.surfacesGroup = &m_surfSetting.surfGroup;
VP_RENDER_CHK_STATUS_RETURN(m_kernelSet->CreateKernelObjects(kernelParams, m_kernelObjs));
// for multi-kernel prepare together
for (auto it = m_kernelObjs.begin(); it != m_kernelObjs.end(); it++)
{
m_kernel = it->second;
VP_RENDER_CHK_NULL_RETURN(m_kernel);
// reset render Data for current kernel
MOS_ZeroMemory(&m_renderData, sizeof(m_renderData));
VP_RENDER_CHK_STATUS_RETURN(RenderEngineSetup());
VP_RENDER_CHK_STATUS_RETURN(KernelStateSetup());
VP_RENDER_CHK_STATUS_RETURN(SetupSurfaceState()); // once Surface setup done, surface index should be created here
VP_RENDER_CHK_STATUS_RETURN(SetupCurbeState()); // Set Curbe with updated surface index
VP_RENDER_CHK_STATUS_RETURN(LoadKernel());
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpRenderCmdPacket::Submit(MOS_COMMAND_BUFFER* commandBuffer, uint8_t packetPhase)
{
if (m_kernelObjs.empty())
{
VP_RENDER_ASSERTMESSAGE("No Kernel Object Creation");
return MOS_STATUS_NULL_POINTER;
}
// for multi-kernel submit in one BB for prepared kernels
for (auto it = m_kernelObjs.begin(); it != m_kernelObjs.end(); it++)
{
VP_RENDER_CHK_STATUS_RETURN(SetupMediaWalker());
VP_RENDER_CHK_STATUS_RETURN(RenderCmdPacket::Submit(commandBuffer, packetPhase));
}
VP_RENDER_CHK_STATUS_RETURN(m_kernelSet->DestroyKernelObjects(m_kernelObjs));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpRenderCmdPacket::SetVeboxUpdateParams(PVEBOX_UPDATE_PARAMS params)
{
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpRenderCmdPacket::PacketInit(
VP_SURFACE* inputSurface,
VP_SURFACE* outputSurface,
VP_SURFACE* previousSurface,
VP_SURFACE_SETTING& surfSetting,
VP_EXECUTE_CAPS packetCaps)
{
// will remodify when normal render path enabled
VP_UNUSED(inputSurface);
VP_UNUSED(outputSurface);
VP_UNUSED(previousSurface);
m_PacketCaps = packetCaps;
m_surfSetting = surfSetting;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpRenderCmdPacket::KernelStateSetup()
{
if (m_kernelId.empty())
{
VP_RENDER_ASSERTMESSAGE("No VP Kernel Processing needed");
}
//VP_RENDER_CHK_NULL_RETURN(m_kernelSet);
VP_RENDER_CHK_NULL_RETURN(m_kernel);
// Processing kernel State setup
int32_t iKUID = 0; // Kernel Unique ID (DNDI uses combined kernels)
int32_t kernelSize = 0;
void* kernelBinary = nullptr;
// // Initialize States
MOS_ZeroMemory(m_filter, sizeof(m_filter));
MOS_ZeroMemory(&m_renderData.KernelEntry, sizeof(Kdll_CacheEntry));
// Store pointer to Kernel Parameter
VP_RENDER_CHK_STATUS_RETURN(m_kernel->GetKernelSettings(m_renderData.KernelParam));
VP_RENDER_CHK_STATUS_RETURN(m_kernel->GetKernelID(iKUID));
kernelSize = m_kernel->GetKernelSize();
kernelBinary = m_kernel->GetKernelBinary();
VP_RENDER_CHK_NULL_RETURN(kernelBinary);
// Set Parameters for Kernel Entry
m_renderData.KernelEntry.iKUID = iKUID;
m_renderData.KernelEntry.iKCID = -1;
m_renderData.KernelEntry.iFilterSize = 2;
m_renderData.KernelEntry.pFilter = m_filter;
m_renderData.KernelEntry.iSize = kernelSize;
m_renderData.KernelEntry.pBinary = (uint8_t*)kernelBinary;
// set the Inline Data length
void* InlineData = nullptr;
uint32_t iInlineLength = 0;
m_kernel->GetInlineState(&InlineData, iInlineLength);
m_renderData.iInlineLength = iInlineLength;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpRenderCmdPacket::SetupSurfaceState()
{
VP_RENDER_CHK_NULL_RETURN(m_kernel);
for (auto it : m_kernel->GetProcessingSurfaces())
{
auto surface = m_kernel->GetKernelSurfaceConfig().find(it);
if (surface != m_kernel->GetKernelSurfaceConfig().end())
{
KERNEL_SURFACE2D_STATE_PARAM kernelSurfaceParam = surface->second;
RENDERHAL_SURFACE_NEXT renderHalSurface;
MOS_ZeroMemory(&renderHalSurface, sizeof(RENDERHAL_SURFACE_NEXT));
RENDERHAL_SURFACE_STATE_PARAMS renderSurfaceParams;
MOS_ZeroMemory(&renderSurfaceParams, sizeof(RENDERHAL_SURFACE_STATE_PARAMS));
if (kernelSurfaceParam.surfaceOverwriteParams.updatedSurfaceParams)
{
renderSurfaceParams = kernelSurfaceParam.surfaceOverwriteParams.renderSurfaceParams;
}
else
{
renderSurfaceParams.bRenderTarget = (kernelSurfaceParam.renderTarget == true) ? 1 : 0;
renderSurfaceParams.Boundary = RENDERHAL_SS_BOUNDARY_ORIGINAL; // Add conditional in future for Surfaces out of range
renderSurfaceParams.bWidth16Align = false;
renderSurfaceParams.bWidthInDword_Y = true;
renderSurfaceParams.bWidthInDword_UV = true;
}
VP_SURFACE* vpSurface = m_surfSetting.surfGroup.find(it)->second;
VP_RENDER_CHK_NULL_RETURN(vpSurface);
VP_RENDER_CHK_STATUS_RETURN(InitRenderHalSurface(*vpSurface, renderHalSurface));
VP_RENDER_CHK_STATUS_RETURN(UpdateRenderSurface(renderHalSurface, kernelSurfaceParam));
uint32_t index = SetSurfaceForHwAccess(
vpSurface->osSurface,
&renderHalSurface,
&renderSurfaceParams,
renderSurfaceParams.bRenderTarget);
VP_RENDER_CHK_STATUS_RETURN(m_kernel->UpdateCurbeBindingIndex(it, index));
}
else
{
VP_RENDER_ASSERTMESSAGE("Kernel Obj Issue: Didn't find correct kernel surface here, return error");
return MOS_STATUS_UNIMPLEMENTED;
}
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpRenderCmdPacket::SetupCurbeState()
{
VP_RENDER_CHK_NULL_RETURN(m_kernel);
// set the Curbe Data length
void* curbeData = nullptr;
uint32_t curbeLength = 0;
m_kernel->GetCurbeState(curbeData, curbeLength);
m_renderData.iCurbeLength = curbeLength;
VP_RENDER_CHK_STATUS_RETURN(SetupCurbe(
curbeData,
curbeLength,
m_renderData.KernelParam.Thread_Count));
return MOS_STATUS_SUCCESS;
}
VP_SURFACE* VpRenderCmdPacket::GetSurface(SurfaceType type)
{
auto it = m_surfSetting.surfGroup.find(type);
VP_SURFACE* surf = (m_surfSetting.surfGroup.end() != it) ? it->second : nullptr;
return surf;
}
MOS_STATUS VpRenderCmdPacket::SetupMediaWalker()
{
VP_RENDER_CHK_NULL_RETURN(m_kernel);
VP_RENDER_CHK_STATUS_RETURN(m_kernel->GetWalkerSetting(m_renderData.walkerParam));
switch (m_walkerType)
{
case WALKER_TYPE_MEDIA:
MOS_ZeroMemory(&m_mediaWalkerParams, sizeof(MHW_WALKER_PARAMS));
// Prepare Media Walker Params
VP_RENDER_CHK_STATUS_RETURN(PrepareMediaWalkerParams(m_renderData.walkerParam, m_mediaWalkerParams));
break;
case WALKER_TYPE_COMPUTE:
// Parepare Compute Walker Param
MOS_ZeroMemory(&m_gpgpuWalkerParams, sizeof(MHW_GPGPU_WALKER_PARAMS));
VP_RENDER_CHK_STATUS_RETURN(PrepareComputeWalkerParams(m_renderData.walkerParam, m_gpgpuWalkerParams));
break;
case WALKER_TYPE_DISABLED:
default:
// using BB for walker setting
return MOS_STATUS_UNIMPLEMENTED;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpRenderCmdPacket::InitRenderHalSurface(VP_SURFACE& surface, RENDERHAL_SURFACE& renderSurface)
{
VP_RENDER_CHK_NULL_RETURN(surface.osSurface);
VP_RENDER_CHK_STATUS_RETURN(RenderCmdPacket::InitRenderHalSurface(*surface.osSurface, &renderSurface));
renderSurface.rcSrc = surface.rcSrc;
renderSurface.rcDst = surface.rcDst;
renderSurface.rcMaxSrc = surface.rcMaxSrc;
renderSurface.SurfType =
InitRenderHalSurfType(surface.SurfType);
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpRenderCmdPacket::UpdateRenderSurface(RENDERHAL_SURFACE_NEXT& renderSurface, KERNEL_SURFACE2D_STATE_PARAM& kernelParams)
{
auto& overwriteParam = kernelParams.surfaceOverwriteParams;
if (overwriteParam.updatedSurfaceParams)
{
if (overwriteParam.width && overwriteParam.height)
{
renderSurface.OsSurface.dwWidth = overwriteParam.width;
renderSurface.OsSurface.dwHeight = overwriteParam.height;
}
renderSurface.OsSurface.dwPitch = overwriteParam.pitch != 0 ? overwriteParam.pitch : renderSurface.OsSurface.dwPitch;
if (renderSurface.OsSurface.dwPitch < renderSurface.OsSurface.dwWidth)
{
VP_RENDER_ASSERTMESSAGE("Invalid Surface where Pitch < Width, return invalid Overwrite Params");
return MOS_STATUS_INVALID_PARAMETER;
}
renderSurface.OsSurface.Format = (overwriteParam.format != 0) ? overwriteParam.format : renderSurface.OsSurface.Format;
}
return MOS_STATUS_SUCCESS;
}
}