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