xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/hw/mhw_vebox.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2014-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 //! \file     mhw_vebox.cpp
23 //! \brief    MHW interface for constructing commands for the VEBOX
24 //! \details  Impelements the functionalities common across all platforms for MHW_VEBOX
25 //!
26 
27 #include "mhw_utilities.h"
28 #include "mhw_vebox.h"
29 #include "hal_oca_interface.h"
30 
RefreshVeboxSync()31 void MhwVeboxInterface::RefreshVeboxSync()
32 {
33     PMHW_VEBOX_HEAP             pVeboxHeap;
34     PMHW_VEBOX_HEAP_STATE       pCurInstance;
35     PMOS_INTERFACE              pOsInterface;
36     uint32_t                    dwCurrentTag;
37     int32_t                     i;
38     int32_t                     iInstanceInUse;
39     MOS_NULL_RENDERING_FLAGS    NullRenderingFlags;
40 
41     MHW_FUNCTION_ENTER;
42     if (m_veboxHeap == nullptr ||
43         m_osInterface == nullptr )
44     {
45         MHW_ASSERTMESSAGE("RefreshVeboxSync failed due to m_veboxHeap or m_osInterface is invalid ");
46         return;
47     }
48     iInstanceInUse = 0;
49 
50     // Vebox Heap will always be locked by driver
51     pVeboxHeap   = m_veboxHeap;
52     pOsInterface = m_osInterface;
53 
54     // Most recent tag
55     if (pOsInterface->bEnableKmdMediaFrameTracking)
56     {
57         dwCurrentTag = pOsInterface->pfnGetGpuStatusSyncTag(pOsInterface, MOS_GPU_CONTEXT_VEBOX);
58     }
59     else
60     {
61         dwCurrentTag = pVeboxHeap->pSync[0];
62     }
63     pVeboxHeap->dwSyncTag = dwCurrentTag - 1;
64 
65     NullRenderingFlags  = m_osInterface->pfnGetNullHWRenderFlags(
66         m_osInterface);
67 
68     // Refresh VeboxHeap states
69     pCurInstance = pVeboxHeap->pStates;
70     for (i = m_veboxSettings.uiNumInstances; i > 0; i--, pCurInstance++)
71     {
72         if (!pCurInstance->bBusy) continue;
73 
74         // The condition below is valid when sync tag wraps from 2^32-1 to 0
75         if (((int32_t)(dwCurrentTag - pCurInstance->dwSyncTag) >= 0) ||
76             NullRenderingFlags.VPGobal ||
77             NullRenderingFlags.VPDnDi)
78         {
79             pCurInstance->bBusy = false;
80         }
81         else
82         {
83             iInstanceInUse++;
84         }
85     }
86 
87     // Save number of instance in use
88     m_veboxHeapInUse = iInstanceInUse;
89 }
90 
AssignVeboxState()91 MOS_STATUS MhwVeboxInterface::AssignVeboxState()
92 {
93     uint32_t                dwWaitMs, dwWaitTag;
94     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
95     PMOS_INTERFACE          pOsInterface;
96     PMHW_VEBOX_HEAP_STATE   pVeboxCurState;
97     PMHW_VEBOX_HEAP         pVeboxHeap;
98     uint32_t                uiOffset;
99 
100     MHW_FUNCTION_ENTER;
101     MHW_CHK_NULL(m_veboxHeap);
102     MHW_CHK_NULL(m_osInterface);
103 
104     pVeboxHeap     = m_veboxHeap;
105     pVeboxCurState = &m_veboxHeap->pStates[pVeboxHeap->uiNextState];
106     pOsInterface   = m_osInterface;
107 
108     // Refresh sync tag for all vebox heap instance
109     RefreshVeboxSync();
110 
111     // Check validity of  current vebox heap instance
112     // The code below is unlikely to be executed - unless all Vebox states are in use
113     // If this ever happens, please consider increasing the number of media states
114     MHW_CHK_NULL(pVeboxCurState);
115     if (pVeboxCurState->bBusy)
116     {
117         // Get current vebox instance sync tag
118         dwWaitTag = pVeboxCurState->dwSyncTag;
119 
120         // Wait for Batch Buffer complete event OR timeout
121         for (dwWaitMs = MHW_TIMEOUT_MS_DEFAULT; dwWaitMs > 0; dwWaitMs--)
122         {
123             uint32_t dwCurrentTag;
124 
125             MHW_CHK_STATUS(pOsInterface->pfnWaitForBBCompleteNotifyEvent(
126                 pOsInterface,
127                 MOS_GPU_CONTEXT_VEBOX,
128                 MHW_EVENT_TIMEOUT_MS));
129 
130             if (pOsInterface->bEnableKmdMediaFrameTracking)
131             {
132                 dwCurrentTag = pOsInterface->pfnGetGpuStatusSyncTag(pOsInterface, MOS_GPU_CONTEXT_VEBOX);
133             }
134             else
135             {
136                 dwCurrentTag = pVeboxHeap->pSync[0];
137             }
138             // Mark current instance status as availabe. Wait if this sync tag came back from GPU
139             if ((int32_t)(dwCurrentTag - dwWaitTag) >= 0)
140             {
141                 pVeboxCurState->bBusy = false;
142                 break;
143             }
144         }
145 
146         // Timeout
147         if (dwWaitMs == 0)
148         {
149             MHW_ASSERTMESSAGE("Timeout on waiting for free Vebox Heap.");
150             eStatus = MOS_STATUS_UNKNOWN;
151             goto finish;
152         }
153     }
154 
155     // Prepare syncTag for GPU write back
156     if (pOsInterface->bEnableKmdMediaFrameTracking)
157     {
158         pVeboxCurState->dwSyncTag = pOsInterface->pfnGetGpuStatusTag(pOsInterface, MOS_GPU_CONTEXT_VEBOX);
159     }
160     else
161     {
162         pVeboxCurState->dwSyncTag = pVeboxHeap->dwNextTag;
163     }
164 
165     // Assign current state and increase next state
166     pVeboxHeap->uiCurState  = pVeboxHeap->uiNextState;
167     pVeboxHeap->uiNextState = (pVeboxHeap->uiNextState + 1) %
168                               (m_veboxSettings.uiNumInstances);
169 
170     //Clean the memory of current veboxheap to avoid the history states
171     uiOffset = pVeboxHeap->uiCurState * pVeboxHeap->uiInstanceSize;
172     MOS_ZeroMemory(pVeboxHeap->pLockedDriverResourceMem + uiOffset, pVeboxHeap->uiInstanceSize);
173 
174 finish:
175     return eStatus;
176 }
177 
UpdateVeboxSync()178 MOS_STATUS MhwVeboxInterface::UpdateVeboxSync()
179 {
180     PMHW_VEBOX_HEAP          pVeboxHeap;
181     MOS_STATUS               eStatus = MOS_STATUS_SUCCESS;
182     PMOS_INTERFACE           pOsInterface;
183 
184     MHW_FUNCTION_ENTER;
185 
186     MHW_CHK_NULL(m_veboxHeap);
187     MHW_CHK_NULL(m_osInterface);
188 
189     pVeboxHeap      = m_veboxHeap;
190     pOsInterface    = m_osInterface;
191 
192     // If KMD frame tracking is on, the dwSyncTag has been set to gpu status tag
193     // in Mhw_VeboxInterface_AssignVeboxState(). dwNextTag is not used anymore.
194     if (!pOsInterface->bEnableKmdMediaFrameTracking)
195     {
196         pVeboxHeap->pStates[pVeboxHeap->uiCurState].dwSyncTag =
197             pVeboxHeap->dwNextTag++;
198     }
199     pVeboxHeap->pStates[pVeboxHeap->uiCurState].bBusy = true;
200 
201 finish:
202     return eStatus;
203 }
204 
GetVeboxHeapInfo(const MHW_VEBOX_HEAP ** ppVeboxHeap)205 MOS_STATUS MhwVeboxInterface::GetVeboxHeapInfo(
206     const MHW_VEBOX_HEAP     **ppVeboxHeap)
207 {
208     MOS_STATUS               eStatus = MOS_STATUS_SUCCESS;
209 
210     MHW_FUNCTION_ENTER;
211     MHW_CHK_NULL(ppVeboxHeap);
212 
213     *ppVeboxHeap = (const MHW_VEBOX_HEAP *)m_veboxHeap;
214 
215 finish:
216     return eStatus;
217 }
218 
CreateHeap()219 MOS_STATUS MhwVeboxInterface::CreateHeap( )
220 {
221     MOS_STATUS              eStatus;
222     uint8_t                 *pMem;
223     uint32_t                uiSize;
224     uint32_t                uiOffset;
225     MOS_ALLOC_GFXRES_PARAMS AllocParams;
226     MOS_LOCK_PARAMS         LockFlags;
227     MEDIA_FEATURE_TABLE     *skuTable = nullptr;
228 
229     MHW_FUNCTION_ENTER;
230 
231     MHW_CHK_NULL(m_osInterface);
232     MHW_CHK_NULL(m_osInterface->pfnGetSkuTable);
233 
234     skuTable = m_osInterface->pfnGetSkuTable(m_osInterface);
235     MHW_CHK_NULL(skuTable);
236 
237     eStatus         = MOS_STATUS_SUCCESS;
238 
239     uiSize =  sizeof(MHW_VEBOX_HEAP);
240     uiSize += m_veboxSettings.uiNumInstances *
241               sizeof(MHW_VEBOX_HEAP_STATE);
242 
243     // Allocate memory for VEBOX
244     pMem = (uint8_t*)MOS_AllocAndZeroMemory(uiSize);
245     MHW_CHK_NULL(pMem);
246 
247     m_veboxHeap = (PMHW_VEBOX_HEAP)pMem;
248 
249     m_veboxHeap->pStates =
250     (PMHW_VEBOX_HEAP_STATE)(pMem + sizeof(MHW_VEBOX_HEAP));
251 
252     // Assign offsets and sizes
253     uiOffset = 0;
254     m_veboxHeap->uiDndiStateOffset = uiOffset;
255     uiOffset += m_veboxSettings.uiDndiStateSize;
256 
257     m_veboxHeap->uiIecpStateOffset = uiOffset;
258     uiOffset += m_veboxSettings.uiIecpStateSize;
259 
260     m_veboxHeap->uiGamutStateOffset = uiOffset;
261     uiOffset += m_veboxSettings.uiGamutStateSize;
262 
263     m_veboxHeap->uiVertexTableOffset = uiOffset;
264     uiOffset += m_veboxSettings.uiVertexTableSize;
265 
266     m_veboxHeap->uiCapturePipeStateOffset = uiOffset;
267     uiOffset += m_veboxSettings.uiCapturePipeStateSize;
268 
269     m_veboxHeap->uiGammaCorrectionStateOffset = uiOffset;
270     uiOffset += m_veboxSettings.uiGammaCorrectionStateSize;
271 
272     m_veboxHeap->uiHdrStateOffset = uiOffset;
273     uiOffset += m_veboxSettings.uiHdrStateSize;
274 
275     m_veboxHeap->uiInstanceSize = uiOffset;
276 
277     // Appending VeboxHeap sync data after all vebox heap instances
278     m_veboxHeap->uiOffsetSync   =
279         m_veboxHeap->uiInstanceSize *
280         m_veboxSettings.uiNumInstances;
281 
282     // Allocate GPU memory
283     uiSize = m_veboxHeap->uiInstanceSize *
284              m_veboxSettings.uiNumInstances +
285              m_veboxSettings.uiSyncSize;
286 
287     // for using vdbox copy, the size have to be cache line aligned
288     MOS_ALIGN_CEIL(uiSize, MHW_CACHELINE_SIZE);
289 
290     m_veboxHeap->uiStateHeapSize = uiSize;
291 
292     MOS_ZeroMemory(&AllocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
293 
294     AllocParams.Type     = MOS_GFXRES_BUFFER;
295     AllocParams.TileType = MOS_TILE_LINEAR;
296     AllocParams.Format   = Format_Buffer;
297     AllocParams.dwBytes  = uiSize;
298     AllocParams.pBufName = "VphalVeboxHeap";
299     AllocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_FF;
300 
301     if (MEDIA_IS_SKU(skuTable, FtrLimitedLMemBar))
302     {
303         AllocParams.dwMemType = MOS_MEMPOOL_SYSTEMMEMORY;
304     }
305 
306     MHW_CHK_STATUS(m_osInterface->pfnAllocateResource(
307         m_osInterface,
308         &AllocParams,
309         &m_veboxHeap->DriverResource));
310 
311     if (MEDIA_IS_SKU(skuTable, FtrLimitedLMemBar))
312     {
313         // Use device memory for vebox heap kernel resource, as no cpu access on it.
314         AllocParams.dwMemType = MOS_MEMPOOL_DEVICEMEMORY;
315     }
316     AllocParams.Flags.bNotLockable = 1;
317     MHW_CHK_STATUS(m_osInterface->pfnAllocateResource(
318         m_osInterface,
319         &AllocParams,
320         &m_veboxHeap->KernelResource));
321 
322     // Lock the driver resource
323     MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS));
324 
325     LockFlags.NoOverWrite = 1;
326 
327     m_veboxHeap->pLockedDriverResourceMem =
328         (uint8_t*)m_osInterface->pfnLockResource(
329                             m_osInterface,
330                             &m_veboxHeap->DriverResource,
331                             &LockFlags);
332     MHW_CHK_NULL(m_veboxHeap->pLockedDriverResourceMem);
333 
334     // Initialize VeboxHeap controls that depend on mapping
335     m_veboxHeap->pSync =
336         (uint32_t*) (m_veboxHeap->pLockedDriverResourceMem +
337                   m_veboxHeap->uiOffsetSync);
338 
339 finish:
340     if (eStatus != MOS_STATUS_SUCCESS)
341     {
342         DestroyHeap();
343     }
344     return eStatus;
345 }
346 
DestroyHeap()347 MOS_STATUS MhwVeboxInterface::DestroyHeap()
348 {
349     PMOS_INTERFACE       pOsInterface;
350     MOS_STATUS           eStatus = MOS_STATUS_SUCCESS;
351 
352     MHW_FUNCTION_ENTER;
353     MHW_CHK_NULL(m_osInterface);
354 
355     pOsInterface = m_osInterface;
356 
357     if (m_veboxHeap)
358     {
359         if (!Mos_ResourceIsNull(&m_veboxHeap->DriverResource))
360         {
361             if (m_veboxHeap->pLockedDriverResourceMem)
362             {
363                 pOsInterface->pfnUnlockResource(
364                     pOsInterface,
365                     &m_veboxHeap->DriverResource);
366             }
367 
368             pOsInterface->pfnFreeResource(
369                 pOsInterface,
370                 &m_veboxHeap->DriverResource);
371         }
372 
373         if (!Mos_ResourceIsNull(&m_veboxHeap->KernelResource))
374         {
375             pOsInterface->pfnFreeResource(
376                 pOsInterface,
377                 &m_veboxHeap->KernelResource);
378         }
379 
380         MOS_FreeMemory(m_veboxHeap);
381         m_veboxHeap = nullptr;
382     }
383 
384 finish:
385     return eStatus;
386 }
387 
MhwVeboxInterface(PMOS_INTERFACE pOsInterface)388 MhwVeboxInterface::MhwVeboxInterface(PMOS_INTERFACE pOsInterface)
389 {
390     MHW_FUNCTION_ENTER;
391 
392     MOS_ZeroMemory(&m_veboxSettings, sizeof(m_veboxSettings));
393     pfnAddResourceToCmd = nullptr;
394 
395     if (pOsInterface == nullptr)
396     {
397         MHW_ASSERTMESSAGE("Invalid input pointers provided");
398         return;
399     }
400     m_osInterface   = pOsInterface;
401 
402     if (m_osInterface->bUsesGfxAddress)
403     {
404         pfnAddResourceToCmd = Mhw_AddResourceToCmd_GfxAddress;
405     }
406     else  //PatchList
407     {
408         pfnAddResourceToCmd = Mhw_AddResourceToCmd_PatchList;
409     }
410 }
411 
TraceIndirectStateInfo(MOS_COMMAND_BUFFER & cmdBuffer,MOS_CONTEXT & mosContext,bool isCmBuffer,bool useVeboxHeapKernelResource)412 void MhwVeboxInterface::TraceIndirectStateInfo(MOS_COMMAND_BUFFER &cmdBuffer, MOS_CONTEXT &mosContext, bool isCmBuffer, bool useVeboxHeapKernelResource)
413 {
414     if (isCmBuffer)
415     {
416         char ocaLog[] = "Vebox indirect state use CmBuffer";
417         HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)&mosContext, ocaLog, sizeof(ocaLog));
418     }
419     else
420     {
421         if (useVeboxHeapKernelResource)
422         {
423             char ocaLog[] = "Vebox indirect state use KernelResource";
424             HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)&mosContext, ocaLog, sizeof(ocaLog));
425         }
426         else
427         {
428             char ocaLog[] = "Vebox indirect state use DriverResource";
429             HalOcaInterface::TraceMessage(cmdBuffer, (MOS_CONTEXT_HANDLE)&mosContext, ocaLog, sizeof(ocaLog));
430         }
431     }
432 }
433