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_encode_wp_mdf_g12.cpp
24 //! \brief This file implements the wp init feature for all codecs on Gen12 platform
25 //!
26
27 #include "codechal_encoder_base.h"
28 #include "codechal_encode_wp_mdf_g12.h"
29 #include "codeckrnheader.h"
30 #include "Gen12LP_WeightedPrediction_genx.h"
31
InitKernelStateIsa(void * kernelIsa,uint32_t kernelIsaSize)32 MOS_STATUS CodechalEncodeWPMdfG12::InitKernelStateIsa(void *kernelIsa, uint32_t kernelIsaSize)
33 {
34 CODECHAL_ENCODE_FUNCTION_ENTER;
35 if (!m_cmProgram)
36 {
37 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->LoadProgram(kernelIsa,
38 kernelIsaSize,
39 m_cmProgram,
40 "-nojitter"));
41 }
42 for (uint8_t i = 0; i < CODEC_NUM_WP_FRAME; i++)
43 {
44 if (m_cmKrn[i] == nullptr)
45 {
46 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateKernel(m_cmProgram,
47 "Scale_frame",
48 m_cmKrn[i]));
49 }
50 }
51
52 return MOS_STATUS_SUCCESS;
53 }
54
SetCurbe(CurbeData & curbe)55 MOS_STATUS CodechalEncodeWPMdfG12::SetCurbe(CurbeData &curbe)
56 {
57 CODECHAL_ENCODE_FUNCTION_ENTER;
58 MOS_ZeroMemory(&curbe, sizeof(CurbeData));
59
60 /* Weights[i][j][k][m] is interpreted as:
61
62 i refers to reference picture list 0 or 1;
63 j refers to reference list entry 0-31;
64 k refers to data for the luma (Y) component when it is 0, the Cb chroma component when it is 1 and the Cr chroma component when it is 2;
65 m refers to weight when it is 0 and offset when it is 1
66 */
67 //C Model hard code log2WeightDenom = 6. No need to send WD paramters to WP Kernel.
68 curbe.DW0.defaultWeight = m_curbeParams.slcParams->weights[m_curbeParams.refPicListIdx][m_curbeParams.wpIdx][0][0];
69 curbe.DW0.defaultOffset = m_curbeParams.slcParams->weights[m_curbeParams.refPicListIdx][m_curbeParams.wpIdx][0][1];
70
71 curbe.DW49.lumaLog2WeightDenom = m_curbeParams.slcParams->luma_log2_weight_denom;
72
73 return MOS_STATUS_SUCCESS;
74 }
75
76 //!
77 //! \brief WP init kernel function
78 //!
79 //! \param [in] params
80 //! Pointer to KernelParams
81 //!
82 //! \return MOS_STATUS
83 //! MOS_STATUS_SUCCESS if success, else fail reason
84 //!
Execute(KernelParams * params)85 MOS_STATUS CodechalEncodeWPMdfG12::Execute(KernelParams *params)
86 {
87 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
88 CODECHAL_ENCODE_FUNCTION_ENTER;
89
90 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
91
92 if (params->slcWPParams && params->slcWPParams->luma_log2_weight_denom != 6)
93 {
94 eStatus = MOS_STATUS_INVALID_PARAMETER;
95 CODECHAL_ENCODE_ASSERTMESSAGE("Weighted Prediction Kernel does not support Log2LumaWeightDenom != 6!");
96 return eStatus;
97 }
98
99 PerfTagSetting perfTag;
100 CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_WP_KERNEL);
101
102 // Allocate output surface
103 if (params->useRefPicList1)
104 {
105 *(params->useWeightedSurfaceForL1) = true;
106 m_surfaceParams.wpOutListIdx = CODEC_WP_OUTPUT_L1_START + params->wpIndex;
107 }
108 else
109 {
110 *(params->useWeightedSurfaceForL0) = true;
111 m_surfaceParams.wpOutListIdx = CODEC_WP_OUTPUT_L0_START + params->wpIndex;
112 }
113 if (m_surfaceParams.wpOutListIdx >= CODEC_NUM_WP_FRAME)
114 {
115 eStatus = MOS_STATUS_INVALID_PARAMETER;
116 CODECHAL_ENCODE_ASSERTMESSAGE("index exceeds maximum value of array weightedPredOutputPicList.");
117 return eStatus;
118 }
119 uint8_t wpKrnIdx = m_surfaceParams.wpOutListIdx;
120 CmKernel *cmKrn = m_cmKrn[wpKrnIdx];
121
122 // Setup Curbe
123 m_curbeParams.refPicListIdx = (params->useRefPicList1) ? LIST_1 : LIST_0;
124 m_curbeParams.wpIdx = params->wpIndex;
125 m_curbeParams.slcParams = params->slcWPParams;
126
127 //Set Surface States
128 m_surfaceParams.refFrameInput = params->refFrameInput;
129 m_surfaceParams.refIsBottomField = params->refIsBottomField;
130
131 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResources());
132
133 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupSurfaces(wpKrnIdx));
134
135 uint32_t ResolutionX = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth);
136 uint32_t ResolutionY = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight);
137
138 uint32_t threadCount = ResolutionX * ResolutionY;
139 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmKrn->SetThreadCount(threadCount));
140
141 if (m_encoder->m_resolutionChanged && m_threadSpace != nullptr)
142 {
143 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroyThreadSpace(m_threadSpace));
144 m_threadSpace = nullptr;
145 }
146
147 if (m_threadSpace == nullptr)
148 {
149 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateThreadSpace(
150 ResolutionX,
151 ResolutionY,
152 m_threadSpace));
153
154 if (m_groupIdSelectSupported)
155 {
156 m_threadSpace->SetMediaWalkerGroupSelect((CM_MW_GROUP_SELECT)m_groupId);
157 }
158 }
159
160 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmKrn->AssociateThreadSpace(m_threadSpace));
161
162 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupKernelArgs(wpKrnIdx));
163
164 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmTask->AddKernel(cmKrn));
165
166 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
167 {
168 CmEvent *event = CM_NO_EVENT;
169 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmQueue->EnqueueFast(m_encoder->m_cmTask, event));
170 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmTask->Reset());
171 m_lastTaskInPhase = false;
172 }
173 else
174 {
175 m_encoder->m_cmTask->AddSync();
176 }
177
178 if (params->useRefPicList1 == false)
179 {
180 // Dump all the surfaces for debugging
181 CODECHAL_DEBUG_TOOL(
182 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
183 m_surfaceParams.refFrameInput,
184 CodechalDbgAttr::attrEncodeRawInputSurface,
185 "WP_input_Surface_L0")));
186
187 CODECHAL_DEBUG_TOOL(
188 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
189 &m_surfaceParams.weightedPredOutputPicList[m_surfaceParams.wpOutListIdx],
190 CodechalDbgAttr::attrReferenceSurfaces,
191 "WP_output_Surface_L0")));
192 }
193 else
194 {
195 // Dump all the surfaces for debugging
196 CODECHAL_DEBUG_TOOL(
197 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
198 m_surfaceParams.refFrameInput,
199 CodechalDbgAttr::attrEncodeRawInputSurface,
200 "WP_input_Surface_L1")));
201
202 CODECHAL_DEBUG_TOOL(
203 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
204 &m_surfaceParams.weightedPredOutputPicList[m_surfaceParams.wpOutListIdx],
205 CodechalDbgAttr::attrReferenceSurfaces,
206 "WP_output_Surface_L1")));
207 }
208 return eStatus;
209 }
210
SetupKernelArgs(uint8_t wpKrnIdx)211 MOS_STATUS CodechalEncodeWPMdfG12::SetupKernelArgs(uint8_t wpKrnIdx)
212 {
213 CODECHAL_ENCODE_FUNCTION_ENTER;
214 int idx = 0;
215 CurbeData curbe;
216 SurfaceIndex *pSurfIndex = nullptr;
217 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbe(curbe));
218 CODECHAL_ENCODE_CHK_NULL_RETURN(m_wpInputSurface[wpKrnIdx]);
219 CODECHAL_ENCODE_CHK_NULL_RETURN(m_wpOutputSurface[wpKrnIdx]);
220
221 // SetKernelArg will copy curbe data
222 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrn[wpKrnIdx]->SetKernelArg(idx++, sizeof(curbe), &curbe));
223 CODECHAL_DEBUG_TOOL(
224 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpMDFCurbe(
225 CODECHAL_MEDIA_STATE_ENC_WP,
226 (uint8_t *)&curbe,
227 sizeof(curbe)));)
228
229 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_wpInputSurface[wpKrnIdx]->GetIndex(pSurfIndex));
230 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrn[wpKrnIdx]->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex));
231
232 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_wpOutputSurface[wpKrnIdx]->GetIndex(pSurfIndex));
233 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrn[wpKrnIdx]->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex));
234
235 return MOS_STATUS_SUCCESS;
236 }
237
SetupSurfaces(uint8_t wpKrnIdx)238 MOS_STATUS CodechalEncodeWPMdfG12::SetupSurfaces(uint8_t wpKrnIdx)
239 {
240 CODECHAL_ENCODE_FUNCTION_ENTER;
241 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->UpdateSurface2D(
242 &m_surfaceParams.refFrameInput->OsResource,
243 m_wpInputSurface[wpKrnIdx]));
244
245 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->UpdateSurface2D(
246 &m_surfaceParams.weightedPredOutputPicList[m_surfaceParams.wpOutListIdx].OsResource,
247 m_wpOutputSurface[wpKrnIdx]));
248
249 return MOS_STATUS_SUCCESS;
250 }
251
ReleaseResources()252 MOS_STATUS CodechalEncodeWPMdfG12::ReleaseResources()
253 {
254 CODECHAL_ENCODE_FUNCTION_ENTER;
255 if (m_threadSpace)
256 {
257 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroyThreadSpace(m_threadSpace));
258 m_threadSpace = nullptr;
259 }
260
261 for (uint8_t i = 0; i < CODEC_NUM_WP_FRAME; i++)
262 {
263 if (m_wpInputSurface[i])
264 {
265 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroySurface(m_wpInputSurface[i]));
266 m_wpInputSurface[i] = nullptr;
267 }
268
269 if (m_wpOutputSurface[i])
270 {
271 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroySurface(m_wpOutputSurface[i]));
272 m_wpOutputSurface[i] = nullptr;
273 }
274
275 if (m_cmKrn[i])
276 {
277 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroyKernel(m_cmKrn[i]));
278 m_cmKrn[i] = nullptr;
279 }
280 }
281
282 if (m_cmProgram)
283 {
284 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroyProgram(m_cmProgram));
285 m_cmProgram = nullptr;
286 }
287
288 return MOS_STATUS_SUCCESS;
289 }
290