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