xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/hw/mhw_mi_generic.h (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2015-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 //! \file     mhw_mi_generic.h
24 //! \brief    MHW interface templates for MI and generic flush commands across all engines
25 //! \details  Impelements shared HW command construction functions across all platforms as templates
26 //!
27 
28 #ifndef __MHW_MI_GENERIC_H__
29 #define __MHW_MI_GENERIC_H__
30 
31 #include "mhw_mi.h"
32 #include "mhw_cp_interface.h"
33 #include "mos_os_cp_interface_specific.h"
34 
35 template <class TMiCmds>
36 class MhwMiInterfaceGeneric : public MhwMiInterface
37 {
38 private:
39     enum AtomicOpCode
40     {
41         atomicInvalid = 0,
42         atomicAnd = 1,
43         atomicOr = 2,
44         atomicXor = 3,
45         atomicMove = 4,
46         atomicInc = 5,
47         atomicDec = 6,
48         atomicAdd = 7,
49         atomicSub = 8,
50         atomicRSub = 9,
51         atomicIMax = 10,
52         atomicIMin = 11,
53         atomicUMax = 12,
54         atomicUMin = 13,
55         atomicCmp = 14,
56         atomicDword = 0,
57         atomicQword = 0x20,
58         atomicOctword = 0x40,
59     };
60 
61     //!
62     //! \brief    Helper function to compose opcode for MI_ATOMIC
63     //! \return   uint32_t
64     //!           Composed opcode for MI_ATOMIC or 0
65     //!
CreateMiAtomicOpcode(uint32_t dataSize,MHW_COMMON_MI_ATOMIC_OPCODE opCode)66     uint32_t CreateMiAtomicOpcode(
67         uint32_t                    dataSize,
68         MHW_COMMON_MI_ATOMIC_OPCODE opCode)
69     {
70         uint32_t formattedOpCode = dataSize;
71 
72         switch (opCode) {
73         case MHW_MI_ATOMIC_AND:
74             formattedOpCode += atomicAnd;
75             break;
76         case MHW_MI_ATOMIC_OR:
77             formattedOpCode += atomicOr;
78             break;
79         case MHW_MI_ATOMIC_XOR:
80             formattedOpCode += atomicXor;
81             break;
82         case MHW_MI_ATOMIC_MOVE:
83             formattedOpCode += atomicMove;
84             break;
85         case MHW_MI_ATOMIC_INC:
86             formattedOpCode += atomicInc;
87             break;
88         case MHW_MI_ATOMIC_DEC:
89             formattedOpCode += atomicDec;
90             break;
91         case MHW_MI_ATOMIC_ADD:
92             formattedOpCode += atomicAdd;
93             break;
94         case MHW_MI_ATOMIC_SUB:
95             formattedOpCode += atomicSub;
96             break;
97         case MHW_MI_ATOMIC_RSUB:
98             formattedOpCode += atomicRSub;
99             break;
100         case MHW_MI_ATOMIC_IMAX:
101             formattedOpCode += atomicIMax;
102             break;
103         case MHW_MI_ATOMIC_IMIN:
104             formattedOpCode += atomicIMin;
105             break;
106         case MHW_MI_ATOMIC_UMAX:
107             formattedOpCode += atomicUMax;
108             break;
109         case MHW_MI_ATOMIC_UMIN:
110             formattedOpCode += atomicUMin;
111             break;
112         case MHW_MI_ATOMIC_CMP:
113             formattedOpCode += atomicCmp;
114             break;
115         default:
116             formattedOpCode = atomicInvalid;
117             break;
118         }
119 
120         return formattedOpCode;
121     }
122 
SendMarkerCommand(PMOS_COMMAND_BUFFER cmdBuffer,bool isRender)123     MOS_STATUS SendMarkerCommand(
124         PMOS_COMMAND_BUFFER cmdBuffer,
125         bool isRender)
126     {
127         MOS_STATUS      eStatus     = MOS_STATUS_SUCCESS;
128         PMOS_RESOURCE   resMarker   = nullptr;
129 
130         MHW_FUNCTION_ENTER;
131 
132         resMarker = m_osInterface->pfnGetMarkerResource(m_osInterface);
133         MHW_CHK_NULL_RETURN(resMarker);
134 
135         if (isRender)
136         {
137             // Send pipe_control to get the timestamp
138             MHW_PIPE_CONTROL_PARAMS             pipeControlParams;
139             MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams));
140             pipeControlParams.presDest          = resMarker;
141             pipeControlParams.dwResourceOffset  = sizeof(uint64_t);
142             pipeControlParams.dwPostSyncOp      = MHW_FLUSH_WRITE_TIMESTAMP_REG;
143             pipeControlParams.dwFlushMode       = MHW_FLUSH_WRITE_CACHE;
144 
145             MHW_MI_CHK_STATUS(AddPipeControl(cmdBuffer, NULL, &pipeControlParams));
146         }
147         else
148         {
149             // Send flush_dw to get the timestamp
150             MHW_MI_FLUSH_DW_PARAMS  flushDwParams;
151             MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
152             flushDwParams.pOsResource           = resMarker;
153             flushDwParams.dwResourceOffset      = sizeof(uint64_t);
154             flushDwParams.postSyncOperation     = MHW_FLUSH_WRITE_TIMESTAMP_REG;
155             flushDwParams.bQWordEnable          = 1;
156 
157             MHW_MI_CHK_STATUS(AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
158         }
159         if (!m_osInterface->apoMosEnabled)
160         {
161             MOS_SafeFreeMemory(resMarker);
162         }
163         return eStatus;
164     }
165 
166 protected:
MhwMiInterfaceGeneric(MhwCpInterface * cpInterface,PMOS_INTERFACE osInterface)167     MhwMiInterfaceGeneric(
168         MhwCpInterface      *cpInterface,
169         PMOS_INTERFACE      osInterface) : MhwMiInterface(cpInterface, osInterface) {}
170 
171 public:
~MhwMiInterfaceGeneric()172     virtual ~MhwMiInterfaceGeneric() { MHW_FUNCTION_ENTER; }
173 
AddMiNoop(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)174     MOS_STATUS AddMiNoop(
175         PMOS_COMMAND_BUFFER cmdBuffer,
176         PMHW_BATCH_BUFFER   batchBuffer)
177     {
178         MHW_FUNCTION_ENTER;
179 
180         if (cmdBuffer == nullptr && batchBuffer == nullptr)
181         {
182             MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
183             return MOS_STATUS_NULL_POINTER;
184         }
185 
186         typename TMiCmds::MI_NOOP_CMD cmd;
187         MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(
188             m_osInterface,
189             cmdBuffer,
190             batchBuffer,
191             &cmd,
192             cmd.byteSize));
193 
194         return MOS_STATUS_SUCCESS;
195     }
196 
AddMiBatchBufferEnd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)197     MOS_STATUS AddMiBatchBufferEnd(
198         PMOS_COMMAND_BUFFER             cmdBuffer,
199         PMHW_BATCH_BUFFER               batchBuffer)
200     {
201         MHW_FUNCTION_ENTER;
202 
203         if (cmdBuffer == nullptr && batchBuffer == nullptr)
204         {
205             MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
206             return MOS_STATUS_NULL_POINTER;
207         }
208 
209         auto waTable = m_osInterface->pfnGetWaTable(m_osInterface);
210         MHW_MI_CHK_NULL(waTable);
211 
212         // This WA does not apply for video or other engines, render requirement only
213         bool isRender =
214             MOS_RCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface));
215 
216         if (isRender &&
217             (MEDIA_IS_WA(waTable, WaMSFWithNoWatermarkTSGHang) ||
218             MEDIA_IS_WA(waTable, WaAddMediaStateFlushCmd)))
219         {
220             MHW_MI_CHK_STATUS(AddMediaStateFlush(cmdBuffer, batchBuffer));
221         }
222 
223         // Mhw_CommonMi_AddMiBatchBufferEnd() is designed to handle both 1st level
224         // and 2nd level BB.  It inserts MI_BATCH_BUFFER_END in both cases.
225         // However, since the 2nd level BB always returens to the 1st level BB and
226         // no chained BB scenario in Media, Epilog is only needed in the 1st level BB.
227         // Therefre, here only the 1st level BB case needs an Epilog inserted.
228         if (cmdBuffer && cmdBuffer->is1stLvlBB)
229         {
230             MHW_MI_CHK_STATUS(m_cpInterface->AddEpilog(m_osInterface, cmdBuffer));
231         }
232 
233         typename TMiCmds::MI_BATCH_BUFFER_END_CMD cmd;
234         MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(
235             m_osInterface,
236             cmdBuffer,
237             batchBuffer,
238             &cmd,
239             cmd.byteSize));
240 
241         if (!cmdBuffer) // Don't need BB not nullptr chk b/c if both are nullptr it won't get this far
242         {
243     #if (_DEBUG || _RELEASE_INTERNAL)
244             batchBuffer->iLastCurrent = batchBuffer->iCurrent;
245     #endif
246         }
247 
248         // Send End Marker command
249         if (m_osInterface->pfnIsSetMarkerEnabled(m_osInterface) && cmdBuffer && cmdBuffer->is1stLvlBB)
250         {
251             MHW_MI_CHK_STATUS(SendMarkerCommand(
252                 cmdBuffer, MOS_RCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface))));
253         }
254 
255         MHW_MI_CHK_STATUS(m_osInterface->osCpInterface->PermeateBBPatchForHM());
256 
257         return MOS_STATUS_SUCCESS;
258     }
259 
AddMiBatchBufferEndOnly(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)260     MOS_STATUS AddMiBatchBufferEndOnly(
261         PMOS_COMMAND_BUFFER             cmdBuffer,
262         PMHW_BATCH_BUFFER               batchBuffer)
263     {
264         MHW_FUNCTION_ENTER;
265 
266         if (cmdBuffer == nullptr && batchBuffer == nullptr)
267         {
268             MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
269             return MOS_STATUS_NULL_POINTER;
270         }
271 
272         // Mhw_CommonMi_AddMiBatchBufferEnd() is designed to handle both 1st level
273         // and 2nd level BB.  It inserts MI_BATCH_BUFFER_END in both cases.
274         // However, since the 2nd level BB always returens to the 1st level BB and
275         // no chained BB scenario in Media, Epilog is only needed in the 1st level BB.
276         // Therefre, here only the 1st level BB case needs an Epilog inserted.
277         if (cmdBuffer && cmdBuffer->is1stLvlBB)
278         {
279             MHW_MI_CHK_STATUS(m_cpInterface->AddEpilog(m_osInterface, cmdBuffer));
280         }
281 
282         typename TMiCmds::MI_BATCH_BUFFER_END_CMD cmd;
283         MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(
284             m_osInterface,
285             cmdBuffer,
286             batchBuffer,
287             &cmd,
288             cmd.byteSize));
289 
290         if (!cmdBuffer) // Don't need BB not nullptr chk b/c if both are nullptr it won't get this far
291         {
292     #if (_DEBUG || _RELEASE_INTERNAL)
293             batchBuffer->iLastCurrent = batchBuffer->iCurrent;
294     #endif
295         }
296 
297         // Send End Marker command
298         if (m_osInterface->pfnIsSetMarkerEnabled(m_osInterface) && cmdBuffer && cmdBuffer->is1stLvlBB)
299         {
300             MHW_MI_CHK_STATUS(SendMarkerCommand(
301                 cmdBuffer, MOS_RCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface))));
302         }
303 
304         return MOS_STATUS_SUCCESS;
305     }
306 
AddMiStoreDataImmCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_STORE_DATA_PARAMS params)307     MOS_STATUS AddMiStoreDataImmCmd(
308         PMOS_COMMAND_BUFFER         cmdBuffer,
309         PMHW_MI_STORE_DATA_PARAMS   params)
310     {
311         MHW_FUNCTION_ENTER;
312 
313         MHW_MI_CHK_NULL(m_osInterface);
314         MHW_MI_CHK_NULL(cmdBuffer);
315         MHW_MI_CHK_NULL(params);
316         MHW_MI_CHK_NULL(params->pOsResource);
317 
318         typename TMiCmds::MI_STORE_DATA_IMM_CMD cmd;
319         MHW_RESOURCE_PARAMS                 resourceParams;
320         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
321         resourceParams.presResource     = params->pOsResource;
322         resourceParams.dwOffset         = params->dwResourceOffset;
323         resourceParams.pdwCmd           = cmd.DW1_2.Value;
324         resourceParams.dwLocationInCmd  = 1;
325         resourceParams.dwLsbNum         = MHW_COMMON_MI_STORE_DATA_DW_SHIFT;
326         resourceParams.HwCommandType    = MOS_MI_STORE_DATA_IMM;
327         resourceParams.bIsWritable      = true;
328 
329         MHW_MI_CHK_STATUS(AddResourceToCmd(
330             m_osInterface,
331             cmdBuffer,
332             &resourceParams));
333 
334         cmd.DW0.UseGlobalGtt = IsGlobalGttInUse();
335         // Force single DW write, driver never writes a QW
336         cmd.DW0.StoreQword = 0;
337         cmd.DW0.DwordLength--;
338 
339         cmd.DW3.DataDword0 = params->dwValue;
340 
341         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
342 
343         return MOS_STATUS_SUCCESS;
344     }
345 
AddMiFlushDwCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_FLUSH_DW_PARAMS params)346     MOS_STATUS AddMiFlushDwCmd(
347         PMOS_COMMAND_BUFFER         cmdBuffer,
348         PMHW_MI_FLUSH_DW_PARAMS     params)
349     {
350         MHW_FUNCTION_ENTER;
351 
352         MHW_MI_CHK_NULL(cmdBuffer);
353         MHW_MI_CHK_NULL(params);
354 
355         return MOS_STATUS_SUCCESS;
356     }
357 
AddMiCopyMemMemCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_COPY_MEM_MEM_PARAMS params)358     MOS_STATUS AddMiCopyMemMemCmd(
359         PMOS_COMMAND_BUFFER                 cmdBuffer,
360         PMHW_MI_COPY_MEM_MEM_PARAMS         params)
361     {
362         MHW_FUNCTION_ENTER;
363 
364         MHW_MI_CHK_NULL(m_osInterface);
365         MHW_MI_CHK_NULL(cmdBuffer);
366         MHW_MI_CHK_NULL(params);
367         MHW_MI_CHK_NULL(params->presSrc);
368         MHW_MI_CHK_NULL(params->presDst);
369 
370         typename TMiCmds::MI_COPY_MEM_MEM_CMD cmd;
371         cmd.DW0.UseGlobalGttDestination = IsGlobalGttInUse();
372         cmd.DW0.UseGlobalGttSource      = IsGlobalGttInUse();
373 
374         MHW_RESOURCE_PARAMS resourceParams;
375         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
376         resourceParams.presResource     = params->presDst;
377         resourceParams.dwOffset         = params->dwDstOffset;
378         resourceParams.pdwCmd           = cmd.DW1_2.Value;
379         resourceParams.dwLocationInCmd  = 1;
380         resourceParams.dwLsbNum         = MHW_COMMON_MI_GENERAL_SHIFT;
381         resourceParams.HwCommandType    = MOS_MI_COPY_MEM_MEM;
382         resourceParams.bIsWritable      = true;
383 
384         MHW_MI_CHK_STATUS(AddResourceToCmd(
385             m_osInterface,
386             cmdBuffer,
387             &resourceParams));
388 
389         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
390         resourceParams.presResource     = params->presSrc;
391         resourceParams.dwOffset         = params->dwSrcOffset;
392         resourceParams.pdwCmd           = cmd.DW3_4.Value;
393         resourceParams.dwLocationInCmd  = 3;
394         resourceParams.dwLsbNum         = MHW_COMMON_MI_GENERAL_SHIFT;
395         resourceParams.HwCommandType    = MOS_MI_COPY_MEM_MEM;
396         resourceParams.bIsWritable      = false;
397 
398         MHW_MI_CHK_STATUS(AddResourceToCmd(
399             m_osInterface,
400             cmdBuffer,
401             &resourceParams));
402 
403         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
404 
405         return MOS_STATUS_SUCCESS;
406     }
407 
AddMiStoreRegisterMemCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_STORE_REGISTER_MEM_PARAMS params)408     MOS_STATUS AddMiStoreRegisterMemCmd(
409         PMOS_COMMAND_BUFFER                 cmdBuffer,
410         PMHW_MI_STORE_REGISTER_MEM_PARAMS   params)
411     {
412         MHW_FUNCTION_ENTER;
413 
414         MHW_MI_CHK_NULL(m_osInterface);
415         MHW_MI_CHK_NULL(cmdBuffer);
416         MHW_MI_CHK_NULL(params);
417         MHW_MI_CHK_NULL(params->presStoreBuffer);
418 
419         typename TMiCmds::MI_STORE_REGISTER_MEM_CMD  cmd;
420         MHW_RESOURCE_PARAMS                 resourceParams;
421         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
422         resourceParams.presResource     = params->presStoreBuffer;
423         resourceParams.dwOffset         = params->dwOffset;
424         resourceParams.pdwCmd           = cmd.DW2_3.Value;
425         resourceParams.dwLocationInCmd  = 2;
426         resourceParams.dwLsbNum         = MHW_COMMON_MI_GENERAL_SHIFT;
427         resourceParams.HwCommandType    = MOS_MI_STORE_REGISTER_MEM;
428         resourceParams.bIsWritable      = true;
429 
430         MHW_MI_CHK_STATUS(AddResourceToCmd(
431             m_osInterface,
432             cmdBuffer,
433             &resourceParams));
434 
435         cmd.DW0.UseGlobalGtt = IsGlobalGttInUse();
436         cmd.DW1.RegisterAddress = params->dwRegister >> 2;
437 
438         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
439 
440         return MOS_STATUS_SUCCESS;
441     }
442 
AddMiLoadRegisterMemCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_MEM_PARAMS params)443     MOS_STATUS AddMiLoadRegisterMemCmd(
444         PMOS_COMMAND_BUFFER                 cmdBuffer,
445         PMHW_MI_LOAD_REGISTER_MEM_PARAMS    params)
446     {
447         MHW_FUNCTION_ENTER;
448 
449         MHW_MI_CHK_NULL(m_osInterface);
450         MHW_MI_CHK_NULL(cmdBuffer);
451         MHW_MI_CHK_NULL(params);
452         MHW_MI_CHK_NULL(params->presStoreBuffer);
453 
454         typename TMiCmds::MI_LOAD_REGISTER_MEM_CMD   cmd;
455         MHW_RESOURCE_PARAMS                 resourceParams;
456         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
457         resourceParams.presResource     = params->presStoreBuffer;
458         resourceParams.dwOffset         = params->dwOffset;
459         resourceParams.pdwCmd           = cmd.DW2_3.Value;
460         resourceParams.dwLocationInCmd  = 2;
461         resourceParams.dwLsbNum         = MHW_COMMON_MI_GENERAL_SHIFT;
462         resourceParams.HwCommandType    = MOS_MI_LOAD_REGISTER_MEM;
463         resourceParams.bIsWritable      = true;
464 
465         MHW_MI_CHK_STATUS(AddResourceToCmd(
466             m_osInterface,
467             cmdBuffer,
468             &resourceParams));
469 
470         cmd.DW0.UseGlobalGtt    = IsGlobalGttInUse();
471         cmd.DW1.RegisterAddress = params->dwRegister >> 2;
472 
473         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
474 
475         return MOS_STATUS_SUCCESS;
476     }
477 
AddMiLoadRegisterImmCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_IMM_PARAMS params)478     MOS_STATUS AddMiLoadRegisterImmCmd(
479         PMOS_COMMAND_BUFFER                 cmdBuffer,
480         PMHW_MI_LOAD_REGISTER_IMM_PARAMS    params)
481     {
482         MHW_FUNCTION_ENTER;
483 
484         MHW_MI_CHK_NULL(m_osInterface);
485         MHW_MI_CHK_NULL(cmdBuffer);
486         MHW_MI_CHK_NULL(params);
487 
488         typename TMiCmds::MI_LOAD_REGISTER_IMM_CMD cmd;
489         cmd.DW1.RegisterOffset = params->dwRegister >> 2;
490         cmd.DW2.DataDword = params->dwData;
491 
492         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
493 
494         return MOS_STATUS_SUCCESS;
495     }
496 
AddMiLoadRegisterRegCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_REG_PARAMS params)497     MOS_STATUS AddMiLoadRegisterRegCmd(
498         PMOS_COMMAND_BUFFER                 cmdBuffer,
499         PMHW_MI_LOAD_REGISTER_REG_PARAMS    params)
500     {
501         MHW_FUNCTION_ENTER;
502 
503         MHW_MI_CHK_NULL(m_osInterface);
504         MHW_MI_CHK_NULL(cmdBuffer);
505         MHW_MI_CHK_NULL(params);
506 
507         typename TMiCmds::MI_LOAD_REGISTER_REG_CMD cmd;
508         cmd.DW1.SourceRegisterAddress = params->dwSrcRegister >> 2;
509         cmd.DW2.DestinationRegisterAddress = params->dwDstRegister >> 2;
510 
511         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
512 
513         return MOS_STATUS_SUCCESS;
514     }
515 
AddMiMathCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_MATH_PARAMS params)516     MOS_STATUS AddMiMathCmd(
517         PMOS_COMMAND_BUFFER      cmdBuffer,
518         PMHW_MI_MATH_PARAMS      params)
519     {
520         MHW_FUNCTION_ENTER;
521 
522         MHW_MI_CHK_NULL(m_osInterface);
523         MHW_MI_CHK_NULL(cmdBuffer);
524         MHW_MI_CHK_NULL(params);
525 
526         if (params->dwNumAluParams == 0 || params->pAluPayload == nullptr)
527         {
528             MHW_ASSERTMESSAGE("MI_MATH requires a valid payload");
529             return MOS_STATUS_INVALID_PARAMETER;
530         }
531 
532         typename TMiCmds::MI_MATH_CMD cmd;
533         cmd.DW0.DwordLength = params->dwNumAluParams - 1;
534 
535         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
536 
537         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(
538             cmdBuffer,
539             &params->pAluPayload[0],
540             sizeof(MHW_MI_ALU_PARAMS)* params->dwNumAluParams));
541 
542         return MOS_STATUS_SUCCESS;
543     }
544 
AddMiSetPredicateCmd(PMOS_COMMAND_BUFFER cmdBuffer,MHW_MI_SET_PREDICATE_ENABLE enableFlag)545     MOS_STATUS AddMiSetPredicateCmd(
546         PMOS_COMMAND_BUFFER                 cmdBuffer,
547         MHW_MI_SET_PREDICATE_ENABLE         enableFlag)
548     {
549         MHW_FUNCTION_ENTER;
550 
551         MHW_MI_CHK_NULL(m_osInterface);
552         MHW_MI_CHK_NULL(cmdBuffer);
553 
554         typename TMiCmds::MI_SET_PREDICATE_CMD cmd;
555         cmd.DW0.PredicateEnable = enableFlag;
556         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
557 
558         return MOS_STATUS_SUCCESS;
559     }
560 
AddMiAtomicCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_ATOMIC_PARAMS params)561     MOS_STATUS AddMiAtomicCmd(
562         PMOS_COMMAND_BUFFER                 cmdBuffer,
563         PMHW_MI_ATOMIC_PARAMS               params)
564     {
565         MHW_FUNCTION_ENTER;
566 
567         MHW_MI_CHK_NULL(m_osInterface);
568         MHW_MI_CHK_NULL(cmdBuffer);
569         MHW_MI_CHK_NULL(params);
570         MHW_MI_CHK_NULL(params->pOsResource);
571 
572         typename TMiCmds::MI_ATOMIC_CMD  cmd;
573         MHW_RESOURCE_PARAMS     resourceParams;
574         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
575         resourceParams.presResource = params->pOsResource;
576         resourceParams.dwOffset = params->dwResourceOffset;
577         resourceParams.pdwCmd = &(cmd.DW1.Value);
578         resourceParams.dwLocationInCmd = 1;
579         resourceParams.dwLsbNum = MHW_COMMON_MI_GENERAL_SHIFT;
580         resourceParams.HwCommandType = MOS_MI_ATOMIC;
581         resourceParams.bIsWritable = true;
582 
583         MHW_MI_CHK_STATUS(AddResourceToCmd(
584             m_osInterface,
585             cmdBuffer,
586             &resourceParams));
587 
588         cmd.DW0.DwordLength = params->bInlineData ? 1 : 9;
589         cmd.DW0.MemoryType = IsGlobalGttInUse();
590         cmd.DW0.ReturnDataControl = params->bReturnData;
591         if (params->dwDataSize == sizeof(uint32_t))
592         {
593             cmd.DW0.DataSize = cmd.DATA_SIZE_DWORD;
594         }
595         else if (params->dwDataSize == sizeof(uint64_t))
596         {
597             cmd.DW0.DataSize = cmd.DATA_SIZE_QWORD;
598         }
599         else if (params->dwDataSize == sizeof(uint64_t)* 2)
600         {
601             cmd.DW0.DataSize = cmd.DATA_SIZE_OCTWORD;
602         }
603         else
604         {
605             MHW_ASSERTMESSAGE("Invalid data size provided");
606             return MOS_STATUS_INVALID_PARAMETER;
607         }
608 
609         if (cmd.DW0.DataSize == cmd.DATA_SIZE_QWORD)
610         {
611             cmd.DW0.AtomicOpcode = atomicQword;
612         }
613         else if (cmd.DW0.DataSize == cmd.DATA_SIZE_OCTWORD)
614         {
615             if (params->Operation != MHW_MI_ATOMIC_CMP)
616             {
617                 MHW_ASSERTMESSAGE("An OCTWORD may only be used in the case of a compare operation!");
618                 return MOS_STATUS_INVALID_PARAMETER;
619             }
620             cmd.DW0.AtomicOpcode = atomicOctword;
621         }
622         cmd.DW0.AtomicOpcode = CreateMiAtomicOpcode(
623             cmd.DW0.AtomicOpcode,
624             params->Operation);
625         if (cmd.DW0.AtomicOpcode == atomicInvalid)
626         {
627             MHW_ASSERTMESSAGE("No MI_ATOMIC opcode could be generated");
628             return MOS_STATUS_INVALID_PARAMETER;
629         }
630 
631         cmd.DW0.InlineData = params->bInlineData;
632         cmd.DW0.DwordLength = params->bInlineData ? 9 : 1;
633 
634         if (params->bInlineData)
635         {
636             cmd.DW3.Operand1DataDword0 = params->dwOperand1Data[0];
637             cmd.DW4.Operand2DataDword0 = params->dwOperand2Data[0];
638             cmd.DW5.Operand1DataDword1 = params->dwOperand1Data[1];
639             cmd.DW6.Operand2DataDword1 = params->dwOperand2Data[1];
640             cmd.DW7.Operand1DataDword2 = params->dwOperand1Data[2];
641             cmd.DW8.Operand2DataDword2 = params->dwOperand2Data[3];
642             cmd.DW9.Operand1DataDword3 = params->dwOperand1Data[3];
643             cmd.DW10.Operand2DataDword3 = params->dwOperand2Data[3];
644         }
645 
646         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
647 
648         return MOS_STATUS_SUCCESS;
649     }
650 
AddMiSemaphoreWaitCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_SEMAPHORE_WAIT_PARAMS params)651     MOS_STATUS AddMiSemaphoreWaitCmd(
652         PMOS_COMMAND_BUFFER             cmdBuffer,
653         PMHW_MI_SEMAPHORE_WAIT_PARAMS   params)
654     {
655         MHW_FUNCTION_ENTER;
656 
657         MHW_MI_CHK_NULL(m_osInterface);
658         MHW_MI_CHK_NULL(cmdBuffer);
659         MHW_MI_CHK_NULL(params);
660         MHW_MI_CHK_NULL(params->presSemaphoreMem);
661 
662         typename TMiCmds::MI_SEMAPHORE_WAIT_CMD  cmd;
663         MHW_RESOURCE_PARAMS             resourceParams;
664         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
665         resourceParams.presResource     = params->presSemaphoreMem;
666         resourceParams.dwOffset         = params->dwResourceOffset;
667         resourceParams.pdwCmd           = cmd.DW2_3.Value;
668         resourceParams.dwLocationInCmd  = 2;
669         resourceParams.dwLsbNum         = MHW_COMMON_MI_GENERAL_SHIFT;
670         resourceParams.HwCommandType    = MOS_MI_SEMAPHORE_WAIT;
671 
672         MHW_MI_CHK_STATUS(AddResourceToCmd(
673             m_osInterface,
674             cmdBuffer,
675             &resourceParams));
676 
677         cmd.DW0.MemoryType          = IsGlobalGttInUse();
678         cmd.DW0.WaitMode            = params->bPollingWaitMode;
679 
680         cmd.DW0.CompareOperation    = params->CompareOperation;
681         cmd.DW1.SemaphoreDataDword  = params->dwSemaphoreData;
682 
683         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
684 
685         return MOS_STATUS_SUCCESS;
686     }
687 
AddMiArbCheckCmd(PMOS_COMMAND_BUFFER cmdBuffer)688     MOS_STATUS AddMiArbCheckCmd(
689         PMOS_COMMAND_BUFFER         cmdBuffer)
690     {
691         MHW_FUNCTION_ENTER;
692 
693         MHW_MI_CHK_NULL(m_osInterface);
694         MHW_MI_CHK_NULL(cmdBuffer);
695 
696         typename TMiCmds::MI_ARB_CHECK_CMD cmd;
697         MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
698 
699         return MOS_STATUS_SUCCESS;
700     }
701 
AddPipeControl(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_PIPE_CONTROL_PARAMS params)702     MOS_STATUS AddPipeControl(
703         PMOS_COMMAND_BUFFER             cmdBuffer,
704         PMHW_BATCH_BUFFER               batchBuffer,
705         PMHW_PIPE_CONTROL_PARAMS        params)
706     {
707         MHW_FUNCTION_ENTER;
708 
709         MHW_MI_CHK_NULL(params);
710 
711         if (cmdBuffer == nullptr && batchBuffer == nullptr)
712         {
713             MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
714             return MOS_STATUS_NULL_POINTER;
715         }
716 
717         typename TMiCmds::PIPE_CONTROL_CMD cmd;
718         cmd.DW1.PipeControlFlushEnable      = true;
719         cmd.DW1.CommandStreamerStallEnable  = !params->bDisableCSStall;
720         cmd.DW4_5.Value[0]                  = params->dwDataDW1;
721         cmd.DW4_5.Value[1]                  = params->dwDataDW2;
722 
723         if (params->presDest)
724         {
725             cmd.DW1.PostSyncOperation       = params->dwPostSyncOp;
726             cmd.DW1.DestinationAddressType  = UseGlobalGtt.m_cs;
727 
728             MHW_RESOURCE_PARAMS resourceParams;
729             MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
730             resourceParams.presResource     = params->presDest;
731             resourceParams.dwOffset         = params->dwResourceOffset;
732             resourceParams.pdwCmd           = &(cmd.DW2.Value);
733             resourceParams.dwLocationInCmd  = 2;
734             resourceParams.dwLsbNum         = MHW_COMMON_MI_PIPE_CONTROL_SHIFT;
735             resourceParams.bIsWritable      = true;
736             resourceParams.HwCommandType    = MOS_PIPE_CONTROL;
737 
738             MHW_MI_CHK_STATUS(AddResourceToCmd(
739                 m_osInterface,
740                 cmdBuffer,
741                 &resourceParams));
742         }
743         else
744         {
745             cmd.DW1.StateCacheInvalidationEnable        = true;
746             cmd.DW1.ConstantCacheInvalidationEnable     = true;
747             cmd.DW1.VfCacheInvalidationEnable           = true;
748             cmd.DW1.InstructionCacheInvalidateEnable    = true;
749             cmd.DW1.RenderTargetCacheFlushEnable        = true;
750             cmd.DW1.PostSyncOperation                   = cmd.POST_SYNC_OPERATION_NOWRITE;
751         }
752 
753         // Cache flush mode
754         switch (params->dwFlushMode)
755         {
756             // Flush all Write caches
757             case MHW_FLUSH_WRITE_CACHE:
758                 cmd.DW1.RenderTargetCacheFlushEnable        = true;
759                 cmd.DW1.DcFlushEnable                       = true;
760                 break;
761 
762             // Invalidate all Read-only caches
763             case MHW_FLUSH_READ_CACHE:
764                 cmd.DW1.RenderTargetCacheFlushEnable        = false;
765                 cmd.DW1.StateCacheInvalidationEnable        = true;
766                 cmd.DW1.ConstantCacheInvalidationEnable     = true;
767                 cmd.DW1.VfCacheInvalidationEnable           = true;
768                 cmd.DW1.InstructionCacheInvalidateEnable    = true;
769                 break;
770 
771             // Custom flush parameters
772             case MHW_FLUSH_CUSTOM:
773                 cmd.DW1.RenderTargetCacheFlushEnable      = params->bFlushRenderTargetCache;
774                 cmd.DW1.DcFlushEnable                     = params->bFlushRenderTargetCache; // same as above
775                 cmd.DW1.StateCacheInvalidationEnable      = params->bInvalidateStateCache;
776                 cmd.DW1.ConstantCacheInvalidationEnable   = params->bInvalidateConstantCache;
777                 cmd.DW1.VfCacheInvalidationEnable         = params->bInvalidateVFECache;
778                 cmd.DW1.InstructionCacheInvalidateEnable  = params->bInvalidateInstructionCache;
779                 cmd.DW1.TlbInvalidate                     = params->bTlbInvalidate;
780                 cmd.DW1.TextureCacheInvalidationEnable    = params->bInvalidateTextureCache;
781                 break;
782 
783             // No-flush operation requested
784             case MHW_FLUSH_NONE:
785             default:
786                 cmd.DW1.RenderTargetCacheFlushEnable      = false;
787                 break;
788         }
789 
790         // When PIPE_CONTROL stall bit is set, one of the following must also be set, otherwise set stall bit to 0
791         if (cmd.DW1.CommandStreamerStallEnable &&
792             (cmd.DW1.DcFlushEnable == 0 && cmd.DW1.NotifyEnable == 0 && cmd.DW1.PostSyncOperation == 0 &&
793              cmd.DW1.DepthStallEnable == 0 && cmd.DW1.StallAtPixelScoreboard == 0 && cmd.DW1.DepthCacheFlushEnable == 0  &&
794              cmd.DW1.RenderTargetCacheFlushEnable == 0))
795         {
796             cmd.DW1.CommandStreamerStallEnable = 0;
797         }
798 
799         if (params->bGenericMediaStateClear)
800         {
801             cmd.DW1.GenericMediaStateClear = true;
802         }
803 
804         if (params->bIndirectStatePointersDisable)
805         {
806             cmd.DW1.IndirectStatePointersDisable = true;
807         }
808 
809         MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, cmd.byteSize));
810 
811         return MOS_STATUS_SUCCESS;
812     }
813 
AddMfxWaitCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,bool stallVdboxPipeline)814     MOS_STATUS AddMfxWaitCmd(
815         PMOS_COMMAND_BUFFER                 cmdBuffer,
816         PMHW_BATCH_BUFFER                   batchBuffer,
817         bool                                stallVdboxPipeline)
818     {
819         MHW_FUNCTION_ENTER;
820 
821         if (cmdBuffer == nullptr && batchBuffer == nullptr)
822         {
823             MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
824             return MOS_STATUS_NULL_POINTER;
825         }
826 
827         typename TMiCmds::MFX_WAIT_CMD cmd;
828         cmd.DW0.MfxSyncControlFlag = stallVdboxPipeline;
829 
830         // set the protection bit based on CP status
831         MHW_MI_CHK_STATUS(m_cpInterface->SetProtectionSettingsForMfxWait(m_osInterface, &cmd));
832 
833         MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, cmd.byteSize));
834 
835         return MOS_STATUS_SUCCESS;
836     }
837 
838     MOS_STATUS AddMediaStateFlush(
839         PMOS_COMMAND_BUFFER             cmdBuffer,
840         PMHW_BATCH_BUFFER               batchBuffer,
841         PMHW_MEDIA_STATE_FLUSH_PARAM    params = nullptr)
842     {
843         MHW_FUNCTION_ENTER;
844 
845        if (cmdBuffer == nullptr && batchBuffer == nullptr)
846         {
847             MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
848             return MOS_STATUS_NULL_POINTER;
849         }
850 
851         return MOS_STATUS_SUCCESS;
852     }
853 
SkipMiBatchBufferEndBb(PMHW_BATCH_BUFFER batchBuffer)854     MOS_STATUS SkipMiBatchBufferEndBb(
855         PMHW_BATCH_BUFFER               batchBuffer)
856     {
857         MHW_FUNCTION_ENTER;
858 
859         MHW_MI_CHK_NULL(batchBuffer);
860 
861         return MOS_STATUS_SUCCESS;
862     }
863 
GetMiFlushDwCmdSize()864     inline uint32_t GetMiFlushDwCmdSize()
865     {
866         return TMiCmds::MI_FLUSH_DW_CMD::byteSize;
867     }
868 
GetMiBatchBufferStartCmdSize()869     inline uint32_t GetMiBatchBufferStartCmdSize()
870     {
871         return TMiCmds::MI_BATCH_BUFFER_START_CMD::byteSize;
872     }
873 
GetMiBatchBufferEndCmdSize()874     inline uint32_t GetMiBatchBufferEndCmdSize()
875     {
876         return TMiCmds::MI_BATCH_BUFFER_END_CMD::byteSize;
877     }
878 
AddBatchBufferEndInsertionFlag(MOS_COMMAND_BUFFER & constructedCmdBuf)879     MOS_STATUS AddBatchBufferEndInsertionFlag(
880         MOS_COMMAND_BUFFER &constructedCmdBuf)
881     {
882         MHW_FUNCTION_ENTER;
883 
884         typename TMiCmds::MI_BATCH_BUFFER_END_CMD cmd;
885 
886         MHW_CHK_NULL_RETURN(constructedCmdBuf.pCmdPtr);
887         *((typename TMiCmds::MI_BATCH_BUFFER_END_CMD *)(constructedCmdBuf.pCmdPtr)) = cmd;
888 
889         return MOS_STATUS_SUCCESS;
890     }
891 
SetWatchdogTimerThreshold(uint32_t frameWidth,uint32_t frameHeight,bool isEncoder)892     MOS_STATUS SetWatchdogTimerThreshold(
893         uint32_t frameWidth,
894         uint32_t frameHeight,
895         bool isEncoder)
896     {
897         MHW_FUNCTION_ENTER;
898 
899         return MOS_STATUS_SUCCESS;
900     }
901 
SetWatchdogTimerRegisterOffset(MOS_GPU_CONTEXT gpuContext)902     MOS_STATUS SetWatchdogTimerRegisterOffset(
903         MOS_GPU_CONTEXT gpuContext)
904     {
905         MHW_FUNCTION_ENTER;
906 
907         return MOS_STATUS_SUCCESS;
908     }
909 
AddWatchdogTimerStartCmd(PMOS_COMMAND_BUFFER cmdBuffer)910     MOS_STATUS AddWatchdogTimerStartCmd(
911         PMOS_COMMAND_BUFFER cmdBuffer)
912     {
913         MHW_FUNCTION_ENTER;
914 
915         return MOS_STATUS_SUCCESS;
916     }
917 
AddWatchdogTimerStopCmd(PMOS_COMMAND_BUFFER cmdBuffer)918     MOS_STATUS AddWatchdogTimerStopCmd(
919         PMOS_COMMAND_BUFFER cmdBuffer)
920     {
921         MHW_FUNCTION_ENTER;
922 
923         return MOS_STATUS_SUCCESS;
924     }
925 };
926 
927 #endif // __MHW_MI_GENERIC_H__
928