1 /*
2 * Copyright (c) 2021, 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     hal_oca_interface_next.cpp
24 //! \brief    Implementation of functions for Hal OCA Interface
25 //! \details  Implementation of functions for Hal OCA Interface
26 //!
27 
28 #include <stdint.h>
29 #include <map>
30 #include <memory>
31 #include <utility>
32 #include "codec_def_common.h"
33 #include "mhw_mi.h"
34 #include "mos_defs.h"
35 #include "mos_defs_specific.h"
36 #include "mos_oca_interface.h"
37 #include "mos_os_hw.h"
38 #include "mos_os_specific.h"
39 #include "mos_os.h"
40 #include "hal_oca_interface_next.h"
41 #include "mhw_mmio.h"
42 #include "mos_interface.h"
43 #include "mos_oca_interface_specific.h"
44 #include "mos_oca_rtlog_mgr.h"
45 #include "vp_debug.h"
46 #include "codechal_oca_debug.h"
47 #include "mhw_utilities_next.h"
48 
49 namespace mhw { namespace mi { class Itf; } }
50 
51 /****************************************************************************************************/
52 /*                                      HalOcaInterfaceNextNext                                             */
53 /****************************************************************************************************/
MhwMiLoadRegisterImmCmd(std::shared_ptr<mhw::mi::Itf> miItf,PMOS_COMMAND_BUFFER pCmdBuffer,MHW_MI_LOAD_REGISTER_IMM_PARAMS * params)54 MOS_STATUS HalOcaInterfaceNext::MhwMiLoadRegisterImmCmd(
55     std::shared_ptr<mhw::mi::Itf>    miItf,
56     PMOS_COMMAND_BUFFER              pCmdBuffer,
57     MHW_MI_LOAD_REGISTER_IMM_PARAMS *params)
58 {
59     return MOS_STATUS_SUCCESS;
60 }
61 
62 //!
63 //! \brief  Oca operation which should be called at the beginning of 1st level batch buffer start.
64 //! \param  [in/out] cmdBuffer
65 //!         Command buffer for current BB. ocaBufHandle in cmdBuffer will be updated.
66 //! \param  [in] mosContext
67 //!         Reference to MOS_CONTEXT.
68 //! \param  [in] gpuContextHandle
69 //!         Gpu context handle
70 //! \param  [in] miItf
71 //!         Reference to Mhw MiItf.
72 //! \param  [in] mmioRegisters
73 //!         mmio registers for current engine.
74 //! \param  [in] offsetOf1stLevelBB
75 //!         Offset for current BB in cmdBuffer.
76 //! \param  [in] bUseSizeOfCmdBuf
77 //!         If true, use size of cmdBuffer for batch buffer, else use sizeOf1stLevelBB.
78 //! \param  [in] sizeOf1stLevelBB
79 //!         Size of BB. Ignore if bUseSizeOfResource == true.
80 //! \return void
81 //!         No return value. Handle all exception inside the function.
82 //!
On1stLevelBBStart(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,uint32_t gpuContextHandle,std::shared_ptr<mhw::mi::Itf> miItf,MHW_MI_MMIOREGISTERS & mmioRegisters,uint32_t offsetOf1stLevelBB,bool bUseSizeOfCmdBuf,uint32_t sizeOf1stLevelBB)83 void HalOcaInterfaceNext::On1stLevelBBStart(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext,
84         uint32_t gpuContextHandle, std::shared_ptr<mhw::mi::Itf> miItf, MHW_MI_MMIOREGISTERS &mmioRegisters,
85         uint32_t offsetOf1stLevelBB, bool bUseSizeOfCmdBuf, uint32_t sizeOf1stLevelBB)
86 {
87     HalOcaInterfaceNext::On1stLevelBBStart(cmdBuffer, *(PMOS_CONTEXT)mosContext, gpuContextHandle);
88 }
89 
90 //!
91 //! \brief  Oca operation which should be called at the beginning of 1st level batch buffer start.
92 //! \param  [in/out] cmdBuffer
93 //!         Command buffer for current BB. ocaBufHandle in cmdBuffer will be updated.
94 //! \param  [in] mosContext
95 //!         Reference to MOS_CONTEXT.
96 //! \param  [in] gpuContextHandle
97 //!         Gpu context handle
98 //! \param  [in] miItf
99 //!         Reference to Mhw MiItf.
100 //! \param  [in] mmioRegisters
101 //!         mmio registers for current engine.
102 //! \param  [in] offsetOf1stLevelBB
103 //!         Offset for current BB in cmdBuffer.
104 //! \param  [in] bUseSizeOfCmdBuf
105 //!         If true, use size of cmdBuffer for batch buffer, else use sizeOf1stLevelBB.
106 //! \param  [in] sizeOf1stLevelBB
107 //!         Size of BB. Ignore if bUseSizeOfResource == true.
108 //! \return void
109 //!         No return value. Handle all exception inside the function.
110 //!
On1stLevelBBStart(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,uint32_t gpuContextHandle,std::shared_ptr<mhw::mi::Itf> miItf,MmioRegistersMfx & mmioRegisters,uint32_t offsetOf1stLevelBB,bool bUseSizeOfCmdBuf,uint32_t sizeOf1stLevelBB)111 void HalOcaInterfaceNext::On1stLevelBBStart(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext,
112         uint32_t gpuContextHandle, std::shared_ptr<mhw::mi::Itf> miItf, MmioRegistersMfx &mmioRegisters,
113         uint32_t offsetOf1stLevelBB, bool bUseSizeOfCmdBuf, uint32_t sizeOf1stLevelBB)
114 {
115     HalOcaInterfaceNext::On1stLevelBBStart(cmdBuffer, *(PMOS_CONTEXT)mosContext, gpuContextHandle);
116 }
117 
118 //!
119 //! \brief  Oca operation which should be called before adding batch buffer end command for 1st
120 //!         level batch buffer.
121 //! \param  [in/out] cmdBuffer
122 //!         Command buffer for current BB. ocaBufHandle in cmdBuffer will be updated.
123 //! \param  [in] osInterface
124 //!         Reference to MOS_INTERFACE.
125 //! \return void
126 //!         No return value. Handle all exception inside the function.
127 //!
On1stLevelBBEnd(MOS_COMMAND_BUFFER & cmdBuffer,MOS_INTERFACE & osInterface)128 void HalOcaInterfaceNext::On1stLevelBBEnd(MOS_COMMAND_BUFFER &cmdBuffer, MOS_INTERFACE &osInterface)
129 {
130     if (nullptr == osInterface.pOsContext)
131     {
132         OnOcaError(nullptr, MOS_STATUS_INVALID_PARAMETER, __FUNCTION__, __LINE__);
133         return;
134     }
135     MOS_CONTEXT &           mosContext     = *osInterface.pOsContext;
136     MosOcaInterface *pOcaInterface         = &MosOcaInterfaceSpecific::GetInstance();
137     MOS_OCA_BUFFER_HANDLE   ocaBufHandle   = 0;
138     MOS_STATUS              status         = MOS_STATUS_SUCCESS;
139 
140     if (nullptr == pOcaInterface || !((MosOcaInterfaceSpecific*)pOcaInterface)->IsOcaEnabled())
141     {
142         // Will come here for UMD_OCA not being enabled case.
143         return;
144     }
145     if ((ocaBufHandle = GetOcaBufferHandle(cmdBuffer, (MOS_CONTEXT_HANDLE)&mosContext)) == MOS_OCA_INVALID_BUFFER_HANDLE)
146     {
147         // May come here for workloads not enabling UMD_OCA.
148         return;
149     }
150 
151     status = pOcaInterface->On1stLevelBBEnd(ocaBufHandle, osInterface.pOsContext);
152     if (MOS_FAILED(status))
153     {
154         // UnlockOcaBuf and RemoveOcaBufferHandle should also be called
155         // for failure case to avoid oca buffer leak.
156         OnOcaError(osInterface.pOsContext, status, __FUNCTION__, __LINE__);
157     }
158     status = pOcaInterface->UnlockOcaBufferWithDelay(ocaBufHandle);
159     if (MOS_FAILED(status))
160     {
161         OnOcaError(osInterface.pOsContext, status, __FUNCTION__, __LINE__);
162     }
163 
164     // remove the oca buffer handle
165     RemoveOcaBufferHandle(cmdBuffer, mosContext);
166 }
167 
168 //!
169 //! \brief  Oca operation which should be called before sending start sub level batch buffer command.
170 //! \param  [in] cmdBuffer
171 //!         Command buffer for current BB.
172 //! \param  [in] mosContext
173 //!         Reference to MOS_CONTEXT.
174 //! \param  [in] pMosResource
175 //!         Pointer to the MOS_RESOURCE.
176 //! \param  [in] offsetOfSubLevelBB
177 //!         Offset for current BB in pMosResource.
178 //! \param  [in] bUseSizeOfResource
179 //!         If true, use size of pMosResource for batch buffer, else use sizeOfIndirectState.
180 //! \param  [in] sizeOfSubLevelBB
181 //!         Size of BB. Ignore if bUseSizeOfResource == true.
182 //! \return void
183 //!         No return value. Handle all exception inside the function.
184 //!
OnSubLevelBBStart(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,void * pMosResource,uint32_t offsetOfSubLevelBB,bool bUseSizeOfResource,uint32_t sizeOfSubLevelBB)185 void HalOcaInterfaceNext::OnSubLevelBBStart(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext, void *pMosResource, uint32_t offsetOfSubLevelBB, bool bUseSizeOfResource, uint32_t sizeOfSubLevelBB)
186 {
187     MosInterface::SetObjectCapture((PMOS_RESOURCE)pMosResource);
188 }
189 
190 //!
191 //! \brief  Oca operation which should be called when indirect states being added.
192 //! \param  [in] cmdBuffer
193 //!         Command buffer for current BB.
194 //! \param  [in] mosContext
195 //!         Reference to MOS_CONTEXT.
196 //! \param  [in] pMosResource
197 //!         Pointer to the MOS_RESOURCE.
198 //! \param  [in] offsetOfIndirectState
199 //!         Offset for current state in pMosResource.
200 //! \param  [in] bUseSizeOfResource
201 //!         If true, use size of pMosResource for indirect state, else use sizeOfIndirectState.
202 //! \param  [in] sizeOfIndirectState
203 //!         Size of indirect state. Ignore if bUseSizeOfResource == true.
204 //! \return void
205 //!         No return value. Handle all exception inside the function.
206 //!
OnIndirectState(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,void * pMosResource,uint32_t offsetOfIndirectState,bool bUseSizeOfResource,uint32_t sizeOfIndirectState)207 void HalOcaInterfaceNext::OnIndirectState(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext, void *pMosResource, uint32_t offsetOfIndirectState, bool bUseSizeOfResource, uint32_t sizeOfIndirectState)
208 {
209     MosInterface::SetObjectCapture((PMOS_RESOURCE)pMosResource);
210 }
211 
212 //!
213 //! \brief  Oca operation which should be called before adding dispatch states,
214 //!         e.g. VEB_DI_IECP_STATE and MEDIA_OBJECT_WALKER.
215 //! \param  [in] cmdBuffer
216 //!         Command buffer for current BB.
217 //! \param  [in] mosContext
218 //!         Reference to MOS_CONTEXT.
219 //! \param  [in] miItf
220 //!         Reference to Mhw MiItf.
221 //! \param  [in] mmioRegisters
222 //!         mmio registers for current engine.
223 //! \return void
224 //!         No return value. Handle all exception inside the function.
225 //!
OnDispatch(MOS_COMMAND_BUFFER & cmdBuffer,MOS_INTERFACE & osInterface,std::shared_ptr<mhw::mi::Itf> miItf,MHW_MI_MMIOREGISTERS & mmioRegisters)226 void HalOcaInterfaceNext::OnDispatch(MOS_COMMAND_BUFFER &cmdBuffer, MOS_INTERFACE &osInterface, std::shared_ptr<mhw::mi::Itf> miItf, MHW_MI_MMIOREGISTERS &mmioRegisters)
227 {
228     MOS_CONTEXT &mosContext = *osInterface.pOsContext;
229     AddRTLogReource(cmdBuffer, (MOS_CONTEXT_HANDLE)&mosContext, osInterface);
230 }
231 
232 //!
233 //! \brief  Add string to oca log section
234 //! \param  [in] cmdBuffer
235 //!         Command buffer for current BB.
236 //! \param  [in] mosContext
237 //!         Reference to MOS_CONTEXT.
238 //! \param  [in] str
239 //!         string to be added.
240 //! \param  [in] maxCount
241 //!         size of the buffer pointed by str.
242 //! \return void
243 //!         No return value. Handle all exception inside the function.
244 //!
TraceMessage(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,const char * str,uint32_t maxCount)245 void HalOcaInterfaceNext::TraceMessage(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext, const char *str, uint32_t maxCount)
246 {
247     MosOcaInterface *pOcaInterface          = &MosOcaInterfaceSpecific::GetInstance();
248     MOS_OCA_BUFFER_HANDLE   ocaBufHandle    = 0;
249     MOS_STATUS              status          = MOS_STATUS_SUCCESS;
250 
251     if (nullptr == pOcaInterface || !((MosOcaInterfaceSpecific*)pOcaInterface)->IsOcaEnabled())
252     {
253         return;
254     }
255     if ((ocaBufHandle = GetOcaBufferHandle(cmdBuffer, mosContext)) == MOS_OCA_INVALID_BUFFER_HANDLE)
256     {
257         // May come here for workloads not enabling UMD_OCA.
258         return;
259     }
260 
261     status = pOcaInterface->TraceMessage(ocaBufHandle, (PMOS_CONTEXT)mosContext, str, maxCount);
262     if (MOS_FAILED(status))
263     {
264         OnOcaError(mosContext, status, __FUNCTION__, __LINE__);
265     }
266 }
267 
268 //!
269 //! \brief  Add vp kernel info to oca log section.
270 //! \param  [in] cmdBuffer
271 //!         Command buffer for current BB.
272 //! \param  [in] osInterface
273 //!         Reference to MOS_INTERFACE.
274 //! \param  [in] res
275 //!         Reference to MOS_RESOURCE.
276 //! \param  [in] hwCmdType
277 //!         Hw command type.
278 //! \param  [in] locationInCmd
279 //!         Location in command.
280 //! \param  [in] offsetInRes
281 //!         Offset in resource.
282 //! \return void
283 //!         No return value. Handle all exception inside the function.
284 //!
DumpResourceInfo(MOS_COMMAND_BUFFER & cmdBuffer,MOS_INTERFACE & osInterface,MOS_RESOURCE & res,MOS_HW_COMMAND hwCmdType,uint32_t locationInCmd,uint32_t offsetInRes)285 void HalOcaInterfaceNext::DumpResourceInfo(MOS_COMMAND_BUFFER &cmdBuffer, MOS_INTERFACE &osInterface, MOS_RESOURCE &res, MOS_HW_COMMAND hwCmdType, uint32_t locationInCmd, uint32_t offsetInRes)
286 {
287     if (nullptr == osInterface.pOsContext)
288     {
289         OnOcaError(nullptr, MOS_STATUS_INVALID_PARAMETER, __FUNCTION__, __LINE__);
290         return;
291     }
292 
293     MOS_CONTEXT &           mosContext      = *osInterface.pOsContext;
294     MosOcaInterface         *pOcaInterface  = &MosOcaInterfaceSpecific::GetInstance();
295     MOS_STATUS              status          = MOS_STATUS_SUCCESS;
296     MOS_OCA_BUFFER_HANDLE   ocaBufHandle    = 0;
297 
298     if (nullptr == pOcaInterface || !((MosOcaInterfaceSpecific*)pOcaInterface)->IsOcaEnabled())
299     {
300         return;
301     }
302 
303     if ((ocaBufHandle = GetOcaBufferHandle(cmdBuffer, (MOS_CONTEXT_HANDLE)&mosContext)) == MOS_OCA_INVALID_BUFFER_HANDLE)
304     {
305         // May come here for workloads not enabling UMD_OCA.
306         return;
307     }
308 
309     if (Mos_ResourceIsNull(&res))
310     {
311         OnOcaError(&mosContext, MOS_STATUS_INVALID_PARAMETER, __FUNCTION__, __LINE__);
312         return;
313     }
314 
315     status = pOcaInterface->AddResourceToDumpList(ocaBufHandle, &mosContext, res, hwCmdType, locationInCmd, offsetInRes);
316     if (MOS_FAILED(status))
317     {
318         OnOcaError(&mosContext, status, __FUNCTION__, __LINE__);
319     }
320 }
321 
322     //!
323 //! \brief  Trace OCA Sku Value.
324 //! \param  [in] cmdBuffer
325 //!         Command buffer for current BB.
326 //! \param  [in] osInterface
327 //!         Reference to MOS_INTERFACE.
328 //! \return void
329 //!         No return value. Handle all exception inside the function.
330 //!
TraceOcaSkuValue(MOS_COMMAND_BUFFER & cmdBuffer,MOS_INTERFACE & osInterface)331 void HalOcaInterfaceNext::TraceOcaSkuValue(MOS_COMMAND_BUFFER &cmdBuffer, MOS_INTERFACE &osInterface)
332 {
333 }
334 
335 //!
336 //! \brief  Add vp kernel info to oca log section.
337 //! \param  [in] cmdBuffer
338 //!         Command buffer for current BB.
339 //! \param  [in] mosContext
340 //!         Reference to MOS_CONTEXT.
341 //! \param  [in] vpKernelID
342 //!         Value of enum VpKernelID.
343 //! \param  [in] fcKernelCount
344 //!         If vpKernelID == kernelCombinedFc, fcKernelCount is the kernel count for fc, otherwise, it's not used.
345 //! \param  [in] fcKernelList
346 //!         If vpKernelID == kernelCombinedFc, fcKernelList is the kernel list for fc, otherwise, it's not used.
347 //! \return void
348 //!         No return value. Handle all exception inside the function.
349 //!
DumpVpKernelInfo(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,int vpKernelID,int fcKernelCount,int * fcKernelList)350 void HalOcaInterfaceNext::DumpVpKernelInfo(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext, int vpKernelID, int fcKernelCount, int *fcKernelList)
351 {
352     MosOcaInterface *pOcaInterface          = &MosOcaInterfaceSpecific::GetInstance();
353     MOS_STATUS              status          = MOS_STATUS_SUCCESS;
354     MOS_OCA_BUFFER_HANDLE   ocaBufHandle    = 0;
355     uint32_t                updateSize      = 0;
356 
357     if (nullptr == pOcaInterface || !((MosOcaInterfaceSpecific*)pOcaInterface)->IsOcaEnabled())
358     {
359         return;
360     }
361 
362     if ((ocaBufHandle = GetOcaBufferHandle(cmdBuffer, mosContext)) == MOS_OCA_INVALID_BUFFER_HANDLE)
363     {
364         // May come here for workloads not enabling UMD_OCA.
365         return;
366     }
367 
368     if (kernelCombinedFc == vpKernelID && (fcKernelCount <= 0 || nullptr == fcKernelList))
369     {
370         OnOcaError(mosContext, MOS_STATUS_INVALID_PARAMETER, __FUNCTION__, __LINE__);
371         return;
372     }
373 
374     if (kernelCombinedFc != vpKernelID)
375     {
376         fcKernelCount = 0;
377         fcKernelList = nullptr;
378     }
379 
380     MOS_OCA_LOG_HEADER_VP_KERNEL_INFO header = {};
381     header.header.type                      = MOS_OCA_LOG_TYPE_VP_KERNEL_INFO;
382     header.header.headerSize                = sizeof(MOS_OCA_LOG_HEADER_VP_KERNEL_INFO);
383     header.header.dataSize                  = fcKernelCount * sizeof(int);
384     header.vpKernelID                       = vpKernelID;
385     header.fcKernelCount                    = fcKernelCount;
386     status = pOcaInterface->DumpDataBlock(ocaBufHandle, (PMOS_CONTEXT)mosContext, (PMOS_OCA_LOG_HEADER)&header, fcKernelList);
387     if (MOS_FAILED(status))
388     {
389         OnOcaError(mosContext, status, __FUNCTION__, __LINE__);
390     }
391 }
392 
393 //!
394 //! \brief  Add vp kernel info to oca log section.
395 //! \param  [in] cmdBuffer
396 //!         Command buffer for current BB.
397 //! \param  [in] mosContext
398 //!         Reference to MOS_CONTEXT.
399 //! \param  [in] pControlValues
400 //!         Value of user features.
401 //! \return void
402 //!         No return value. Handle all exception inside the function.
403 //!
DumpVpUserFeautreControlInfo(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,PMOS_OCA_LOG_USER_FEATURE_CONTROL_INFO pControlValues)404 void HalOcaInterfaceNext::DumpVpUserFeautreControlInfo(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext, PMOS_OCA_LOG_USER_FEATURE_CONTROL_INFO pControlValues)
405 {
406     MosOcaInterface      *pOcaInterface = &MosOcaInterfaceSpecific::GetInstance();
407     MOS_STATUS            status        = MOS_STATUS_SUCCESS;
408     MOS_OCA_BUFFER_HANDLE hOcaBuf       = 0;
409 
410     if (nullptr == pOcaInterface || (hOcaBuf = GetOcaBufferHandle(cmdBuffer, mosContext)) == MOS_OCA_INVALID_BUFFER_HANDLE)
411     {
412         // Will come here for UMD_OCA not being enabled case.
413         return;
414     }
415 
416     MOS_OCA_LOG_HEADER header                           = {};
417     header.type                                         = MOS_OCA_LOG_TYPE_VP_USER_FEATURE_CONTROL_INFO;
418     header.headerSize                                   = sizeof(MOS_OCA_LOG_HEADER);
419     header.dataSize                                     = sizeof(MOS_OCA_LOG_USER_FEATURE_CONTROL_INFO);
420 
421     status = pOcaInterface->DumpDataBlock(hOcaBuf, (PMOS_CONTEXT)mosContext, (PMOS_OCA_LOG_HEADER)&header, pControlValues);
422     if (MOS_FAILED(status))
423     {
424         OnOcaError(mosContext, status, __FUNCTION__, __LINE__);
425     }
426 }
427 
428 //!
429 //! \brief  Add vphal parameters to oca log section.
430 //! \param  [in] mosContext
431 //!         Reference to MOS_CONTEXT.
432 //! \param  [in] pVphalDumper
433 //!         Pointer to vphal dumper object.
434 //! \return void
435 //!         No return value. Handle all exception inside the function.
436 //!
DumpVphalParam(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,void * pVphalDumper)437 void HalOcaInterfaceNext::DumpVphalParam(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext, void *pVphalDumper)
438 {
439     MosOcaInterface *pOcaInterface       = &MosOcaInterfaceSpecific::GetInstance();
440     MOS_STATUS status                    = MOS_STATUS_SUCCESS;
441     MOS_OCA_BUFFER_HANDLE ocaBufHandle   = 0;
442     uint32_t updateSize                  = 0;
443 
444     if (nullptr == pOcaInterface                                   ||
445         !((MosOcaInterfaceSpecific*)pOcaInterface)->IsOcaEnabled() ||
446         nullptr == pVphalDumper)
447     {
448         return;
449     }
450     if ((ocaBufHandle = GetOcaBufferHandle(cmdBuffer, mosContext)) == MOS_OCA_INVALID_BUFFER_HANDLE)
451     {
452         // May come here for workloads not enabling UMD_OCA.
453         return;
454     }
455 
456     VPHAL_OCA_RENDER_PARAM *pVphalParam = ((VphalOcaDumper *)pVphalDumper)->GetRenderParam();
457     if (nullptr == pVphalParam)
458     {
459         return;
460     }
461 
462     MOS_OCA_LOG_HEADER_VPHAL_PARAM header = {};
463     header.header.type                = MOS_OCA_LOG_TYPE_VPHAL_PARAM;  // 00000003
464     header.header.headerSize          = sizeof(MOS_OCA_LOG_HEADER_VPHAL_PARAM);
465     header.header.dataSize            = pVphalParam->Header.size;
466     status = pOcaInterface->DumpDataBlock(ocaBufHandle, (PMOS_CONTEXT)mosContext, (PMOS_OCA_LOG_HEADER)&header, pVphalParam);
467     if (MOS_FAILED(status))
468     {
469         OnOcaError(mosContext, status, __FUNCTION__, __LINE__);
470     }
471 }
472 
473 //!
474 //! \brief  Add codechal parameters to oca log section.
475 //! \param  [in] cmdBuffer
476 //!         Command buffer for current BB.
477 //! \param  [in] mosContext
478 //!         Reference to MOS_CONTEXT.
479 //! \param  [in] pCodechalDumper
480 //!         Pointer to codechal dumper object.
481 //! \return void
482 //!         No return value. Handle all exception inside the function.
483 //!
DumpCodechalParam(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,void * pCodechalDumper,CODECHAL_STANDARD codec)484 void HalOcaInterfaceNext::DumpCodechalParam(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext, void *pCodechalDumper, CODECHAL_STANDARD codec)
485 {
486     MosOcaInterface *pOcaInterface       = &MosOcaInterfaceSpecific::GetInstance();
487     MOS_STATUS status                    = MOS_STATUS_SUCCESS;
488     MOS_OCA_BUFFER_HANDLE ocaBufHandle   = 0;
489     uint32_t updateSize                  = 0;
490 
491     if (nullptr == pOcaInterface                                   ||
492         !((MosOcaInterfaceSpecific*)pOcaInterface)->IsOcaEnabled() ||
493         nullptr == pCodechalDumper)
494     {
495         return;
496     }
497     if ((ocaBufHandle = GetOcaBufferHandle(cmdBuffer, mosContext)) == MOS_OCA_INVALID_BUFFER_HANDLE)
498     {
499         // May come here for workloads not enabling UMD_OCA.
500         return;
501     }
502 
503     CODECHAL_OCA_DECODE_HEADER *pCodechalParam = ((CodechalOcaDumper *)pCodechalDumper)->GetDecodeParam();
504     if (nullptr == pCodechalParam)
505     {
506         return;
507     }
508 
509     MOS_OCA_LOG_HEADER_CODECHAL_PARAM header = {};
510     header.header.type                       = MOS_OCA_LOG_TYPE_CODECHAL_PARAM;  // 00000007
511     header.header.headerSize                 = sizeof(MOS_OCA_LOG_HEADER_CODECHAL_PARAM);
512     header.header.dataSize                   = pCodechalParam->Header.size;
513     header.codec                             = (uint32_t)codec;
514     status = pOcaInterface->DumpDataBlock(ocaBufHandle, (PMOS_CONTEXT)mosContext, (PMOS_OCA_LOG_HEADER)&header, pCodechalParam);
515 
516     if (MOS_FAILED(status))
517     {
518         OnOcaError(mosContext, status, __FUNCTION__, __LINE__);
519     }
520 }
521 
IsLargeResouceDumpSupported()522 bool HalOcaInterfaceNext::IsLargeResouceDumpSupported()
523 {
524     return true;
525 }
526 
AddRTLogReource(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,MOS_INTERFACE & osInterface)527 void HalOcaInterfaceNext::AddRTLogReource(MOS_COMMAND_BUFFER &cmdBuffer,
528                                MOS_CONTEXT_HANDLE mosContext,
529                                MOS_INTERFACE &osInterface)
530 {
531     if (!MosOcaRTLogMgr::IsOcaRTLogEnabled())
532     {
533         return;
534     }
535     MOS_STATUS status = MOS_STATUS_SUCCESS;
536     PMOS_RESOURCE osResource = nullptr;
537     uint32_t size = 0;
538     if (!osInterface.osStreamState)
539     {
540         return;
541     }
542     osInterface.pfnGetRtLogResourceInfo(&osInterface, osResource, size);
543     if(osResource == nullptr || size == 0)
544     {
545         return;
546     }
547 
548     MOS_LINUX_BO *bo = cmdBuffer.OsResource.bo;
549     if (bo == nullptr ||
550         bo->virt == nullptr ||
551         bo->size <= OCA_LOG_SECTION_SIZE_MAX)
552     {
553         return;
554     }
555     OCA_LOG_SECTION_HEADER *header = (OCA_LOG_SECTION_HEADER *)((uint64_t)bo->virt + bo->size - OCA_LOG_SECTION_SIZE_MAX);
556     if (header->magicNum != OCA_LOG_SECTION_MAGIC_NUMBER)
557     {
558         return;
559     }
560     MHW_RESOURCE_PARAMS ResourceParams = {};
561 
562     ResourceParams.dwOffset = 0;
563     uint32_t cmd = 0;
564     ResourceParams.presResource = osResource;
565     ResourceParams.pdwCmd = &cmd;
566     // Align logic in Mhw_AddResourceToCmd
567     ResourceParams.dwLocationInCmd = ((int32_t)((uint8_t*)&header->rtlogPatchAddr - (uint8_t*)cmdBuffer.pCmdBase) - cmdBuffer.iOffset) / sizeof(uint32_t);
568     ResourceParams.HwCommandType = MOS_OCA_RESERVED;
569     ResourceParams.dwSharedMocsOffset = 1 - ResourceParams.dwLocationInCmd;
570 
571     if (osInterface.bUsesGfxAddress)
572     {
573         status = Mhw_AddResourceToCmd_GfxAddress(&osInterface, &cmdBuffer, &ResourceParams);
574     }
575     else
576     {
577         status = Mhw_AddResourceToCmd_PatchList(&osInterface, &cmdBuffer, &ResourceParams);
578     }
579 
580     if (MOS_FAILED(status))
581     {
582         OnOcaError(mosContext, status, __FUNCTION__, __LINE__);
583     }
584     HalOcaInterfaceNext::OnIndirectState(cmdBuffer, mosContext, osResource, 0, false, size);
585 }
586 
DumpCpParam(MosOcaInterface & ocaInterface,MOS_OCA_BUFFER_HANDLE & ocaBufHandle,PMOS_CONTEXT mosCtx,void * pCpDumper)587 void HalOcaInterfaceNext::DumpCpParam(MosOcaInterface &ocaInterface, MOS_OCA_BUFFER_HANDLE &ocaBufHandle, PMOS_CONTEXT mosCtx, void *pCpDumper)
588 {
589 }
590 
DumpCpIoMsg(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext,void * pCpDumper,int type)591 void HalOcaInterfaceNext::DumpCpIoMsg(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext, void *pCpDumper, int type)
592 {
593 }
594 
OnOcaError(MOS_CONTEXT_HANDLE mosCtx,MOS_STATUS status,const char * functionName,uint32_t lineNumber)595 void HalOcaInterfaceNext::OnOcaError(MOS_CONTEXT_HANDLE mosCtx, MOS_STATUS status, const char *functionName, uint32_t lineNumber)
596 {
597     MosOcaInterfaceSpecific::OnOcaError((PMOS_CONTEXT)mosCtx, status, functionName, lineNumber);
598 }
599 
GetOcaBufferHandle(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT_HANDLE mosContext)600 MOS_OCA_BUFFER_HANDLE HalOcaInterfaceNext::GetOcaBufferHandle(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT_HANDLE mosContext)
601 {
602     MosOcaInterface *pOcaInterface = &MosOcaInterfaceSpecific::GetInstance();
603     if(pOcaInterface == nullptr)
604     {
605         OnOcaError(mosContext, MOS_STATUS_NULL_POINTER, __FUNCTION__, __LINE__);
606         return MOS_OCA_INVALID_BUFFER_HANDLE;
607     }
608 
609     return pOcaInterface->GetOcaBufHandleFromMap(cmdBuffer.pCmdBase);
610 }
611 
RemoveOcaBufferHandle(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT & mosContext)612 void HalOcaInterfaceNext::RemoveOcaBufferHandle(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT &mosContext)
613 {
614     MosOcaInterface *pOcaInterface       = &MosOcaInterfaceSpecific::GetInstance();
615     if(pOcaInterface == nullptr)
616     {
617         OnOcaError(&mosContext, MOS_STATUS_NULL_POINTER, __FUNCTION__, __LINE__);
618         return;
619     }
620     pOcaInterface->RemoveOcaBufHandleFromMap(cmdBuffer.pCmdBase);
621 }
622 
623 //!
624 //! \brief  Oca operation which should be called at the beginning of 1st level batch buffer start.
625 //! \param  [in/out] cmdBuffer
626 //!         Command buffer for current BB. ocaBufHandle in cmdBuffer will be updated.
627 //! \param  [in] mosContext
628 //!         Reference to MOS_CONTEXT.
629 //! \param  [in] gpuContextHandle
630 //!         Gpu context handle
631 //! \return void
632 //!         No return value. Handle all exception inside the function.
633 //!
On1stLevelBBStart(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT & mosContext,uint32_t gpuContextHandle)634 void HalOcaInterfaceNext::On1stLevelBBStart(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT &mosContext,
635         uint32_t gpuContextHandle)
636 {
637     MosInterface::SetObjectCapture(&cmdBuffer.OsResource);
638     MOS_STATUS status                   = MOS_STATUS_SUCCESS;
639     MosOcaInterface *pOcaInterface      = &MosOcaInterfaceSpecific::GetInstance();
640     MOS_OCA_BUFFER_HANDLE ocaBufHandle  = 0;
641     uint64_t  ocaBase                   = 0;
642 
643     if (nullptr == pOcaInterface || !((MosOcaInterfaceSpecific*)pOcaInterface)->IsOcaEnabled())
644     {
645         return;
646     }
647 
648     ocaBufHandle = GetOcaBufferHandle(cmdBuffer, (MOS_CONTEXT_HANDLE)&mosContext);
649     if (ocaBufHandle != MOS_OCA_INVALID_BUFFER_HANDLE)
650     {
651         // will come here when On1stLevelBBStart being called twice without On1stLevelBBEnd being called.
652         OnOcaError(&mosContext, MOS_STATUS_INVALID_PARAMETER, __FUNCTION__, __LINE__);
653         return;
654     }
655     else
656     {
657         ocaBufHandle = pOcaInterface->LockOcaBufAvailable(&mosContext, gpuContextHandle);
658 
659         if (MOS_OCA_INVALID_BUFFER_HANDLE == ocaBufHandle)
660         {
661             OnOcaError(&mosContext, MOS_STATUS_INVALID_HANDLE, __FUNCTION__, __LINE__);
662             return;
663         }
664         if (MOS_FAILED(pOcaInterface->InsertOcaBufHandleMap(cmdBuffer.pCmdBase, ocaBufHandle)))
665         {
666             OnOcaError(&mosContext, MOS_STATUS_INVALID_HANDLE, __FUNCTION__, __LINE__);
667             return;
668         }
669     }
670 
671     status = pOcaInterface->On1stLevelBBStart(ocaBase, ocaBufHandle, &mosContext, &cmdBuffer.OsResource, 0, true, 0);
672     if (MOS_FAILED(status))
673     {
674         RemoveOcaBufferHandle(cmdBuffer, mosContext);
675         OnOcaError(&mosContext, status, __FUNCTION__, __LINE__);
676     }
677 }
678 
679 /****************************************************************************************************/
680 /*                         Private functions to ensure class singleton.                             */
681 /****************************************************************************************************/
HalOcaInterfaceNext()682 HalOcaInterfaceNext::HalOcaInterfaceNext()
683 {
684 }
685 
HalOcaInterfaceNext(HalOcaInterfaceNext &)686 HalOcaInterfaceNext::HalOcaInterfaceNext(HalOcaInterfaceNext &)
687 {
688 }
689 
operator =(HalOcaInterfaceNext &)690 HalOcaInterfaceNext& HalOcaInterfaceNext::operator= (HalOcaInterfaceNext &)
691 {
692     return *this;
693 }
694