1 /*
2 * Copyright (c) 2017-2019, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     codechal_kernel_intra_dist.cpp
24 //! \brief    Defines the intra distortion kernel base
25 //! \details  Intra distortion base includes all common functions and definitions for intra distortion
26 //!
27 #include "codechal_kernel_intra_dist_mdf_g12.h"
28 
CodechalKernelIntraDistMdfG12(CodechalEncoderState * encoder)29 CodechalKernelIntraDistMdfG12::CodechalKernelIntraDistMdfG12(CodechalEncoderState *encoder) : CodechalKernelBase(encoder)
30 {
31 }
32 
~CodechalKernelIntraDistMdfG12()33 CodechalKernelIntraDistMdfG12::~CodechalKernelIntraDistMdfG12()
34 {
35     ReleaseResources();
36 }
37 
AllocateResources()38 MOS_STATUS CodechalKernelIntraDistMdfG12::AllocateResources()
39 {
40     // no resource need to allocate
41     return MOS_STATUS_SUCCESS;
42 }
43 
ReleaseResources()44 MOS_STATUS CodechalKernelIntraDistMdfG12::ReleaseResources()
45 {
46     CODECHAL_ENCODE_CHK_NULL_RETURN(m_encoder->m_cmDev);
47     if (m_vmeIdx)
48     {
49         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroyVmeSurfaceG7_5(m_vmeIdx));
50         m_vmeIdx = nullptr;
51     }
52 
53     if (m_src4xSurface)
54     {
55         m_src4xSurface->NotifyUmdResourceChanged(nullptr);
56         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroySurface(m_src4xSurface));
57         m_src4xSurface = nullptr;
58     }
59 
60     if (m_threadSpace)
61     {
62         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroyThreadSpace(m_threadSpace));
63         m_threadSpace = nullptr;
64     }
65 
66     if (m_cmKrn)
67     {
68         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroyKernel(m_cmKrn));
69         m_cmKrn = nullptr;
70     }
71 
72     if (m_cmProgram)
73     {
74         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroyProgram(m_cmProgram));
75         m_cmProgram = nullptr;
76     }
77 
78     return MOS_STATUS_SUCCESS;
79 }
80 
InitializeKernelIsa(void * kernelIsa,uint32_t kernelIsaSize)81 MOS_STATUS CodechalKernelIntraDistMdfG12::InitializeKernelIsa(void *kernelIsa, uint32_t kernelIsaSize)
82 {
83     CODECHAL_ENCODE_FUNCTION_ENTER;
84     CODECHAL_ENCODE_CHK_NULL_RETURN(m_encoder->m_cmDev);
85 
86     if (!m_cmProgram)
87     {
88         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->LoadProgram(kernelIsa,
89             kernelIsaSize,
90             m_cmProgram,
91             "-nojitter"));
92     }
93     if (!m_cmKrn)
94     {
95         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgram,
96             "Coarse_Intra",
97             m_cmKrn));
98     }
99 
100     return MOS_STATUS_SUCCESS;
101 }
102 
SetCurbe(MHW_KERNEL_STATE * kernelState)103 MOS_STATUS CodechalKernelIntraDistMdfG12::SetCurbe(MHW_KERNEL_STATE *kernelState)
104 {
105     // Do nothing in the MDF path
106     return MOS_STATUS_SUCCESS;
107 }
108 
SendSurfaces(PMOS_COMMAND_BUFFER cmd,MHW_KERNEL_STATE * kernelState)109 MOS_STATUS CodechalKernelIntraDistMdfG12::SendSurfaces(PMOS_COMMAND_BUFFER cmd, MHW_KERNEL_STATE *kernelState)
110 {
111     // Do nothing in the MDF path
112     return MOS_STATUS_SUCCESS;
113 }
114 
AddPerfTag()115 MOS_STATUS CodechalKernelIntraDistMdfG12::AddPerfTag()
116 {
117     PerfTagSetting perfTag;
118 
119     perfTag.Value             = 0;
120     perfTag.Mode              = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
121     perfTag.CallType          = CODECHAL_ENCODE_PERFTAG_CALL_INTRA_DIST;
122     perfTag.PictureCodingType = m_pictureCodingType > 3 ? 0 : m_pictureCodingType;
123     m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
124     m_osInterface->pfnResetPerfBufferID(m_osInterface);
125 
126     return MOS_STATUS_SUCCESS;
127 }
128 
GetActiveKernelState()129 MHW_KERNEL_STATE *CodechalKernelIntraDistMdfG12::GetActiveKernelState()
130 {
131     // Do nothing in the MDF path
132     return nullptr;
133 }
134 
InitWalkerCodecParams(CODECHAL_WALKER_CODEC_PARAMS & walkerParam)135 MOS_STATUS CodechalKernelIntraDistMdfG12::InitWalkerCodecParams(CODECHAL_WALKER_CODEC_PARAMS &walkerParam)
136 {
137     // Do nothing in the MDF path
138     return MOS_STATUS_SUCCESS;
139 }
140 
SetIntraDistCurbe(Curbe & curbe)141 MOS_STATUS CodechalKernelIntraDistMdfG12::SetIntraDistCurbe(Curbe &curbe)
142 {
143     curbe.m_data.DW0.picWidthInLumaSamples  = m_curbeParam.downScaledWidthInMb4x << 4;
144     curbe.m_data.DW0.picHeightInLumaSamples = m_curbeParam.downScaledHeightInMb4x << 4;
145 
146     return MOS_STATUS_SUCCESS;
147 }
148 
GetMediaStateType()149 CODECHAL_MEDIA_STATE_TYPE CodechalKernelIntraDistMdfG12::GetMediaStateType()
150 {
151     return CODECHAL_MEDIA_STATE_ENC_I_FRAME_DIST;
152 }
153 
SetupSurfaces()154 MOS_STATUS CodechalKernelIntraDistMdfG12::SetupSurfaces()
155 {
156     CmDevice *&cmDev            = m_encoder->m_cmDev;
157     bool       currFieldPicture = CodecHal_PictureIsField(m_encoder->m_currOriginalPic);
158     bool       currBottomField  = CodecHal_PictureIsBottomField(m_encoder->m_currOriginalPic) ? true : false;
159 
160     if (m_vmeIdx)
161     {
162         CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->DestroyVmeSurfaceG7_5(m_vmeIdx));
163         m_vmeIdx = nullptr;
164     }
165 
166     CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->UpdateSurface2D(
167         &m_surfaceParam.input4xDsSurface->OsResource,
168         m_src4xSurface));
169 
170     if (currFieldPicture)
171     {
172         m_src4xSurface->SetProperty(currBottomField ? CM_BOTTOM_FIELD : CM_TOP_FIELD);
173 
174         CM_SURFACE2D_STATE_PARAM surfStateParam;
175         MOS_ZeroMemory(&surfStateParam, sizeof(CM_SURFACE2D_STATE_PARAM));
176         surfStateParam.height           = MOS_ALIGN_CEIL((m_curbeParam.downScaledHeightInMb4x * 4), 8);
177         surfStateParam.surface_y_offset = currBottomField ? surfStateParam.height : 0;
178         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_surfaceParam.intraDistSurface->SetSurfaceStateParam(nullptr, &surfStateParam));
179     }
180 
181     CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateVmeSurfaceG7_5(
182         m_src4xSurface,
183         nullptr,
184         nullptr,
185         0,
186         0,
187         m_vmeIdx));
188 
189     return MOS_STATUS_SUCCESS;
190 }
191 
SetupKernelArgs()192 MOS_STATUS CodechalKernelIntraDistMdfG12::SetupKernelArgs()
193 {
194     CODECHAL_ENCODE_FUNCTION_ENTER;
195     int           idx = 0;
196     Curbe         curbe;
197     SurfaceIndex *pSurfIndex = nullptr;
198 
199     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetIntraDistCurbe(curbe));
200     m_cmKrn->SetKernelArg(idx++, sizeof(curbe), &curbe);
201 
202     m_src4xSurface->GetIndex(pSurfIndex);
203     m_cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex);
204 
205     m_surfaceParam.intraDistSurface->GetIndex(pSurfIndex);
206     m_cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex);
207 
208     m_cmKrn->SetKernelArg(idx++, sizeof(SurfaceIndex), m_vmeIdx);
209 
210     CODECHAL_DEBUG_TOOL(
211         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpMDFCurbe(
212             CODECHAL_MEDIA_STATE_ENC_I_FRAME_DIST,
213             (uint8_t *)&curbe,
214             sizeof(curbe)));)
215 
216     return MOS_STATUS_SUCCESS;
217 }
218 
Execute(CurbeParam & curbeParam,SurfaceParams & surfaceParam)219 MOS_STATUS CodechalKernelIntraDistMdfG12::Execute(CurbeParam &curbeParam, SurfaceParams &surfaceParam)
220 {
221     CODECHAL_ENCODE_FUNCTION_ENTER;
222 
223     MOS_SecureMemcpy(&m_curbeParam, sizeof(m_curbeParam), &curbeParam, sizeof(m_curbeParam));
224     MOS_SecureMemcpy(&m_surfaceParam, sizeof(m_surfaceParam), &surfaceParam, sizeof(m_surfaceParam));
225 
226     CmDevice *&cmDev = m_encoder->m_cmDev;
227 
228     SetupSurfaces();
229 
230     AddPerfTag();
231 
232     if (m_encoder->m_resolutionChanged && m_threadSpace != nullptr)
233     {
234         CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->DestroyThreadSpace(m_threadSpace));
235         m_threadSpace = nullptr;
236     }
237 
238     if (m_threadSpace == nullptr)
239     {
240         CODECHAL_ENCODE_CHK_STATUS_RETURN(cmDev->CreateThreadSpace(
241             m_curbeParam.downScaledWidthInMb4x,
242             m_curbeParam.downScaledHeightInMb4x,
243             m_threadSpace));
244         if (m_groupIdSelectSupported)
245         {
246             m_threadSpace->SetMediaWalkerGroupSelect((CM_MW_GROUP_SELECT)m_groupId);
247         }
248     }
249 
250     uint32_t threadCount = m_curbeParam.downScaledWidthInMb4x * m_curbeParam.downScaledHeightInMb4x;
251     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrn->SetThreadCount(threadCount));
252 
253     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrn->AssociateThreadSpace(m_threadSpace));
254     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupKernelArgs());
255     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmTask->AddKernel(m_cmKrn));
256 
257     if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
258     {
259         CmEvent *event = CM_NO_EVENT;
260         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmQueue->EnqueueFast(m_encoder->m_cmTask, event));
261         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmTask->Reset());
262         m_lastTaskInPhase = false;
263     }
264     else
265     {
266         m_encoder->m_cmTask->AddSync();
267     }
268 
269     return MOS_STATUS_SUCCESS;
270 }
271