1 /*
2 * Copyright (c) 2018, 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
24
25 //!
26 //! \file media_scalability_singlepipe.cpp
27 //! \brief Defines the common interface for media scalability singlepipe mode.
28 //! \details The media scalability singlepipe interface is further sub-divided by component,
29 //! this file is for the base interface which is shared by all components.
30 //!
31
32 #include "codec_hw_next.h"
33 #include "encode_scalability_defs.h"
34 #include "encode_scalability_singlepipe.h"
35
36 #include "media_context.h"
37 #include "media_status_report.h"
38 #include "mhw_utilities.h"
39 #include "encode_status_report_defs.h"
40 #include "hal_oca_interface_next.h"
41
42 namespace encode
43 {
44
EncodeScalabilitySinglePipe(void * hwInterface,MediaContext * mediaContext,uint8_t componentType)45 EncodeScalabilitySinglePipe::EncodeScalabilitySinglePipe(void *hwInterface, MediaContext *mediaContext, uint8_t componentType) :
46 MediaScalabilitySinglePipeNext(hwInterface, mediaContext, componentType)
47 {
48 if (hwInterface == nullptr)
49 {
50 return;
51 }
52 m_hwInterface = (CodechalHwInterfaceNext *)hwInterface;
53 m_osInterface = m_hwInterface->GetOsInterface();
54 }
55
Initialize(const MediaScalabilityOption & option)56 MOS_STATUS EncodeScalabilitySinglePipe::Initialize(const MediaScalabilityOption &option)
57 {
58 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
59 m_userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
60 if (!m_userSettingPtr)
61 {
62 ENCODE_NORMALMESSAGE("Initialize m_userSettingPtr instance failed!");
63 }
64
65 m_scalabilityOption = MOS_New(EncodeScalabilityOption, (const EncodeScalabilityOption &)option);
66 SCALABILITY_CHK_NULL_RETURN(m_scalabilityOption);
67
68 MediaUserSetting::Value outValue;
69 auto statusKey = ReadUserSetting(
70 m_userSettingPtr,
71 outValue,
72 "Enable Frame Tracking",
73 MediaUserSetting::Group::Sequence);
74
75 if (statusKey == MOS_STATUS_SUCCESS)
76 {
77 m_frameTrackingEnabled = outValue.Get<bool>();
78 }
79 else
80 {
81 m_frameTrackingEnabled = m_osInterface->bEnableKmdMediaFrameTracking ? true : false;
82 }
83
84 // !Don't check the return status here, because this function will return fail if there's no regist key in register.
85 // But it's normal that regist key not in register.
86 m_osInterface->pfnVirtualEngineSupported(m_osInterface, false, true);
87 m_miItf = m_hwInterface->GetMiInterfaceNext();
88 SCALABILITY_CHK_NULL_RETURN(m_miItf);
89
90 SCALABILITY_CHK_STATUS_RETURN(MediaScalabilitySinglePipeNext::Initialize(option));
91
92 PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreateOption =
93 dynamic_cast<PMOS_GPUCTX_CREATOPTIONS_ENHANCED>(m_gpuCtxCreateOption);
94 EncodeScalabilityOption *scalabilityOption =
95 dynamic_cast<EncodeScalabilityOption *>(m_scalabilityOption);
96 //The changes to indicate vdenc is required when slim vdbox is supported
97 if(gpuCtxCreateOption != nullptr &&
98 scalabilityOption != nullptr &&
99 scalabilityOption->IsVdencEnabled() &&
100 MEDIA_IS_SKU(m_osInterface->pfnGetSkuTable(m_osInterface), FtrWithSlimVdbox))
101 {
102 gpuCtxCreateOption->Flags |= (1 << 2);
103 }
104
105 return MOS_STATUS_SUCCESS;
106 }
107
VerifySpaceAvailable(uint32_t requestedSize,uint32_t requestedPatchListSize,bool & singleTaskPhaseSupportedInPak)108 MOS_STATUS EncodeScalabilitySinglePipe::VerifySpaceAvailable(uint32_t requestedSize, uint32_t requestedPatchListSize, bool &singleTaskPhaseSupportedInPak)
109 {
110 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
111
112 SCALABILITY_FUNCTION_ENTER;;
113
114 bool bothPatchListAndCmdBufChkSuccess = false;
115 uint8_t looptimes = m_singleTaskPhaseSupported ? 2 : 1;
116
117 for(auto i = 0 ; i < looptimes ; i++)
118 {
119 SCALABILITY_CHK_STATUS_RETURN(MediaScalability::VerifySpaceAvailable(
120 requestedSize, requestedPatchListSize, bothPatchListAndCmdBufChkSuccess));
121
122 if (bothPatchListAndCmdBufChkSuccess == true)
123 {
124 singleTaskPhaseSupportedInPak = m_singleTaskPhaseSupported;
125 return eStatus;
126 }
127
128 MOS_STATUS statusPatchList = MOS_STATUS_SUCCESS;
129 MOS_STATUS statusCmdBuf = MOS_STATUS_SUCCESS;
130
131 if (requestedPatchListSize > 0)
132 {
133 statusPatchList = (MOS_STATUS)m_osInterface->pfnVerifyPatchListSize(
134 m_osInterface,
135 requestedPatchListSize);
136 }
137
138 statusCmdBuf = (MOS_STATUS)m_osInterface->pfnVerifyCommandBufferSize(
139 m_osInterface,
140 requestedSize,
141 0);
142
143 if ((statusCmdBuf == MOS_STATUS_SUCCESS) && (statusPatchList == MOS_STATUS_SUCCESS))
144 {
145 singleTaskPhaseSupportedInPak = m_singleTaskPhaseSupported;
146 return eStatus;
147 }
148 }
149
150 eStatus = MOS_STATUS_NO_SPACE;
151 SCALABILITY_ASSERTMESSAGE("Resize Command buffer failed with no space!");
152 return eStatus;
153
154 }
155
UpdateState(void * statePars)156 MOS_STATUS EncodeScalabilitySinglePipe::UpdateState(void *statePars)
157 {
158 SCALABILITY_FUNCTION_ENTER;
159 SCALABILITY_CHK_STATUS_RETURN(MediaScalabilitySinglePipeNext::UpdateState(statePars));
160
161 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
162
163 StateParams *encodeStatePars = (StateParams *)statePars;
164 m_singleTaskPhaseSupported = encodeStatePars->singleTaskPhaseSupported;
165 m_statusReport = encodeStatePars->statusReport;
166 m_currentPass = encodeStatePars->currentPass;
167 m_currentRow = encodeStatePars->currentRow;
168 m_currentSubPass = encodeStatePars->currentSubPass;
169 SCALABILITY_CHK_NULL_RETURN(m_statusReport);
170
171 return eStatus;
172 }
173
ResizeCommandBufferAndPatchList(uint32_t requestedCommandBufferSize,uint32_t requestedPatchListSize)174 MOS_STATUS EncodeScalabilitySinglePipe::ResizeCommandBufferAndPatchList(
175 uint32_t requestedCommandBufferSize,
176 uint32_t requestedPatchListSize)
177 {
178 SCALABILITY_FUNCTION_ENTER;
179 SCALABILITY_CHK_NULL_RETURN(m_hwInterface);
180
181 return m_hwInterface->ResizeCommandBufferAndPatchList(requestedCommandBufferSize, requestedPatchListSize);
182 }
183
SendAttrWithFrameTracking(MOS_COMMAND_BUFFER & cmdBuffer,bool frameTrackingRequested)184 MOS_STATUS EncodeScalabilitySinglePipe::SendAttrWithFrameTracking(
185 MOS_COMMAND_BUFFER &cmdBuffer,
186 bool frameTrackingRequested)
187 {
188 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
189
190 SCALABILITY_FUNCTION_ENTER;
191
192 bool renderEngineUsed = m_mediaContext->IsRenderEngineUsed();
193
194 // initialize command buffer attributes
195 cmdBuffer.Attributes.bTurboMode = m_hwInterface->m_turboMode;
196 cmdBuffer.Attributes.bMediaPreemptionEnabled = renderEngineUsed ? m_hwInterface->GetRenderInterfaceNext()->IsPreemptionEnabled() : 0;
197 cmdBuffer.Attributes.dwNumRequestedEUSlices = m_hwInterface->m_numRequestedEuSlices;
198 cmdBuffer.Attributes.dwNumRequestedSubSlices = m_hwInterface->m_numRequestedSubSlices;
199 cmdBuffer.Attributes.dwNumRequestedEUs = m_hwInterface->m_numRequestedEus;
200 cmdBuffer.Attributes.bValidPowerGatingRequest = true;
201
202 PMOS_RESOURCE resource = nullptr;
203 uint32_t offset = 0;
204
205 if (frameTrackingRequested && m_frameTrackingEnabled)
206 {
207 m_statusReport->GetAddress(encode::statusReportGlobalCount, resource, offset);
208 cmdBuffer.Attributes.bEnableMediaFrameTracking = true;
209 cmdBuffer.Attributes.resMediaFrameTrackingSurface = resource;
210 cmdBuffer.Attributes.dwMediaFrameTrackingTag = m_statusReport->GetSubmittedCount() + 1;
211 // Set media frame tracking address offset(the offset from the encoder status buffer page)
212 cmdBuffer.Attributes.dwMediaFrameTrackingAddrOffset = 0;
213 }
214
215 return eStatus;
216 }
217 //#include "mhw_mi_impl.h"
218 ////VDBOX MFX register offsets
219 //static constexpr uint32_t MFC_IMAGE_STATUS_MASK_REG_OFFSET_NODE_1_INIT = 0x1C08B4;
220 //static constexpr uint32_t MFC_IMAGE_STATUS_CTRL_REG_OFFSET_NODE_1_INIT = 0x1C08B8;
221 //static constexpr uint32_t MFC_AVC_NUM_SLICES_REG_OFFSET_NODE_1_INIT = 0x1C0954;
222 //static constexpr uint32_t MFC_QP_STATUS_COUNT_OFFSET_NODE_1_INIT = 0x1C08BC;
223 //static constexpr uint32_t MFX_ERROR_FLAG_REG_OFFSET_NODE_1_INIT = 0x1C0800;
224 //static constexpr uint32_t MFX_FRAME_CRC_REG_OFFSET_NODE_1_INIT = 0x1C0850;
225 //static constexpr uint32_t MFX_MB_COUNT_REG_OFFSET_NODE_1_INIT = 0x1C0868;
226 //static constexpr uint32_t MFC_BITSTREAM_BYTECOUNT_FRAME_REG_OFFSET_NODE_1_INIT = 0x1C08A0;
227 //static constexpr uint32_t MFC_BITSTREAM_SE_BITCOUNT_FRAME_REG_OFFSET_NODE_1_INIT = 0x1C08A4;
228 //static constexpr uint32_t MFC_BITSTREAM_BYTECOUNT_SLICE_REG_OFFSET_NODE_1_INIT = 0x1C08D0;
229 ////VDBOX MFX register initial value
230 //static constexpr uint32_t MFX_LRA0_REG_OFFSET_NODE_1_INIT = 0;
231 //static constexpr uint32_t MFX_LRA1_REG_OFFSET_NODE_1_INIT = 0;
232 //static constexpr uint32_t MFX_LRA2_REG_OFFSET_NODE_1_INIT = 0;
233 //void EncodeScalabilitySinglePipe::InitMmioRegisters()
234 //{
235 // MmioRegistersMfx *mmioRegisters = &m_mmioRegisters[MHW_VDBOX_NODE_1];
236 //
237 // mmioRegisters->generalPurposeRegister0LoOffset = mhw::mi::GENERAL_PURPOSE_REGISTER0_LO_OFFSET_NODE_1_INIT;
238 // mmioRegisters->generalPurposeRegister0HiOffset = mhw::mi::GENERAL_PURPOSE_REGISTER0_HI_OFFSET_NODE_1_INIT;
239 // mmioRegisters->generalPurposeRegister4LoOffset = mhw::mi::GENERAL_PURPOSE_REGISTER4_LO_OFFSET_NODE_1_INIT;
240 // mmioRegisters->generalPurposeRegister4HiOffset = mhw::mi::GENERAL_PURPOSE_REGISTER4_HI_OFFSET_NODE_1_INIT;
241 // mmioRegisters->generalPurposeRegister11LoOffset = mhw::mi::GENERAL_PURPOSE_REGISTER11_LO_OFFSET_NODE_1_INIT;
242 // mmioRegisters->generalPurposeRegister11HiOffset = mhw::mi::GENERAL_PURPOSE_REGISTER11_HI_OFFSET_NODE_1_INIT;
243 // mmioRegisters->generalPurposeRegister12LoOffset = mhw::mi::GENERAL_PURPOSE_REGISTER12_LO_OFFSET_NODE_1_INIT;
244 // mmioRegisters->generalPurposeRegister12HiOffset = mhw::mi::GENERAL_PURPOSE_REGISTER12_HI_OFFSET_NODE_1_INIT;
245 // mmioRegisters->mfcImageStatusMaskRegOffset = MFC_IMAGE_STATUS_MASK_REG_OFFSET_NODE_1_INIT;
246 // mmioRegisters->mfcImageStatusCtrlRegOffset = MFC_IMAGE_STATUS_CTRL_REG_OFFSET_NODE_1_INIT;
247 // mmioRegisters->mfcAvcNumSlicesRegOffset = MFC_AVC_NUM_SLICES_REG_OFFSET_NODE_1_INIT;
248 // mmioRegisters->mfcQPStatusCountOffset = MFC_QP_STATUS_COUNT_OFFSET_NODE_1_INIT;
249 // mmioRegisters->mfxErrorFlagsRegOffset = MFX_ERROR_FLAG_REG_OFFSET_NODE_1_INIT;
250 // mmioRegisters->mfxFrameCrcRegOffset = MFX_FRAME_CRC_REG_OFFSET_NODE_1_INIT;
251 // mmioRegisters->mfxMBCountRegOffset = MFX_MB_COUNT_REG_OFFSET_NODE_1_INIT;
252 // mmioRegisters->mfcBitstreamBytecountFrameRegOffset = MFC_BITSTREAM_BYTECOUNT_FRAME_REG_OFFSET_NODE_1_INIT;
253 // mmioRegisters->mfcBitstreamSeBitcountFrameRegOffset = MFC_BITSTREAM_SE_BITCOUNT_FRAME_REG_OFFSET_NODE_1_INIT;
254 // mmioRegisters->mfcBitstreamBytecountSliceRegOffset = MFC_BITSTREAM_BYTECOUNT_SLICE_REG_OFFSET_NODE_1_INIT;
255 // mmioRegisters->mfxLra0RegOffset = MFX_LRA0_REG_OFFSET_NODE_1_INIT;
256 // mmioRegisters->mfxLra1RegOffset = MFX_LRA1_REG_OFFSET_NODE_1_INIT;
257 // mmioRegisters->mfxLra2RegOffset = MFX_LRA2_REG_OFFSET_NODE_1_INIT;
258 //
259 // m_mmioRegisters[MHW_VDBOX_NODE_2] = m_mmioRegisters[MHW_VDBOX_NODE_1];
260 //}
261 //MmioRegistersMfx *EncodeScalabilitySinglePipe::GetMmioRegisters(MHW_VDBOX_NODE_IND index)
262 //{
263 // if (index < MHW_VDBOX_NODE_MAX)
264 // {
265 // return &m_mmioRegisters[index];
266 // }
267 // else
268 // {
269 // MHW_ASSERT("index is out of range!");
270 // return &m_mmioRegisters[MHW_VDBOX_NODE_1];
271 // }
272 //}
273 //bool EncodeScalabilitySinglePipe::ConvertToMiRegister(MHW_VDBOX_NODE_IND index, MHW_MI_MMIOREGISTERS &mmioRegister)
274 //{
275 // MmioRegistersMfx *mfxMmioReg = GetMmioRegisters(index);
276 // if (mfxMmioReg)
277 // {
278 // mmioRegister.generalPurposeRegister0LoOffset = mfxMmioReg->generalPurposeRegister0LoOffset;
279 // mmioRegister.generalPurposeRegister0HiOffset = mfxMmioReg->generalPurposeRegister0HiOffset;
280 // mmioRegister.generalPurposeRegister4LoOffset = mfxMmioReg->generalPurposeRegister4LoOffset;
281 // mmioRegister.generalPurposeRegister4HiOffset = mfxMmioReg->generalPurposeRegister4HiOffset;
282 // mmioRegister.generalPurposeRegister11LoOffset = mfxMmioReg->generalPurposeRegister11LoOffset;
283 // mmioRegister.generalPurposeRegister11HiOffset = mfxMmioReg->generalPurposeRegister11HiOffset;
284 // mmioRegister.generalPurposeRegister12LoOffset = mfxMmioReg->generalPurposeRegister12LoOffset;
285 // mmioRegister.generalPurposeRegister12HiOffset = mfxMmioReg->generalPurposeRegister12HiOffset;
286 // return true;
287 // }
288 // else
289 // return false;
290 //}
291
Oca1stLevelBBStart(MOS_COMMAND_BUFFER & cmdBuffer)292 MOS_STATUS EncodeScalabilitySinglePipe::Oca1stLevelBBStart(MOS_COMMAND_BUFFER &cmdBuffer)
293 {
294 MHW_MI_MMIOREGISTERS mmioRegister;
295 SCALABILITY_CHK_NULL_RETURN(m_hwInterface);
296
297 auto vdencItf = m_hwInterface->GetVdencInterfaceNext();
298 SCALABILITY_CHK_NULL_RETURN(vdencItf);
299 bool validMmio = vdencItf->ConvertToMiRegister(MHW_VDBOX_NODE_1, mmioRegister);
300 if (validMmio)
301 {
302 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
303 SCALABILITY_CHK_NULL_RETURN(m_osInterface->pOsContext);
304
305 HalOcaInterfaceNext::On1stLevelBBStart(
306 cmdBuffer,
307 (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext,
308 m_osInterface->CurrentGpuContextHandle,
309 m_miItf,
310 mmioRegister);
311 }
312
313 return MOS_STATUS_SUCCESS;
314 }
315
Oca1stLevelBBEnd(MOS_COMMAND_BUFFER & cmdBuffer)316 MOS_STATUS EncodeScalabilitySinglePipe::Oca1stLevelBBEnd(MOS_COMMAND_BUFFER &cmdBuffer)
317 {
318 SCALABILITY_CHK_NULL_RETURN(m_osInterface);
319 HalOcaInterfaceNext::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
320
321 return MOS_STATUS_SUCCESS;
322 }
323
324 }
325
326
327