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 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->CreateThreadSpace(
142 ResolutionX,
143 ResolutionY,
144 m_threadSpace));
145
146 if (m_groupIdSelectSupported)
147 {
148 m_threadSpace->SetMediaWalkerGroupSelect((CM_MW_GROUP_SELECT)m_groupId);
149 }
150
151 CODECHAL_ENCODE_CHK_STATUS_RETURN(cmKrn->AssociateThreadSpace(m_threadSpace));
152
153 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupKernelArgs(wpKrnIdx));
154
155 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmTask->AddKernel(cmKrn));
156
157 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
158 {
159 CmEvent * event = CM_NO_EVENT;
160 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmQueue->EnqueueFast(m_encoder->m_cmTask, event));
161 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmTask->Reset());
162 m_lastTaskInPhase = false;
163 }
164 else
165 {
166 m_encoder->m_cmTask->AddSync();
167 }
168
169 if (params->useRefPicList1 == false)
170 {
171 // Dump all the surfaces for debugging
172 CODECHAL_DEBUG_TOOL(
173 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
174 m_surfaceParams.refFrameInput,
175 CodechalDbgAttr::attrEncodeRawInputSurface,
176 "WP_input_Surface_L0")));
177
178 CODECHAL_DEBUG_TOOL(
179 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
180 &m_surfaceParams.weightedPredOutputPicList[m_surfaceParams.wpOutListIdx],
181 CodechalDbgAttr::attrReferenceSurfaces,
182 "WP_output_Surface_L0")));
183 }
184 else
185 {
186 // Dump all the surfaces for debugging
187 CODECHAL_DEBUG_TOOL(
188 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
189 m_surfaceParams.refFrameInput,
190 CodechalDbgAttr::attrEncodeRawInputSurface,
191 "WP_input_Surface_L1")));
192
193 CODECHAL_DEBUG_TOOL(
194 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
195 &m_surfaceParams.weightedPredOutputPicList[m_surfaceParams.wpOutListIdx],
196 CodechalDbgAttr::attrReferenceSurfaces,
197 "WP_output_Surface_L1")));
198 }
199 return eStatus;
200 }
201
SetupKernelArgs(uint8_t wpKrnIdx)202 MOS_STATUS CodechalEncodeWPMdfG12::SetupKernelArgs(uint8_t wpKrnIdx)
203 {
204 CODECHAL_ENCODE_FUNCTION_ENTER;
205 int idx = 0;
206 CurbeData curbe;
207 SurfaceIndex * pSurfIndex = nullptr;
208 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbe(curbe));
209 CODECHAL_ENCODE_CHK_NULL_RETURN(m_wpInputSurface[wpKrnIdx]);
210 CODECHAL_ENCODE_CHK_NULL_RETURN(m_wpOutputSurface[wpKrnIdx]);
211
212 // SetKernelArg will copy curbe data
213 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrn[wpKrnIdx]->SetKernelArg(idx++, sizeof(curbe), &curbe));
214 CODECHAL_DEBUG_TOOL(
215 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpMDFCurbe(
216 CODECHAL_MEDIA_STATE_ENC_WP,
217 (uint8_t *)&curbe,
218 sizeof(curbe)));)
219
220 m_wpInputSurface[wpKrnIdx]->GetIndex(pSurfIndex);
221 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrn[wpKrnIdx]->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex));
222
223 m_wpOutputSurface[wpKrnIdx]->GetIndex(pSurfIndex);
224 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cmKrn[wpKrnIdx]->SetKernelArg(idx++, sizeof(SurfaceIndex), pSurfIndex));
225
226 return MOS_STATUS_SUCCESS;
227 }
228
SetupSurfaces(uint8_t wpKrnIdx)229 MOS_STATUS CodechalEncodeWPMdfG12::SetupSurfaces(uint8_t wpKrnIdx)
230 {
231 CODECHAL_ENCODE_FUNCTION_ENTER;
232 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->UpdateSurface2D(
233 &m_surfaceParams.refFrameInput->OsResource,
234 m_wpInputSurface[wpKrnIdx]));
235
236 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->UpdateSurface2D(
237 &m_surfaceParams.weightedPredOutputPicList[m_surfaceParams.wpOutListIdx].OsResource,
238 m_wpOutputSurface[wpKrnIdx]));
239
240 return MOS_STATUS_SUCCESS;
241 }
242
ReleaseResources()243 MOS_STATUS CodechalEncodeWPMdfG12::ReleaseResources()
244 {
245 CODECHAL_ENCODE_FUNCTION_ENTER;
246 for (uint8_t i = 0; i < CODEC_NUM_WP_FRAME; i++)
247 {
248 if (m_wpInputSurface[i])
249 {
250 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroySurface(m_wpInputSurface[i]));
251 m_wpInputSurface[i] = nullptr;
252 }
253
254 if (m_wpOutputSurface[i])
255 {
256 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_cmDev->DestroySurface(m_wpOutputSurface[i]));
257 m_wpOutputSurface[i] = nullptr;
258 }
259 }
260
261 return MOS_STATUS_SUCCESS;
262 }
263