xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/hw/mhw_state_heap.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2014-2017, 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_state_heap.cpp
24 //! \brief         This modules implements HW interface layer to be used on all platforms on     all operating systems/DDIs, across MHW components.
25 //!
26 #include "mhw_state_heap.h"
27 #include "mhw_utilities.h"
28 #include "mhw_block_manager.h"
29 #include "media_interfaces_mhw_next.h"
30 #include "mhw_mi.h"
31 #include "mhw_cp_interface.h"
32 #include "mos_interface.h"
33 
34 extern const uint8_t g_cMhw_VDirection[MHW_NUM_FRAME_FIELD_TYPES] = {
35     MEDIASTATE_VDIRECTION_FULL_FRAME,
36     MEDIASTATE_VDIRECTION_TOP_FIELD,
37     MEDIASTATE_VDIRECTION_BOTTOM_FIELD
38 };
39 
40 extern const MHW_SAMPLER_STATE_UNORM_PARAM g_cInit_MhwSamplerStateUnormParam =
41 {
42     MHW_SAMPLER_FILTER_CUSTOM,                      // SamplerFilterMode
43     MHW_GFX3DSTATE_MAPFILTER_LINEAR,                // MagFilter
44     MHW_GFX3DSTATE_MAPFILTER_LINEAR,                // MinFilter
45     MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP,              // AddressU
46     MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP,              // AddressV
47     MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP,              // AddressW
48     MHW_SAMPLER_SURFACE_PIXEL_UINT,
49     {0},
50     {0},
51     {0},
52     {0},
53     0,
54     0,
55     0
56 };
57 
58 extern const MHW_SURFACE_STATE_PARAMS g_cInit_MhwSurfaceStateParams =
59 {
60     nullptr,     // pSurfaceState
61 
62     0,        // dwCacheabilityControl
63     0,        // dwFormat
64     0,        // dwWidth
65     0,        // dwHeight
66     0,        // dwDepth
67     0,        // dwPitch
68     0,        // dwQPitch
69     0,        // bUseAdvState
70     0,        // AddressControl
71     0,        // SurfaceType3D
72     false,    // bTiledSurface
73     false,    // bTileWalk
74     false,    // bVerticalLineStride
75     false,    // bVerticalLineStrideOffset
76     false,    // bCompressionEnabled
77     false,    // bCompressionMode
78     0,        // MmcState
79     false,    // bInterleaveChroma
80     false,    // bHalfPitchChroma
81     false,    // bSeperateUVPlane
82     0,        // UVPixelOffsetUDirection
83     0,        // UVPixelOffsetVDirection
84     0,        // RotationMode
85     0,        // bSurfaceArraySpacing
86     false,    // bBoardColorOGL
87     0,        // iXOffset
88     0,        // iYOffset
89     0,        // dwXOffsetForU
90     0,        // dwYOffsetForU
91     0,        // dwXOffsetForV
92     0,        // dwYOffsetForV
93     0,        // Compression Format
94     0,        // L1CacheConfig
95 
96     nullptr,     // [out] pdwCmd
97     0         // [out] dwLocationInCmd
98 };
99 
100 extern const MHW_ID_ENTRY_PARAMS g_cInit_MhwIdEntryParams =
101 {
102     0,       // dwMediaIdOffset
103     0,       // iMediaId
104     0,       // dwKernelOffset
105     0,       // dwSamplerOffset
106     0,       // dwSamplerCount
107     0,       // dwBindingTableOffset
108     0,       // iCurbeOffset
109     0,       // iCurbeLength
110     false,   // bBarrierEnable
111     0,       // bGlobalBarrierEnable
112     0,       // dwNumberofThreadsInGPGPUGroup
113     0,       // dwSharedLocalMemorySize
114     0        // iCrsThdConDataRdLn
115 };
116 
117 //!
118 //! \brief    Assigns space in a state heap to a kernel state
119 //! \details  Client facing function to assign as space in a state heap a kernel state;
120 //!           if no space is available, a clean up is attempted
121 //! \param    PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface
122 //!           [in] State heap interface
123 //! \param    MHW_STATE_HEAP_TYPE StateHeapType
124 //!           [in] The state heap type requested (ISH/DSH)
125 //! \param    PMHW_KERNEL_STATE pKernelState
126 //!           [in] Kernel state to which a state heap space will be assigned
127 //! \param    uint32_t dwSpaceRequested
128 //!           [in] The amount of space requested from the state heap
129 //! \param    bool bStatic
130 //!           [in] Whether or not the space requested is static
131 //! \param    bool bZeroAssignedMem
132 //!           [in] Whether or not acquired memory should be zeroed
133 //! \return   MOS_STATUS
134 //!           MOS_STATUS_SUCCESS if success, MOS_STATUS_CLIENT_AR_NO_SPACE if no space
135 //!           is available but it is possible for the client to wait, else fail reason
136 //!
Mhw_StateHeapInterface_AssignSpaceInStateHeap(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,MHW_STATE_HEAP_TYPE StateHeapType,PMHW_KERNEL_STATE pKernelState,uint32_t dwSpaceRequested,bool bStatic,bool bZeroAssignedMem)137 MOS_STATUS Mhw_StateHeapInterface_AssignSpaceInStateHeap(
138     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
139     MHW_STATE_HEAP_TYPE         StateHeapType,
140     PMHW_KERNEL_STATE           pKernelState,
141     uint32_t                    dwSpaceRequested,
142     bool                        bStatic,
143     bool                        bZeroAssignedMem)
144 {
145     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
146 
147     MHW_FUNCTION_ENTER;
148 
149     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
150 
151     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
152 
153     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->AssignSpaceInStateHeap(
154                   StateHeapType,
155                   pKernelState,
156                   dwSpaceRequested,
157                   bStatic,
158                   bZeroAssignedMem));
159 
160     return eStatus;
161 }
162 
163 //!
164 //! \brief    Assigns space in a state heap to a kernel state
165 //! \details  Client facing function to assign as space in a state heap a kernel state;
166 //!           if no space is available, a clean up is attempted
167 //! \param    [in] pCommonStateHeapInterface
168 //!           State heap interface
169 //! \param    [in] pKernelState
170 //!           Kernel state containing all memory blocks to submit
171 //! \return   MOS_STATUS
172 //!           MOS_STATUS_SUCCESS if success
173 //!
Mhw_StateHeapInterface_SubmitBlocks(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,PMHW_KERNEL_STATE pKernelState)174 MOS_STATUS Mhw_StateHeapInterface_SubmitBlocks(
175     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
176     PMHW_KERNEL_STATE           pKernelState)
177 {
178     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
179 
180     MHW_FUNCTION_ENTER;
181 
182     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
183 
184     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
185 
186     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->SubmitBlocks(pKernelState));
187 
188     return eStatus;
189 }
190 
191 //!
192 //! \brief    Locks requested state heap
193 //! \details  Client facing function to lock a state heap
194 //! \param    PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
195 //!           [in] State heap interface
196 //! \param    PMHW_STATE_HEAP pStateHeap
197 //!           [in] The state heap to be locked
198 //! \return   MOS_STATUS
199 //!           MOS_STATUS_SUCCESS if success
200 //!
Mhw_StateHeapInterface_LockStateHeap(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,PMHW_STATE_HEAP pStateHeap)201 MOS_STATUS Mhw_StateHeapInterface_LockStateHeap(
202     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
203     PMHW_STATE_HEAP                    pStateHeap)
204 {
205     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
206 
207     MHW_FUNCTION_ENTER;
208 
209     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
210 
211     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
212 
213     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->LockStateHeap(
214                    pStateHeap));
215 
216     return eStatus;
217 }
218 
219 //!
220 //! \brief    Unlocks requested state heap
221 //! \details  Client facing function to unlock a state heap
222 //! \param    PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
223 //!           [in] State heap interface
224 //! \param    PMHW_STATE_HEAP pStateHeap
225 //!           [in] The state heap to be locked
226 //! \return   MOS_STATUS
227 //!           MOS_STATUS_SUCCESS if success
228 //!
Mhw_StateHeapInterface_UnlockStateHeap(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,PMHW_STATE_HEAP pStateHeap)229 MOS_STATUS Mhw_StateHeapInterface_UnlockStateHeap(
230     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
231     PMHW_STATE_HEAP             pStateHeap)
232 {
233     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
234 
235     MHW_FUNCTION_ENTER;
236 
237     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
238 
239     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
240 
241     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->UnLockStateHeap(
242                    pStateHeap));
243 
244     return eStatus;
245 }
246 
247 //!
248 //! \brief    Allocates a state heap of the requested type
249 //! \details  Client facing function to extend a state heap of the requested time, which
250 //!           involves allocating state heap and added it to the state heap liked list.
251 //! \param    PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
252 //!           [in] State heap interface
253 //! \param    MHW_STATE_HEAP_TYPE StateHeapType
254 //!           [in] The state heap type requested (ISH/DSH)
255 //! \param    uint32_t dwSizeRequested
256 //!           [in] The size of the state heap
257 //! \return   MOS_STATUS
258 //!           MOS_STATUS_SUCCESS if success, else fail reason
259 //!
Mhw_StateHeapInterface_ExtendStateHeap(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,MHW_STATE_HEAP_TYPE StateHeapType,uint32_t dwSizeRequested)260 MOS_STATUS Mhw_StateHeapInterface_ExtendStateHeap(
261     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
262     MHW_STATE_HEAP_TYPE         StateHeapType,
263     uint32_t                    dwSizeRequested)
264 {
265     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
266 
267     MHW_FUNCTION_ENTER;
268 
269     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
270 
271     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
272 
273     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->ExtendStateHeap(
274                    StateHeapType, dwSizeRequested));
275 
276     return eStatus;
277 }
278 
279 //!
280 //! \brief    Update CmdBufIdGlobal
281 //! \details  Client facing function to update CmdBufIdGlobal
282 //! \param    PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
283 //!           [in] State heap interface
284 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
285 //!           [in] The command buffer containing the kernel workload
286 //! \param    void  *pvRenderEngineInterface
287 //!           [in] Render engine interface
288 //! \return   MOS_STATUS
289 //!           MOS_STATUS_SUCCESS if success, else fail reason
290 //!
Mhw_StateHeapInterface_UpdateGlobalCmdBufId(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface)291 MOS_STATUS Mhw_StateHeapInterface_UpdateGlobalCmdBufId(
292     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface)
293 {
294     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
295 
296     MHW_FUNCTION_ENTER;
297 
298     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
299 
300     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
301 
302     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->UpdateGlobalCmdBufId());
303 
304     return eStatus;
305 }
306 
307 //!
308 //! \brief    Set command buffer status pointer
309 //! \details  Client facing function to set command buffer status pointer
310 //! \param    PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
311 //!           [in] State heap interface
312 //! \param    void  *pvCmdBufStatus
313 //!           [in] command buffer status pointer
314 //! \return   MOS_STATUS
315 //!           MOS_STATUS_SUCCESS if success, else fail reason
316 //!
Mhw_StateHeapInterface_SetCmdBufStatusPtr(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,void * pvCmdBufStatus)317 MOS_STATUS Mhw_StateHeapInterface_SetCmdBufStatusPtr(
318     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
319     void                        *pvCmdBufStatus)
320 {
321     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
322 
323     MHW_FUNCTION_ENTER;
324 
325     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
326 
327     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
328 
329     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->SetCmdBufStatusPtr(
330         pvCmdBufStatus));
331 
332     return eStatus;
333 }
334 
335 //!
336 //! \brief    Calculate the space needed in the SSH
337 //! \details  Client facing function to calculate the space needed in the SSH
338 //!           given the number of binding table entries
339 //! \param    PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
340 //!           [in] State heap interface
341 //! \param    uint32_t dwBtEntriesRequested
342 //!           [in] Binding table entries requested in the SSH
343 //! \param    uint32_t *pdwSshSize
344 //!           [out] The size needed in the SSH
345 //! \return   MOS_STATUS
346 //!           MOS_STATUS_SUCCESS if success, else fail reason
347 //!
Mhw_StateHeapInterface_CalculateSshAndBtSizesRequested(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,uint32_t dwBtEntriesRequested,uint32_t * pdwSshSize,uint32_t * pdwBtSize)348 MOS_STATUS Mhw_StateHeapInterface_CalculateSshAndBtSizesRequested(
349     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
350     uint32_t                    dwBtEntriesRequested,
351     uint32_t                    *pdwSshSize,
352     uint32_t                    *pdwBtSize)
353 {
354     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
355 
356     MHW_FUNCTION_ENTER;
357 
358     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
359 
360     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
361 
362     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->CalculateSshAndBtSizesRequested(
363                    dwBtEntriesRequested, pdwSshSize, pdwBtSize));
364 
365     return eStatus;
366 }
367 
368 //!
369 //! \brief    Request SSH space for a command buffer.
370 //! \details  Client facing function to request SSH space for a command buffer, if not enough
371 //!           space is available, more will be requested.
372 //! \param    PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
373 //!           [in] State heap interface
374 //! \param    uint32_t dwBtEntriesRequested
375 //!           [in] Binding table entries requested in the SSH
376 //! \return   MOS_STATUS
377 //!           MOS_STATUS_SUCCESS if success, else fail reason
378 //!
Mhw_StateHeapInterface_RequestSshSpaceForCmdBuf(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,uint32_t dwBtEntriesRequested)379 MOS_STATUS Mhw_StateHeapInterface_RequestSshSpaceForCmdBuf(
380     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
381     uint32_t                    dwBtEntriesRequested)
382 {
383     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
384 
385     MHW_FUNCTION_ENTER;
386 
387     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
388 
389     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
390 
391     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->RequestSshSpaceForCmdBuf(
392                    dwBtEntriesRequested));
393 
394     return eStatus;
395 }
396 
Mhw_StateHeapInterface_SetInterfaceDescriptor(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,uint32_t dwNumIdsToSet,PMHW_INTERFACE_DESCRIPTOR_PARAMS pParams)397 MOS_STATUS Mhw_StateHeapInterface_SetInterfaceDescriptor (
398         PMHW_STATE_HEAP_INTERFACE    pCommonStateHeapInterface,
399         uint32_t                            dwNumIdsToSet,
400         PMHW_INTERFACE_DESCRIPTOR_PARAMS    pParams)
401 {
402     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
403 
404     MHW_FUNCTION_ENTER;
405 
406     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
407 
408     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
409 
410     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->SetInterfaceDescriptor(
411                    dwNumIdsToSet, pParams));
412 
413     return eStatus;
414 }
415 
Mhw_StateHeapInterface_SetInterfaceDescriptorEntry(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,PMHW_ID_ENTRY_PARAMS pParams)416 MOS_STATUS Mhw_StateHeapInterface_SetInterfaceDescriptorEntry (
417     PMHW_STATE_HEAP_INTERFACE    pCommonStateHeapInterface,
418     PMHW_ID_ENTRY_PARAMS                pParams)
419 {
420     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
421 
422     MHW_FUNCTION_ENTER;
423 
424     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
425 
426     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
427 
428     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->SetInterfaceDescriptorEntry(
429                    pParams));
430 
431     return eStatus;
432 }
433 
Mhw_StateHeapInterface_SetBindingTable(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,PMHW_KERNEL_STATE pKernelState)434 MOS_STATUS Mhw_StateHeapInterface_SetBindingTable (
435     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
436     PMHW_KERNEL_STATE                  pKernelState)
437 {
438     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
439 
440     MHW_FUNCTION_ENTER;
441 
442     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
443 
444     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
445 
446     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->SetBindingTable(
447                    pKernelState));
448 
449     return eStatus;
450 }
451 
Mhw_StateHeapInterface_SetBindingTableEntry(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,PMHW_BINDING_TABLE_PARAMS pParams)452 MOS_STATUS Mhw_StateHeapInterface_SetBindingTableEntry (
453     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
454     PMHW_BINDING_TABLE_PARAMS          pParams)
455 {
456     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
457 
458     MHW_FUNCTION_ENTER;
459 
460     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
461 
462     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
463 
464     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->SetBindingTableEntry(
465                    pParams));
466 
467     return eStatus;
468 }
469 
Mhw_StateHeapInterface_SendBindingTableEntry(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,PMHW_BINDING_TABLE_SEND_PARAMS pParams)470 MOS_STATUS Mhw_StateHeapInterface_SendBindingTableEntry (
471     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
472     PMHW_BINDING_TABLE_SEND_PARAMS     pParams)
473 {
474     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
475 
476     MHW_FUNCTION_ENTER;
477 
478     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
479 
480     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
481 
482     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->SendBindingTableEntry(
483                    pParams));
484 
485     return eStatus;
486 }
487 
Mhw_StateHeapInterface_SetSurfaceState(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,PMHW_KERNEL_STATE pKernelState,PMOS_COMMAND_BUFFER pCmdBuffer,uint32_t dwNumSurfaceStatesToSet,PMHW_RCS_SURFACE_PARAMS pParams)488 MOS_STATUS Mhw_StateHeapInterface_SetSurfaceState(
489     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
490     PMHW_KERNEL_STATE           pKernelState,
491     PMOS_COMMAND_BUFFER         pCmdBuffer,
492     uint32_t                    dwNumSurfaceStatesToSet,
493     PMHW_RCS_SURFACE_PARAMS     pParams)
494 {
495     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
496 
497     MHW_FUNCTION_ENTER;
498 
499     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
500 
501     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
502 
503     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->SetSurfaceState(
504                    pKernelState,pCmdBuffer, dwNumSurfaceStatesToSet, pParams));
505 
506     return eStatus;
507 }
508 
Mhw_StateHeapInterface_SetSurfaceStateEntry(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,PMHW_SURFACE_STATE_PARAMS pParams)509 MOS_STATUS Mhw_StateHeapInterface_SetSurfaceStateEntry(
510     PMHW_STATE_HEAP_INTERFACE    pCommonStateHeapInterface,
511     PMHW_SURFACE_STATE_PARAMS           pParams)
512 {
513     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
514 
515     MHW_FUNCTION_ENTER;
516 
517     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
518 
519     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
520 
521     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->SetSurfaceStateEntry(
522                    pParams));
523 
524     return eStatus;
525 }
526 
Mhw_StateHeapInterface_InitSamplerStates(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,void * pSampler,int32_t iSamplers)527 MOS_STATUS Mhw_StateHeapInterface_InitSamplerStates(
528     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
529     void                        *pSampler,
530     int32_t                     iSamplers)
531 {
532     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
533 
534     MHW_FUNCTION_ENTER;
535 
536     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
537 
538     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
539 
540     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->InitSamplerStates(
541                    pSampler,iSamplers));
542 
543     return eStatus;
544 }
545 
Mhw_StateHeapInterface_SetSamplerState(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,void * pSampler,PMHW_SAMPLER_STATE_PARAM pParams)546 MOS_STATUS Mhw_StateHeapInterface_SetSamplerState(
547     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface,
548     void                               *pSampler,
549     PMHW_SAMPLER_STATE_PARAM           pParams)
550 {
551     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
552 
553     MHW_FUNCTION_ENTER;
554 
555     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
556 
557     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface->pStateHeapInterface);
558 
559     MHW_CHK_STATUS_RETURN(pCommonStateHeapInterface->pStateHeapInterface->SetSamplerState(
560                    pSampler,pParams));
561 
562     return eStatus;
563 }
564 
Mhw_StateHeapInterface_DSH_CalculateSpaceNeeded(PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,MHW_STATE_HEAP_TYPE StateHeapType,PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)565 uint32_t Mhw_StateHeapInterface_DSH_CalculateSpaceNeeded(
566     PMHW_STATE_HEAP_INTERFACE            pStateHeapInterface,
567     MHW_STATE_HEAP_TYPE                  StateHeapType,
568     PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)
569 {
570     if (pStateHeapInterface == nullptr)
571     {
572         MHW_ASSERTMESSAGE("Invalid Input Parameter");
573         return 0;
574     }
575     else
576     {
577         if (pStateHeapInterface->pStateHeapInterface == nullptr)
578         {
579             MHW_ASSERTMESSAGE("Invalid Input Parameter");
580             return 0;
581         }
582     }
583 
584     return  pStateHeapInterface->pStateHeapInterface->CalculateSpaceNeededDyn(
585             StateHeapType,  pParams);
586 }
587 
Mhw_StateHeapInterface_DSH_AllocateDynamicBlock(PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,MHW_STATE_HEAP_TYPE StateHeapType,PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)588 PMHW_STATE_HEAP_MEMORY_BLOCK Mhw_StateHeapInterface_DSH_AllocateDynamicBlock(
589         PMHW_STATE_HEAP_INTERFACE            pStateHeapInterface,
590         MHW_STATE_HEAP_TYPE                  StateHeapType,
591         PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)
592 {
593     if (pStateHeapInterface == nullptr)
594     {
595         MHW_ASSERTMESSAGE("Invalid Input Parameter");
596         return (PMHW_STATE_HEAP_MEMORY_BLOCK)0;
597     }
598     else
599     {
600         if (pStateHeapInterface->pStateHeapInterface == nullptr)
601         {
602             MHW_ASSERTMESSAGE("Invalid Input Parameter");
603             return (PMHW_STATE_HEAP_MEMORY_BLOCK)0;
604         }
605     }
606 
607     return pStateHeapInterface->pStateHeapInterface->AllocateDynamicBlockDyn(
608         StateHeapType,  pParams);
609 }
610 
Mhw_StateHeapInterface_DSH_SubmitDynamicBlock(PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,MHW_STATE_HEAP_TYPE StateHeapType,PMHW_STATE_HEAP_MEMORY_BLOCK pBlock,FrameTrackerTokenFlat * trackerToken)611 MOS_STATUS Mhw_StateHeapInterface_DSH_SubmitDynamicBlock(
612         PMHW_STATE_HEAP_INTERFACE            pStateHeapInterface,
613         MHW_STATE_HEAP_TYPE                  StateHeapType,
614         PMHW_STATE_HEAP_MEMORY_BLOCK         pBlock,
615         FrameTrackerTokenFlat                *trackerToken)
616 {
617     MHW_CHK_NULL_RETURN(pStateHeapInterface);
618     MHW_CHK_NULL_RETURN(pStateHeapInterface->pStateHeapInterface);
619 
620     return pStateHeapInterface->pStateHeapInterface->SubmitDynamicBlockDyn(
621         StateHeapType,  pBlock,  trackerToken);
622 }
623 
Mhw_StateHeapInterface_DSH_FreeDynamicBlock(PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,MHW_STATE_HEAP_TYPE StateHeapType,PMHW_STATE_HEAP_MEMORY_BLOCK pBlock)624 MOS_STATUS Mhw_StateHeapInterface_DSH_FreeDynamicBlock(
625         PMHW_STATE_HEAP_INTERFACE            pStateHeapInterface,
626         MHW_STATE_HEAP_TYPE                  StateHeapType,
627         PMHW_STATE_HEAP_MEMORY_BLOCK         pBlock)
628 {
629     MHW_CHK_NULL_RETURN(pStateHeapInterface);
630     MHW_CHK_NULL_RETURN(pStateHeapInterface->pStateHeapInterface);
631 
632     return pStateHeapInterface->pStateHeapInterface->FreeDynamicBlockDyn(
633         StateHeapType,  pBlock);
634 }
635 
Mhw_StateHeapInterface_DSH_RefreshDynamicHeap(PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,MHW_STATE_HEAP_TYPE StateHeapType)636 MOS_STATUS Mhw_StateHeapInterface_DSH_RefreshDynamicHeap (
637     PMHW_STATE_HEAP_INTERFACE   pStateHeapInterface,
638     MHW_STATE_HEAP_TYPE         StateHeapType)
639 {
640     MHW_CHK_NULL_RETURN(pStateHeapInterface);
641     MHW_CHK_NULL_RETURN(pStateHeapInterface->pStateHeapInterface);
642 
643     return pStateHeapInterface->pStateHeapInterface->RefreshDynamicHeapDyn(
644          StateHeapType);
645 }
646 
Mhw_StateHeapInterface_DSH_ReleaseStateHeap(PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,PMHW_STATE_HEAP pStateHeap)647 MOS_STATUS Mhw_StateHeapInterface_DSH_ReleaseStateHeap(
648     PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,
649     PMHW_STATE_HEAP pStateHeap)
650 {
651     MHW_CHK_NULL_RETURN(pStateHeapInterface);
652     MHW_CHK_NULL_RETURN(pStateHeapInterface->pStateHeapInterface);
653 
654     return pStateHeapInterface->pStateHeapInterface->ReleaseStateHeapDyn(pStateHeap);
655 }
656 
657 //!
658 //! \brief    Allocates the state heap interface internal parameters
659 //! \details  Internal MHW function to allocate all parameters needed for the
660 //!           state heap interface
661 //! \param    PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
662 //!           [in] State heap interface
663 //! \param    MHW_STATE_HEAP_SETTINGS StateHeapSettings
664 //!           [in] Setting used to initialize the state heap interface
665 //! \return   MOS_STATUS
666 //!           MOS_STATUS_SUCCESS if success, else fail reason
667 //!
Mhw_StateHeapInterface_Create(PMHW_STATE_HEAP_INTERFACE * ppStateHeapInterface,MHW_STATE_HEAP_SETTINGS StateHeapSettings)668 MOS_STATUS Mhw_StateHeapInterface_Create(
669     PMHW_STATE_HEAP_INTERFACE   *ppStateHeapInterface,
670     MHW_STATE_HEAP_SETTINGS     StateHeapSettings)
671 {
672     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
673 
674     MHW_FUNCTION_ENTER;
675     MHW_CHK_NULL_RETURN(ppStateHeapInterface);
676     MHW_CHK_NULL_RETURN(*ppStateHeapInterface);
677 
678     MHW_CHK_NULL_RETURN((*ppStateHeapInterface)->pStateHeapInterface);
679 
680     MHW_CHK_STATUS_RETURN((*ppStateHeapInterface)->pStateHeapInterface->InitializeInterface(
681         StateHeapSettings));
682 
683     return eStatus;
684 }
685 //!
686 //! \brief    Destroys the state heap interface
687 //! \details  Internal MHW function to destroy the state heap interface
688 //! \param    PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
689 //!           [in] State heap interface
690 //! \return   MOS_STATUS
691 //!           MOS_STATUS_SUCCESS if success, else fail reason
692 //!
Mhw_StateHeapInterface_Destroy(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface)693 MOS_STATUS Mhw_StateHeapInterface_Destroy(
694     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface)
695 {
696     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
697 
698     MHW_FUNCTION_ENTER;
699 
700     if (pCommonStateHeapInterface)
701     {
702         if (pCommonStateHeapInterface->pStateHeapInterface)
703         {
704             MOS_Delete(pCommonStateHeapInterface->pStateHeapInterface);
705         }
706         MOS_FreeMemory(pCommonStateHeapInterface);
707     }
708 
709     return eStatus;
710 }
711 
712 //!
713 //! \brief    Assign the state heap interfaces
714 //! \details  Internal MHW function to assign all function pointers
715 //! \param    PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
716 //!           [in/out] Pointer to state heap interface
717 //! \return   MOS_STATUS
718 //!           MOS_STATUS_SUCCESS if success, else fail reason
719 //!
Mhw_StateHeapInterface_AssignInterfaces(PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface)720 MOS_STATUS Mhw_StateHeapInterface_AssignInterfaces(
721     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface)
722 {
723     MHW_FUNCTION_ENTER;
724 
725     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
726     //Common Interfaces
727     pCommonStateHeapInterface->pfnCreate                          = Mhw_StateHeapInterface_Create;
728     pCommonStateHeapInterface->pfnDestroy                         = Mhw_StateHeapInterface_Destroy;
729     pCommonStateHeapInterface->pfnLockStateHeap                   = Mhw_StateHeapInterface_LockStateHeap;
730     pCommonStateHeapInterface->pfnUnlockStateHeap                 = Mhw_StateHeapInterface_UnlockStateHeap;
731     pCommonStateHeapInterface->pfnAssignSpaceInStateHeap          = Mhw_StateHeapInterface_AssignSpaceInStateHeap;
732     pCommonStateHeapInterface->pfnSubmitBlocks                    = Mhw_StateHeapInterface_SubmitBlocks;
733     pCommonStateHeapInterface->pfnExtendStateHeap                 = Mhw_StateHeapInterface_ExtendStateHeap;
734     pCommonStateHeapInterface->pfnUpdateGlobalCmdBufId            = Mhw_StateHeapInterface_UpdateGlobalCmdBufId;
735     pCommonStateHeapInterface->pfnSetCmdBufStatusPtr              = Mhw_StateHeapInterface_SetCmdBufStatusPtr;
736     pCommonStateHeapInterface->pfnRequestSshSpaceForCmdBuf        = Mhw_StateHeapInterface_RequestSshSpaceForCmdBuf;
737     pCommonStateHeapInterface->pfnCalculateSshAndBtSizesRequested = Mhw_StateHeapInterface_CalculateSshAndBtSizesRequested;
738 
739     //Interfaces in dynamic mode
740     pCommonStateHeapInterface->pfnCalculateDynamicSpaceNeeded     = Mhw_StateHeapInterface_DSH_CalculateSpaceNeeded;
741     pCommonStateHeapInterface->pfnAllocateDynamicBlock            = Mhw_StateHeapInterface_DSH_AllocateDynamicBlock;
742     pCommonStateHeapInterface->pfnSubmitDynamicBlock              = Mhw_StateHeapInterface_DSH_SubmitDynamicBlock;
743     pCommonStateHeapInterface->pfnFreeDynamicBlock                = Mhw_StateHeapInterface_DSH_FreeDynamicBlock;
744     pCommonStateHeapInterface->pfnRefreshDynamicHeap              = Mhw_StateHeapInterface_DSH_RefreshDynamicHeap;
745     pCommonStateHeapInterface->pfnReleaseStateHeap                = Mhw_StateHeapInterface_DSH_ReleaseStateHeap;
746 
747     //Generic Interfaces
748     pCommonStateHeapInterface->pfnSetInterfaceDescriptor      = Mhw_StateHeapInterface_SetInterfaceDescriptor;
749     pCommonStateHeapInterface->pfnSetInterfaceDescriptorEntry = Mhw_StateHeapInterface_SetInterfaceDescriptorEntry;
750     pCommonStateHeapInterface->pfnSetBindingTable             = Mhw_StateHeapInterface_SetBindingTable;
751     pCommonStateHeapInterface->pfnSetSurfaceState             = Mhw_StateHeapInterface_SetSurfaceState;
752     pCommonStateHeapInterface->pfnSetBindingTableEntry        = Mhw_StateHeapInterface_SetBindingTableEntry;
753     pCommonStateHeapInterface->pfnSendBindingTableEntry       = Mhw_StateHeapInterface_SendBindingTableEntry;
754     pCommonStateHeapInterface->pfnSetSurfaceStateEntry        = Mhw_StateHeapInterface_SetSurfaceStateEntry;
755     pCommonStateHeapInterface->pfnInitSamplerStates           = Mhw_StateHeapInterface_InitSamplerStates;
756     pCommonStateHeapInterface->pfnSetSamplerState             = Mhw_StateHeapInterface_SetSamplerState;
757 
758     return MOS_STATUS_SUCCESS;
759 }
760 
761 //!
762 //! \brief    Initializes the state heap interface
763 //! \details  Internal MHW function to initialize all function pointers and some parameters
764 //! \param    PMHW_STATE_HEAP_INTERFACE* ppStateHeapInterface
765 //!           [in/out] Poitner to state heap interface pointer to be allocated
766 //! \param    PMOS_INTERFACE pOsInterface
767 //!           [in] OS interface
768 //! \return   MOS_STATUS
769 //!           MOS_STATUS_SUCCESS if success, else fail reason
770 //!
Mhw_StateHeapInterface_InitInterface(PMHW_STATE_HEAP_INTERFACE * ppCommonStateHeapInterface,PMOS_INTERFACE pOsInterface,uint8_t bDynamicMode)771 MOS_STATUS Mhw_StateHeapInterface_InitInterface(
772     PMHW_STATE_HEAP_INTERFACE   *ppCommonStateHeapInterface,
773     PMOS_INTERFACE              pOsInterface,
774     uint8_t                     bDynamicMode)
775 {
776     PMHW_STATE_HEAP_INTERFACE   pCommonStateHeapInterface = nullptr;
777     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
778     MhwInterfacesNext::CreateParams params;
779     MhwInterfacesNext           *mhwInterfaces = nullptr;
780 
781     MHW_FUNCTION_ENTER;
782 
783     MHW_CHK_NULL_RETURN(ppCommonStateHeapInterface);
784     MHW_CHK_NULL_RETURN(pOsInterface);
785 
786     pCommonStateHeapInterface =
787         (PMHW_STATE_HEAP_INTERFACE)MOS_AllocAndZeroMemory(sizeof(MHW_STATE_HEAP_INTERFACE));
788     MHW_CHK_NULL_RETURN(pCommonStateHeapInterface);
789     do
790     {
791         eStatus = Mhw_StateHeapInterface_AssignInterfaces(pCommonStateHeapInterface);
792         if (eStatus != MOS_STATUS_SUCCESS)
793         {
794             MHW_ASSERTMESSAGE("Assign the state heap interface fail");
795             break;
796         }
797         MOS_ZeroMemory(&params, sizeof(params));
798         params.Flags.m_stateHeap = true;
799         params.m_heapMode        = bDynamicMode;
800         mhwInterfaces            = MhwInterfacesNext::CreateFactory(params, pOsInterface);
801         if (mhwInterfaces)
802         {
803             if (mhwInterfaces->m_stateHeapInterface==nullptr)
804             {
805                 MHW_ASSERTMESSAGE("m_stateHeapInterface is nullptr");
806                 eStatus = MOS_STATUS_NULL_POINTER;
807                 break;
808             }
809             pCommonStateHeapInterface->pStateHeapInterface = mhwInterfaces->m_stateHeapInterface;
810             // MhwInterfaces always create CP interfaces, so we have to delete those we don't need.
811             pOsInterface->pfnDeleteMhwCpInterface(mhwInterfaces->m_cpInterface);
812             mhwInterfaces->m_cpInterface = NULL;
813             MOS_Delete(mhwInterfaces);
814         }
815         else
816         {
817             MHW_ASSERTMESSAGE("Allocate MhwInterfaces failed");
818             eStatus = MOS_STATUS_NO_SPACE;
819             break;
820         }
821         *ppCommonStateHeapInterface = pCommonStateHeapInterface;
822     } while (false);
823 
824     if (eStatus != MOS_STATUS_SUCCESS && pCommonStateHeapInterface)
825     {
826         pCommonStateHeapInterface->pfnDestroy(pCommonStateHeapInterface);
827         *ppCommonStateHeapInterface = nullptr;
828     }
829     return eStatus;
830 }
831 
XMHW_STATE_HEAP_INTERFACE(PMOS_INTERFACE pInputOSInterface,int8_t bDynamicMode)832 XMHW_STATE_HEAP_INTERFACE::XMHW_STATE_HEAP_INTERFACE(
833     PMOS_INTERFACE pInputOSInterface,
834     int8_t         bDynamicMode):
835     m_pWaTable(nullptr),
836     m_pdwCmdBufIdGlobal(nullptr),
837     m_dwCurrCmdBufId(0),
838     m_pSyncTags(nullptr),
839     m_dwCurrSyncTag(0),
840     m_dwInvalidSyncTagId(0),
841     m_bRegisteredBBCompleteNotifyEvent(false),
842     m_pInstructionStateHeaps(nullptr),
843     m_dwNumIsh(0),
844     m_dwNumDsh(0),
845     m_pDynamicStateHeaps(nullptr),
846     m_bDynamicMode(bDynamicMode),
847     m_pIshBlockManager(nullptr),
848     m_pDshBlockManager(nullptr),
849     m_pOsInterface(pInputOSInterface),
850     m_wIdAlignment(0),
851     m_wBtIdxAlignment(0),
852     m_wCurbeAlignment(0),
853     m_wSizeOfCmdSamplerState(0),
854     m_dwMaxSurfaceStateSize(0),
855     m_pfnAddResourceToCmd(nullptr),
856     m_wSizeOfCmdInterfaceDescriptorData(0)
857 {
858     MHW_FUNCTION_ENTER;
859 
860     MOS_ZeroMemory(&m_resCmdBufIdGlobal, sizeof(m_resCmdBufIdGlobal));
861     MOS_ZeroMemory(&m_SurfaceStateHeap, sizeof(m_SurfaceStateHeap));
862     MOS_ZeroMemory(&m_HwSizes, sizeof(m_HwSizes));
863     MOS_ZeroMemory(&m_StateHeapSettings, sizeof(m_StateHeapSettings));
864 }
865 
~XMHW_STATE_HEAP_INTERFACE()866 XMHW_STATE_HEAP_INTERFACE::~XMHW_STATE_HEAP_INTERFACE()
867 {
868     MHW_FUNCTION_ENTER;
869 
870     if (m_bDynamicMode == MHW_DGSH_MODE)
871     {
872         // heap manager destructors called automatically
873         return;
874     }
875 
876     PMHW_STATE_HEAP              pStateHeapPtr, pStateHeapNext;
877     PMHW_STATE_HEAP_MEMORY_BLOCK pMemBlkPtr, pMemBlkNext;
878 
879     //Release m_SyncTags
880     MOS_FreeMemory(m_pSyncTags);
881 
882     // Destroy all memory block objects and block manager objects for ISH, DSH
883     if(m_bDynamicMode == MHW_DSH_MODE)
884     {
885         MOS_Delete(m_pIshBlockManager);
886         MOS_Delete(m_pDshBlockManager);
887     }
888 
889     //Release m_resCmdBufIdGlobal
890     if (m_pOsInterface != nullptr)
891     {
892         m_pOsInterface->pfnUnlockResource(m_pOsInterface, &m_resCmdBufIdGlobal);
893         m_pOsInterface->pfnFreeResource(m_pOsInterface, &m_resCmdBufIdGlobal);
894     }
895 
896     //Free ISH
897     pStateHeapPtr = m_pInstructionStateHeaps;
898     for (uint32_t i = 0; i < m_dwNumIsh; i++)
899     {
900         pStateHeapNext = pStateHeapPtr->pNext;
901         if (m_pOsInterface != nullptr)
902         {
903             if (pStateHeapPtr->bKeepLocked)
904             {
905                 pStateHeapPtr->bKeepLocked = false;
906                 UnLockStateHeap(pStateHeapPtr);
907             }
908             m_pOsInterface->pfnFreeResource(m_pOsInterface, &pStateHeapPtr->resHeap);
909         }
910 
911         if(m_bDynamicMode == MHW_RENDER_HAL_MODE)
912         {
913             pMemBlkPtr = pStateHeapPtr->pMemoryHead;
914             while (pMemBlkPtr)
915             {
916                 pMemBlkNext = pMemBlkPtr->pNext;
917                 MOS_FreeMemory(pMemBlkPtr);
918                 pMemBlkPtr = pMemBlkNext;
919             }
920         }
921         MOS_FreeMemory(pStateHeapPtr);
922         pStateHeapPtr = pStateHeapNext;
923     }
924 
925     // Free DSH
926     pStateHeapPtr = m_pDynamicStateHeaps;
927     for (uint32_t i = 0; i < m_dwNumDsh; i++)
928     {
929         if (pStateHeapPtr == nullptr)
930         {
931             return;
932         }
933 
934         pStateHeapNext = pStateHeapPtr->pNext;
935         if (m_pOsInterface != nullptr)
936         {
937             if (pStateHeapPtr->bKeepLocked)
938             {
939                 pStateHeapPtr->bKeepLocked = false;
940                 UnLockStateHeap(pStateHeapPtr);
941             }
942             m_pOsInterface->pfnFreeResource(m_pOsInterface, &pStateHeapPtr->resHeap);
943         }
944 
945         if(m_bDynamicMode == MHW_RENDER_HAL_MODE)
946         {
947             pMemBlkPtr = pStateHeapPtr->pMemoryHead;
948             while (pMemBlkPtr)
949             {
950                 pMemBlkNext = pMemBlkPtr->pNext;
951                 MOS_FreeMemory(pMemBlkPtr);
952                 pMemBlkPtr = pMemBlkNext;
953             }
954         }
955 
956         MOS_FreeMemory(pStateHeapPtr);
957         pStateHeapPtr = pStateHeapNext;
958     }
959 
960     return ;
961 }
962 
InitializeInterface(MHW_STATE_HEAP_SETTINGS StateHeapSettings)963 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::InitializeInterface(
964     MHW_STATE_HEAP_SETTINGS StateHeapSettings)
965 {
966     MOS_ALLOC_GFXRES_PARAMS     AllocParams;
967     MOS_LOCK_PARAMS             LockParams;
968     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
969 
970     MHW_FUNCTION_ENTER;
971 
972     //state heap settings
973     m_StateHeapSettings = StateHeapSettings;
974 
975     MHW_CHK_NULL_RETURN(m_pOsInterface);
976 
977     m_pWaTable  = m_pOsInterface->pfnGetWaTable(m_pOsInterface);
978 
979     if (m_pOsInterface->bUsesGfxAddress)
980     {
981         m_pfnAddResourceToCmd = Mhw_AddResourceToCmd_GfxAddress;
982     }
983     else if (m_pOsInterface->bUsesPatchList)
984     {
985         m_pfnAddResourceToCmd = Mhw_AddResourceToCmd_PatchList;
986     }
987     else
988     {
989         // No addressing method selected
990         eStatus = MOS_STATUS_UNKNOWN;
991         return eStatus;
992     }
993 
994     if (m_bDynamicMode == MHW_DGSH_MODE)
995     {
996         m_ishManager.RegisterOsInterface(m_pOsInterface);
997         m_ishManager.SetDefaultBehavior(StateHeapSettings.m_ishBehavior);
998         MHW_MI_CHK_STATUS(m_ishManager.SetInitialHeapSize(StateHeapSettings.dwIshSize));
999         if (StateHeapSettings.m_ishBehavior == HeapManager::Behavior::extend ||
1000             StateHeapSettings.m_ishBehavior == HeapManager::Behavior::destructiveExtend ||
1001             StateHeapSettings.m_ishBehavior == HeapManager::Behavior::waitAndExtend)
1002         {
1003             m_ishManager.SetExtendHeapSize(StateHeapSettings.dwIshIncrement);
1004         }
1005         if (StateHeapSettings.m_keepIshLocked)
1006         {
1007             MHW_MI_CHK_STATUS(m_ishManager.LockHeapsOnAllocate());
1008         }
1009 
1010         m_dshManager.RegisterOsInterface(m_pOsInterface);
1011         m_dshManager.SetDefaultBehavior(StateHeapSettings.m_dshBehavior);
1012         MHW_MI_CHK_STATUS(m_dshManager.SetInitialHeapSize(StateHeapSettings.dwDshSize));
1013         if (StateHeapSettings.m_dshBehavior == HeapManager::Behavior::extend ||
1014             StateHeapSettings.m_dshBehavior == HeapManager::Behavior::destructiveExtend ||
1015             StateHeapSettings.m_dshBehavior == HeapManager::Behavior::waitAndExtend)
1016         {
1017             m_dshManager.SetExtendHeapSize(StateHeapSettings.dwDshIncrement);
1018         }
1019         if (StateHeapSettings.m_keepDshLocked)
1020         {
1021             MHW_MI_CHK_STATUS(m_dshManager.LockHeapsOnAllocate());
1022         }
1023 
1024         return MOS_STATUS_SUCCESS;
1025     }
1026 
1027     //Sync tags and sync tag id
1028     if (m_pSyncTags == nullptr)
1029     {
1030         m_pSyncTags = (PMHW_SYNC_TAG)MOS_AllocAndZeroMemory(sizeof(MHW_SYNC_TAG) *
1031                                                             StateHeapSettings.dwNumSyncTags);
1032     }
1033     MHW_CHK_NULL_RETURN(m_pSyncTags);
1034 
1035     if(m_bDynamicMode == MHW_DSH_MODE)
1036     {
1037         m_dwInvalidSyncTagId = 0;
1038 
1039         //Allocate block manager for ISH
1040         m_pIshBlockManager = MOS_New(MHW_BLOCK_MANAGER, nullptr);
1041         MHW_CHK_NULL_RETURN(m_pIshBlockManager);
1042 
1043 
1044     }
1045     else // m_bDynamicMode == MHW_RENDER_HAL_MODE
1046     {
1047         m_dwInvalidSyncTagId = StateHeapSettings.dwNumSyncTags;
1048 
1049         //Extend state heap for DSH
1050         MHW_CHK_STATUS_RETURN(ExtendStateHeap(
1051             MHW_DSH_TYPE,
1052             StateHeapSettings.dwDshSize));
1053         if (StateHeapSettings.m_keepDshLocked)
1054         {
1055             MHW_CHK_STATUS_RETURN(LockStateHeap(m_pDynamicStateHeaps));
1056             m_pDynamicStateHeaps->bKeepLocked = true;
1057         }
1058     }
1059 
1060     //Allocate resCmdBufIdGlobal
1061     MOS_ZeroMemory(&AllocParams, sizeof(AllocParams));
1062     AllocParams.Type     = MOS_GFXRES_BUFFER;
1063     AllocParams.TileType = MOS_TILE_LINEAR;
1064     AllocParams.Format   = Format_Buffer;
1065     AllocParams.dwBytes  = MHW_CACHELINE_SIZE;
1066     AllocParams.pBufName = "CmdBufIdGlobal";
1067     if (Mos_ResourceIsNull(&m_resCmdBufIdGlobal))
1068     {
1069         MHW_CHK_STATUS_RETURN(m_pOsInterface->pfnAllocateResource(
1070             m_pOsInterface,
1071             &AllocParams,
1072             &m_resCmdBufIdGlobal));
1073         m_dwCurrCmdBufId = 1;
1074     }
1075 
1076     MOS_ZeroMemory(&LockParams, sizeof(LockParams));
1077     LockParams.WriteOnly = 1;
1078     m_pdwCmdBufIdGlobal = (uint32_t*)m_pOsInterface->pfnLockResource(
1079         m_pOsInterface,
1080         &m_resCmdBufIdGlobal,
1081         &LockParams);
1082     MHW_CHK_NULL_RETURN(m_pdwCmdBufIdGlobal);
1083     MOS_ZeroMemory(m_pdwCmdBufIdGlobal, AllocParams.dwBytes);
1084     m_dwCurrCmdBufId = 1;
1085 
1086     //Extend state heap for ISH
1087     MHW_CHK_STATUS_RETURN(ExtendStateHeap(
1088         MHW_ISH_TYPE,
1089         StateHeapSettings.dwIshSize));
1090     if (StateHeapSettings.m_keepIshLocked)
1091     {
1092         MHW_CHK_NULL_RETURN(m_pInstructionStateHeaps);
1093         MHW_CHK_STATUS_RETURN(LockStateHeap(m_pInstructionStateHeaps));
1094         m_pInstructionStateHeaps->bKeepLocked = true;
1095     }
1096 
1097     return eStatus;
1098 }
1099 
InitMemoryBlock(PMHW_STATE_HEAP pStateHeap,PMHW_STATE_HEAP_MEMORY_BLOCK * ppMemoryBlock,uint32_t dwRequestedSize,bool bStatic)1100 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::InitMemoryBlock(
1101     PMHW_STATE_HEAP                 pStateHeap,
1102     PMHW_STATE_HEAP_MEMORY_BLOCK    *ppMemoryBlock,
1103     uint32_t                        dwRequestedSize,
1104     bool                            bStatic)
1105 {
1106     PMHW_STATE_HEAP_MEMORY_BLOCK    pMemoryBlock;
1107     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1108 
1109     MHW_CHK_NULL_RETURN(ppMemoryBlock);
1110 
1111     if (dwRequestedSize > 0)
1112     {
1113         pMemoryBlock = (PMHW_STATE_HEAP_MEMORY_BLOCK)MOS_AllocAndZeroMemory(
1114                         sizeof(MHW_STATE_HEAP_MEMORY_BLOCK));
1115         MHW_CHK_NULL_RETURN(pMemoryBlock);
1116 
1117         FrameTrackerTokenFlat_Invalidate(&pMemoryBlock->trackerToken);
1118         pMemoryBlock->dwBlockSize = dwRequestedSize;
1119         pMemoryBlock->pStateHeap = pStateHeap;
1120         pMemoryBlock->bStatic = bStatic;
1121 
1122         *ppMemoryBlock = pMemoryBlock;
1123     }
1124 
1125     return eStatus;
1126 }
1127 
InsertMemoryBlock(PMHW_STATE_HEAP_MEMORY_BLOCK pMemoryBlockFree,PMHW_STATE_HEAP_MEMORY_BLOCK pMemoryBlockToAdd)1128 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::InsertMemoryBlock(
1129         PMHW_STATE_HEAP_MEMORY_BLOCK    pMemoryBlockFree,
1130         PMHW_STATE_HEAP_MEMORY_BLOCK    pMemoryBlockToAdd)
1131 {
1132     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1133 
1134     MHW_CHK_NULL_RETURN(pMemoryBlockFree);
1135     MHW_CHK_NULL_RETURN(pMemoryBlockToAdd);
1136 
1137     if (pMemoryBlockFree->dwBlockSize < pMemoryBlockToAdd->dwBlockSize)
1138     {
1139         MHW_ASSERTMESSAGE("Free block does not have enough space to contain new block.");
1140         eStatus = MOS_STATUS_NO_SPACE;
1141         return eStatus;
1142     }
1143 
1144     pMemoryBlockFree->dwBlockSize -= pMemoryBlockToAdd->dwBlockSize;
1145     pMemoryBlockToAdd->dwOffsetInStateHeap =
1146         pMemoryBlockFree->dwOffsetInStateHeap + pMemoryBlockFree->dwBlockSize;
1147 
1148     MHW_CHK_STATUS_RETURN(InsertLinkedList(
1149         pMemoryBlockFree,
1150         pMemoryBlockToAdd));
1151 
1152     return eStatus;
1153 }
1154 
InsertLinkedList(PMHW_STATE_HEAP_MEMORY_BLOCK pStartNode,PMHW_STATE_HEAP_MEMORY_BLOCK pNodeToAdd)1155 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::InsertLinkedList(
1156         PMHW_STATE_HEAP_MEMORY_BLOCK    pStartNode,
1157         PMHW_STATE_HEAP_MEMORY_BLOCK    pNodeToAdd)
1158 {
1159     PMHW_STATE_HEAP_MEMORY_BLOCK    pStartNext;
1160     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1161 
1162     MHW_CHK_NULL_RETURN(pStartNode);
1163     MHW_CHK_NULL_RETURN(pNodeToAdd);
1164 
1165     pStartNext = pStartNode->pNext;
1166 
1167     pStartNode->pNext = pNodeToAdd;
1168     pNodeToAdd->pPrev = pStartNode;
1169     pNodeToAdd->pNext = pStartNext;
1170     if (pStartNext)
1171     {
1172         pStartNext->pPrev = pNodeToAdd;
1173     }
1174 
1175     return eStatus;
1176 }
1177 
ReturnSpaceMemoryBlock(PMHW_STATE_HEAP_MEMORY_BLOCK pMemoryBlock)1178 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::ReturnSpaceMemoryBlock(
1179     PMHW_STATE_HEAP_MEMORY_BLOCK    pMemoryBlock)
1180 {
1181     PMHW_STATE_HEAP_MEMORY_BLOCK    pPrevBlock, pNextBlock;
1182     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1183 
1184     MHW_CHK_NULL_RETURN(pMemoryBlock);
1185 
1186     if (pMemoryBlock->bStatic)
1187     {
1188         MHW_VERBOSEMESSAGE("Static blocks do not need to be cleaned up.");
1189         return eStatus;
1190     }
1191 
1192     pPrevBlock = pMemoryBlock->pPrev;
1193     pNextBlock = pMemoryBlock->pNext;
1194 
1195     FrameTrackerTokenFlat_Invalidate(&pMemoryBlock->trackerToken);
1196 
1197     if (pPrevBlock && !pPrevBlock->bStatic)
1198     {
1199         if (!FrameTrackerTokenFlat_IsValid(&pPrevBlock->trackerToken))
1200         {
1201             pPrevBlock->dwBlockSize += pMemoryBlock->dwBlockSize;
1202             pPrevBlock->pNext = pNextBlock;
1203             if (pNextBlock)
1204             {
1205                 pNextBlock->pPrev = pPrevBlock;
1206             }
1207             MOS_FreeMemory(pMemoryBlock);
1208             pMemoryBlock = pPrevBlock;
1209         }
1210     }
1211 
1212     if (pNextBlock && !pNextBlock->bStatic)
1213     {
1214         if (!FrameTrackerTokenFlat_IsValid(&pNextBlock->trackerToken))
1215         {
1216             pMemoryBlock->dwBlockSize += pNextBlock->dwBlockSize;
1217             pMemoryBlock->pNext = pNextBlock->pNext;
1218             if (pNextBlock->pNext)
1219             {
1220                 pNextBlock->pNext->pPrev = pMemoryBlock;
1221             }
1222             MOS_FreeMemory(pNextBlock);
1223         }
1224     }
1225 
1226     return eStatus;
1227 }
1228 
AssignSpaceInStateHeap(MHW_STATE_HEAP_TYPE StateHeapType,PMHW_KERNEL_STATE pKernelState,uint32_t dwSpaceRequested,bool bStatic,bool bZeroAssignedMem)1229 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::AssignSpaceInStateHeap(
1230     MHW_STATE_HEAP_TYPE         StateHeapType,
1231     PMHW_KERNEL_STATE           pKernelState,
1232     uint32_t                    dwSpaceRequested,
1233     bool                        bStatic,
1234     bool                        bZeroAssignedMem)
1235 {
1236     MHW_FUNCTION_ENTER;
1237 
1238     MHW_MI_CHK_NULL(pKernelState);
1239 
1240     HeapManager *heapManager = nullptr;
1241     MemoryBlock *requestedBlock = nullptr;
1242     if (StateHeapType == MHW_ISH_TYPE)
1243     {
1244         heapManager = &m_ishManager;
1245         requestedBlock = &pKernelState->m_ishRegion;
1246     }
1247     else if (StateHeapType == MHW_DSH_TYPE)
1248     {
1249         heapManager = &m_dshManager;
1250         requestedBlock = &pKernelState->m_dshRegion;
1251     }
1252     else if (StateHeapType == MHW_SSH_TYPE)
1253     {
1254         pKernelState->dwSshOffset = m_SurfaceStateHeap.dwCurrOffset;
1255         m_SurfaceStateHeap.dwCurrOffset += pKernelState->dwSshSize;
1256         if (m_SurfaceStateHeap.dwCurrOffset > m_SurfaceStateHeap.dwSize)
1257         {
1258             MHW_ASSERTMESSAGE("Insufficient space requested for SSH");
1259             return MOS_STATUS_NO_SPACE;
1260         }
1261         return MOS_STATUS_SUCCESS;
1262     }
1263     else
1264     {
1265         MHW_ASSERTMESSAGE("Unsupported state heap type.");
1266         return MOS_STATUS_INVALID_PARAMETER;
1267     }
1268     MHW_MI_CHK_NULL(heapManager);
1269 
1270     uint32_t spaceNeeded = 0;
1271     MemoryBlockManager::AcquireParams acquireParams =
1272         MemoryBlockManager::AcquireParams(pKernelState->m_currTrackerId, m_blockSizes);
1273     acquireParams.m_staticBlock = bStatic ? true : false;
1274     if (m_blockSizes.empty())
1275     {
1276         m_blockSizes.emplace_back(dwSpaceRequested);
1277     }
1278     else
1279     {
1280         m_blockSizes[0] = dwSpaceRequested;
1281     }
1282 
1283     MHW_MI_CHK_STATUS(heapManager->AcquireSpace(
1284         acquireParams,
1285         m_blocks,
1286         spaceNeeded));
1287 
1288     if (m_blocks.empty())
1289     {
1290         MHW_ASSERTMESSAGE("No blocks were acquired");
1291         return MOS_STATUS_UNKNOWN;
1292     }
1293     if (!m_blocks[0].IsValid())
1294     {
1295         MHW_ASSERTMESSAGE("No blocks were acquired");
1296         return MOS_STATUS_UNKNOWN;
1297     }
1298 
1299     *requestedBlock = m_blocks[0];
1300 
1301     if (bZeroAssignedMem)
1302     {
1303         requestedBlock->AddData(nullptr, 0, 0, true);
1304     }
1305 
1306     return MOS_STATUS_SUCCESS;
1307 }
1308 
SubmitBlocks(PMHW_KERNEL_STATE pKernelState)1309 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::SubmitBlocks(PMHW_KERNEL_STATE pKernelState)
1310 {
1311     MHW_MI_CHK_NULL(pKernelState);
1312     if (!pKernelState->m_ishRegion.IsStatic())
1313     {
1314         std::vector<MemoryBlock> block;
1315         block.push_back(pKernelState->m_ishRegion);
1316         MHW_MI_CHK_STATUS(m_ishManager.SubmitBlocks(block));
1317     }
1318     if (!pKernelState->m_dshRegion.IsStatic())
1319     {
1320         std::vector<MemoryBlock> block;
1321         block.push_back(pKernelState->m_dshRegion);
1322         MHW_MI_CHK_STATUS(m_dshManager.SubmitBlocks(block));
1323     }
1324 
1325     pKernelState->m_currTrackerId = MemoryBlock::m_invalidTrackerId;
1326 
1327     return MOS_STATUS_SUCCESS;
1328 }
1329 
LockStateHeap(PMHW_STATE_HEAP pStateHeap)1330 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::LockStateHeap(
1331     PMHW_STATE_HEAP             pStateHeap)
1332 {
1333     PMOS_INTERFACE  pOsInterface = nullptr;
1334     MOS_LOCK_PARAMS LockParams;
1335     MOS_STATUS      eStatus = MOS_STATUS_SUCCESS;
1336 
1337     MHW_CHK_NULL_RETURN(pStateHeap);
1338 
1339     if (pStateHeap->bKeepLocked)
1340     {
1341         MHW_CHK_NULL_RETURN(pStateHeap->pvLockedHeap);
1342         return eStatus;
1343     }
1344 
1345     pOsInterface = m_pOsInterface;
1346 
1347     MOS_ZeroMemory(&LockParams, sizeof(LockParams));
1348     LockParams.WriteOnly = 1;
1349     LockParams.NoOverWrite = 1;
1350     LockParams.Uncached = 1;
1351     pStateHeap->pvLockedHeap =
1352         pOsInterface->pfnLockResource(pOsInterface, &pStateHeap->resHeap, &LockParams);
1353     MHW_CHK_NULL_RETURN(pStateHeap->pvLockedHeap);
1354 
1355     return eStatus;
1356 }
1357 
UnLockStateHeap(PMHW_STATE_HEAP pStateHeap)1358 MOS_STATUS  XMHW_STATE_HEAP_INTERFACE::UnLockStateHeap(
1359     PMHW_STATE_HEAP             pStateHeap)
1360 {
1361     MOS_STATUS      eStatus = MOS_STATUS_SUCCESS;
1362 
1363     MHW_CHK_NULL_RETURN(pStateHeap);
1364 
1365     if (pStateHeap->bKeepLocked)
1366     {
1367         MHW_CHK_NULL_RETURN(pStateHeap->pvLockedHeap);
1368         return eStatus;
1369     }
1370 
1371     MHW_CHK_STATUS_RETURN(m_pOsInterface->pfnUnlockResource(m_pOsInterface, &pStateHeap->resHeap));
1372 
1373     pStateHeap->pvLockedHeap = nullptr;
1374 
1375     return eStatus;
1376 }
1377 
ExtendStateHeap(MHW_STATE_HEAP_TYPE StateHeapType,uint32_t dwSizeRequested)1378 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::ExtendStateHeap(
1379     MHW_STATE_HEAP_TYPE         StateHeapType,
1380     uint32_t                    dwSizeRequested)
1381 {
1382     if (m_bDynamicMode == MHW_DSH_MODE)
1383     {
1384         return ExtendStateHeapDyn(StateHeapType,dwSizeRequested);
1385     }
1386     else if (m_bDynamicMode == MHW_RENDER_HAL_MODE)
1387     {
1388         return ExtendStateHeapSta(StateHeapType,dwSizeRequested);
1389     }
1390     else
1391     {
1392         return MOS_STATUS_UNKNOWN;
1393     }
1394 }
1395 
UpdateGlobalCmdBufId()1396 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::UpdateGlobalCmdBufId()
1397 {
1398     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1399 
1400     MHW_FUNCTION_ENTER;
1401 
1402     m_SurfaceStateHeap.dwCurrOffset = 0;
1403 
1404     return eStatus;
1405 }
1406 
SetCmdBufStatusPtr(void * pvCmdBufStatus)1407 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::SetCmdBufStatusPtr(void *pvCmdBufStatus)
1408 {
1409     MHW_FUNCTION_ENTER;
1410     MHW_MI_CHK_NULL(pvCmdBufStatus);
1411     m_pdwCmdBufIdGlobal = (uint32_t*)pvCmdBufStatus;
1412     MHW_MI_CHK_STATUS(m_ishManager.RegisterTrackerResource((uint32_t*)m_pdwCmdBufIdGlobal));
1413     MHW_MI_CHK_STATUS(m_dshManager.RegisterTrackerResource((uint32_t*)m_pdwCmdBufIdGlobal));
1414     return MOS_STATUS_SUCCESS;
1415 }
1416 
RequestSshSpaceForCmdBuf(uint32_t dwBtEntriesRequested)1417 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::RequestSshSpaceForCmdBuf(
1418     uint32_t                    dwBtEntriesRequested)
1419 {
1420     PMOS_INTERFACE      pOsInterface;
1421     PMHW_STATE_HEAP     pStateHeap;
1422     MOS_COMMAND_BUFFER  CmdBuffer;
1423     uint32_t            dwRequestedSshSize = 0, dwBtSize = 0;
1424     uint32_t            uiExistingSshSize = 0, uiExistingSshOffset = 0;
1425     MOS_STATUS          eStatus = MOS_STATUS_SUCCESS;
1426 
1427     MHW_FUNCTION_ENTER;
1428 
1429     pOsInterface    = m_pOsInterface;
1430     pStateHeap      = &m_SurfaceStateHeap;
1431     MHW_CHK_NULL_RETURN(pOsInterface);
1432     MHW_CHK_NULL_RETURN(pStateHeap);
1433 
1434     MHW_CHK_STATUS_RETURN(pOsInterface->pfnGetIndirectState(
1435         pOsInterface,
1436         &uiExistingSshOffset,
1437         &uiExistingSshSize));
1438     pStateHeap->dwSize = (uint32_t)uiExistingSshSize;
1439 
1440     dwBtSize =
1441         MOS_ALIGN_CEIL(dwBtEntriesRequested, m_wBtIdxAlignment);
1442     MHW_CHK_STATUS_RETURN(CalculateSshAndBtSizesRequested(
1443         dwBtEntriesRequested,
1444         &dwRequestedSshSize,
1445         &dwBtSize));
1446     dwRequestedSshSize = MOS_ALIGN_CEIL(dwRequestedSshSize, (1 << MHW_SSH_BASE_SHIFT));
1447 
1448     if (dwRequestedSshSize > pStateHeap->dwSize)
1449     {
1450         MHW_CHK_STATUS_RETURN(pOsInterface->pfnSetIndirectStateSize(
1451             pOsInterface,
1452             (uint32_t)dwRequestedSshSize));
1453         MOS_ZeroMemory(&CmdBuffer, sizeof(CmdBuffer));
1454         MHW_CHK_STATUS_RETURN(pOsInterface->pfnGetCommandBuffer(pOsInterface, &CmdBuffer, 0));
1455         MHW_CHK_STATUS_RETURN(pOsInterface->pfnResetCommandBuffer(pOsInterface, &CmdBuffer));
1456         pOsInterface->pfnReturnCommandBuffer(pOsInterface, &CmdBuffer, 0);
1457         pOsInterface->pfnResetOsStates(pOsInterface);
1458 
1459         m_SurfaceStateHeap.dwSize = dwRequestedSshSize;
1460     }
1461 
1462     return eStatus;
1463 }
1464 
ExtendStateHeapDyn(MHW_STATE_HEAP_TYPE StateHeapType,uint32_t dwSizeRequested)1465 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::ExtendStateHeapDyn(
1466         MHW_STATE_HEAP_TYPE         StateHeapType,
1467         uint32_t                    dwSizeRequested)
1468 {
1469     PMHW_STATE_HEAP             pNewStateHeap = nullptr;
1470     PMHW_STATE_HEAP            *ppStateHeapPtr;
1471     MOS_ALLOC_GFXRES_PARAMS     AllocParams;
1472     uint32_t                    dwNumHeaps;
1473     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
1474     PMHW_BLOCK_MANAGER          pBlockManager = nullptr;
1475     MEDIA_FEATURE_TABLE        *skuTable = nullptr;
1476 
1477     MHW_FUNCTION_ENTER;
1478     do
1479     {
1480         if (m_pOsInterface==nullptr)
1481         {
1482             MHW_ASSERTMESSAGE("m_pOsInterface is nullptr");
1483             eStatus = MOS_STATUS_NULL_POINTER;
1484             break;
1485         }
1486         if (m_pOsInterface->pfnGetSkuTable == nullptr)
1487         {
1488             MHW_ASSERTMESSAGE("pfnGetSkuTable is nullptr");
1489             eStatus = MOS_STATUS_NULL_POINTER;
1490             break;
1491         }
1492         skuTable = m_pOsInterface->pfnGetSkuTable(m_pOsInterface);
1493         if (skuTable == nullptr)
1494         {
1495             MHW_ASSERTMESSAGE("skuTable is nullptr");
1496             eStatus = MOS_STATUS_NULL_POINTER;
1497             break;
1498         }
1499         pNewStateHeap = (PMHW_STATE_HEAP)MOS_AllocAndZeroMemory(sizeof(MHW_STATE_HEAP));
1500         if (pNewStateHeap == nullptr)
1501         {
1502             MHW_ASSERTMESSAGE("pNewStateHeap is nullptr");
1503             eStatus = MOS_STATUS_NULL_POINTER;
1504             break;
1505         }
1506         pNewStateHeap->dwSize = MOS_ALIGN_CEIL(dwSizeRequested, MHW_CACHELINE_SIZE);
1507         pNewStateHeap->dwUsed = 0;
1508         pNewStateHeap->dwFree = pNewStateHeap->dwSize;
1509 
1510         pNewStateHeap->pMhwStateHeapInterface = this;
1511 
1512         MOS_ZeroMemory(&AllocParams, sizeof(AllocParams));
1513         AllocParams.Type     = MOS_GFXRES_BUFFER;
1514         AllocParams.TileType = MOS_TILE_LINEAR;
1515         AllocParams.Format   = Format_Buffer;
1516         AllocParams.dwBytes  = pNewStateHeap->dwSize;
1517         AllocParams.pBufName = "DynamicStateHeap";
1518         if (MEDIA_IS_SKU(skuTable, FtrLimitedLMemBar))
1519         {
1520             AllocParams.dwMemType = MOS_MEMPOOL_SYSTEMMEMORY;
1521         }
1522         eStatus = m_pOsInterface->pfnAllocateResource(
1523             m_pOsInterface,
1524             &AllocParams,
1525             &pNewStateHeap->resHeap);
1526         if (eStatus != MOS_STATUS_SUCCESS)
1527         {
1528             MHW_ASSERTMESSAGE("Allocate resource fail");
1529             break;
1530         }
1531         // RegisterResource will be called in AddResourceToHWCmd. It is not allowed to be called by hal explicitly
1532         if (!m_pOsInterface->apoMosEnabled)
1533         {
1534             eStatus = m_pOsInterface->pfnRegisterResource(m_pOsInterface, &pNewStateHeap->resHeap, true, true);
1535             if (eStatus != MOS_STATUS_SUCCESS)
1536             {
1537                 MHW_ASSERTMESSAGE("Reigister Resource fail");
1538                 break;
1539             }
1540         }
1541 
1542         if (StateHeapType == MHW_ISH_TYPE)
1543         {
1544             if (m_StateHeapSettings.m_keepIshLocked)
1545             {
1546                 eStatus = LockStateHeap(pNewStateHeap);
1547                 if (eStatus != MOS_STATUS_SUCCESS)
1548                 {
1549                     MHW_ASSERTMESSAGE("fail to lock state heap.");
1550                     break;
1551                 }
1552                 pNewStateHeap->bKeepLocked = true;
1553             }
1554 
1555             ppStateHeapPtr = &m_pInstructionStateHeaps;
1556             dwNumHeaps     = m_dwNumIsh++;
1557             pBlockManager  = m_pIshBlockManager;
1558         }
1559         else
1560         {
1561             if (m_StateHeapSettings.m_keepDshLocked)
1562             {
1563                 eStatus = LockStateHeap(pNewStateHeap);
1564                 if (eStatus != MOS_STATUS_SUCCESS)
1565                 {
1566                     MHW_ASSERTMESSAGE("fail to lock state heap.");
1567                     break;
1568                 }
1569                 pNewStateHeap->bKeepLocked = true;
1570             }
1571 
1572             ppStateHeapPtr = &m_pDynamicStateHeaps;
1573             dwNumHeaps     = m_dwNumDsh++;
1574             pBlockManager  = m_pDshBlockManager;
1575         }
1576 
1577         pNewStateHeap->pNext = *ppStateHeapPtr;
1578         *ppStateHeapPtr      = pNewStateHeap;
1579         if (pNewStateHeap->pNext)
1580             pNewStateHeap->pNext->pPrev = pNewStateHeap;
1581 
1582         pBlockManager->SetStateHeap(pNewStateHeap);
1583 
1584         // Register new state heap with block manager
1585         pBlockManager->RegisterStateHeap(pNewStateHeap);
1586     } while (false);
1587 
1588     if (eStatus != MOS_STATUS_SUCCESS)
1589     {
1590         if (pNewStateHeap)
1591         {
1592             if (m_pOsInterface)
1593             {
1594                 m_pOsInterface->pfnFreeResource(m_pOsInterface, &pNewStateHeap->resHeap);
1595             }
1596 
1597             MOS_FreeMemory(pNewStateHeap);
1598         }
1599     }
1600 
1601     return eStatus;
1602 }
1603 
ExtendStateHeapSta(MHW_STATE_HEAP_TYPE StateHeapType,uint32_t dwSizeRequested)1604 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::ExtendStateHeapSta(
1605         MHW_STATE_HEAP_TYPE         StateHeapType,
1606         uint32_t                    dwSizeRequested)
1607 {
1608     PMOS_INTERFACE              pOsInterface = nullptr;
1609     PMHW_STATE_HEAP             pNewStateHeap = nullptr, pPrevStateHeap, *ppStateHeapPtr;
1610     MOS_ALLOC_GFXRES_PARAMS     AllocParams;
1611     uint32_t                    i, dwNumHeaps;
1612     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
1613     MEDIA_FEATURE_TABLE         *skuTable = nullptr;
1614 
1615     MHW_FUNCTION_ENTER;
1616     do
1617     {
1618         pOsInterface = m_pOsInterface;
1619         if (pOsInterface == nullptr)
1620         {
1621             MHW_ASSERTMESSAGE("pOsInterface is nullptr");
1622             eStatus = MOS_STATUS_NULL_POINTER;
1623             break;
1624         }
1625         if (pOsInterface->pfnGetSkuTable == nullptr)
1626         {
1627             MHW_ASSERTMESSAGE("pfnGetSkuTabl is nullptr");
1628             eStatus = MOS_STATUS_NULL_POINTER;
1629             break;
1630         }
1631 
1632         skuTable = pOsInterface->pfnGetSkuTable(pOsInterface);
1633         if (skuTable == nullptr)
1634         {
1635             MHW_ASSERTMESSAGE("skuTable is nullptr");
1636             eStatus = MOS_STATUS_NULL_POINTER;
1637             break;
1638         }
1639 
1640         pNewStateHeap = (PMHW_STATE_HEAP)MOS_AllocAndZeroMemory(sizeof(MHW_STATE_HEAP));
1641         if (pNewStateHeap == nullptr)
1642         {
1643             MHW_ASSERTMESSAGE("pNewStateHeap is nullptr");
1644             eStatus = MOS_STATUS_NULL_POINTER;
1645             break;
1646         }
1647 
1648         pNewStateHeap->dwSize = MOS_ALIGN_CEIL(dwSizeRequested, MHW_CACHELINE_SIZE);
1649         MOS_ZeroMemory(&AllocParams, sizeof(AllocParams));
1650         AllocParams.Type     = MOS_GFXRES_BUFFER;
1651         AllocParams.TileType = MOS_TILE_LINEAR;
1652         AllocParams.Format   = Format_Buffer;
1653         AllocParams.dwBytes  = pNewStateHeap->dwSize;
1654         AllocParams.pBufName = "StateHeap";
1655         AllocParams.ResUsageType = m_StateHeapSettings.m_heapUsageType;
1656 
1657         if (MEDIA_IS_SKU(skuTable, FtrLimitedLMemBar))
1658         {
1659             AllocParams.dwMemType = MOS_MEMPOOL_SYSTEMMEMORY;
1660         }
1661 
1662         eStatus = pOsInterface->pfnAllocateResource(
1663             pOsInterface,
1664             &AllocParams,
1665             &pNewStateHeap->resHeap);
1666         if (eStatus != MOS_STATUS_SUCCESS)
1667         {
1668             MHW_ASSERTMESSAGE("Allocate Resource fail");
1669             break;
1670         }
1671 
1672         eStatus = InitMemoryBlock(
1673             pNewStateHeap,
1674             &pNewStateHeap->pMemoryHead,
1675             pNewStateHeap->dwSize,
1676             false);
1677         if (eStatus != MOS_STATUS_SUCCESS)
1678         {
1679             MHW_ASSERTMESSAGE("Allocate memory block fail");
1680             break;
1681         }
1682 
1683         if (StateHeapType == MHW_ISH_TYPE)
1684         {
1685             ppStateHeapPtr = &m_pInstructionStateHeaps;
1686             dwNumHeaps     = m_dwNumIsh++;
1687         }
1688         else
1689         {
1690             ppStateHeapPtr = &m_pDynamicStateHeaps;
1691             dwNumHeaps     = m_dwNumDsh++;
1692         }
1693 
1694         if (ppStateHeapPtr == nullptr)
1695         {
1696             MHW_ASSERTMESSAGE("ppStateHeapPtr is nullptr");
1697             eStatus = MOS_STATUS_NULL_POINTER;
1698             break;
1699         }
1700         pPrevStateHeap = nullptr;
1701         for (i = 0; i < dwNumHeaps; i++)
1702         {
1703             pPrevStateHeap = *ppStateHeapPtr;
1704             ppStateHeapPtr = &(*ppStateHeapPtr)->pNext;
1705         }
1706 
1707         *ppStateHeapPtr      = pNewStateHeap;
1708         pNewStateHeap->pPrev = pPrevStateHeap;
1709     } while (false);
1710 
1711     if (eStatus != MOS_STATUS_SUCCESS)
1712     {
1713         if (pNewStateHeap)
1714         {
1715             MOS_FreeMemAndSetNull(pNewStateHeap->pMemoryHead);
1716             if (pOsInterface)
1717             {
1718                 pOsInterface->pfnFreeResource(pOsInterface, &pNewStateHeap->resHeap);
1719             }
1720             MOS_FreeMemory(pNewStateHeap);
1721         }
1722     }
1723 
1724     return eStatus;
1725 }
1726 
CalculateSpaceNeededDyn(MHW_STATE_HEAP_TYPE StateHeapType,PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)1727 uint32_t XMHW_STATE_HEAP_INTERFACE::CalculateSpaceNeededDyn(
1728     MHW_STATE_HEAP_TYPE                  StateHeapType,
1729     PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)
1730 {
1731 
1732     PMHW_STATE_HEAP                 pStateHeap;
1733     PMHW_BLOCK_MANAGER              pBlockManager = nullptr;
1734     uint32_t                        dwNeeded = 0;
1735     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1736 
1737     MHW_FUNCTION_ENTER;
1738 
1739     MHW_CHK_NULL_RETURN(pParams);
1740     MHW_CHK_NULL_RETURN(pParams->piSizes);
1741 
1742     if (pParams->iCount <= 0)
1743     {
1744         return dwNeeded;
1745     }
1746 
1747     if (StateHeapType == MHW_ISH_TYPE)
1748     {
1749         MHW_CHK_NULL_RETURN(m_pInstructionStateHeaps);
1750         pStateHeap = m_pInstructionStateHeaps;
1751         pBlockManager = m_pIshBlockManager;
1752     }
1753     else if (StateHeapType == MHW_DSH_TYPE)
1754     {
1755         MHW_CHK_NULL_RETURN(m_pDynamicStateHeaps);
1756         pStateHeap = m_pDynamicStateHeaps;
1757         pBlockManager = m_pDshBlockManager;
1758     }
1759     else
1760     {
1761         MHW_ASSERTMESSAGE("Unsupported state heap type.");
1762         eStatus = MOS_STATUS_INVALID_PARAMETER;
1763         return dwNeeded;
1764     }
1765 
1766     // Allocate simple block
1767     MHW_CHK_NULL_RETURN(pBlockManager);
1768     dwNeeded = pBlockManager->CalculateSpaceNeeded((uint32_t*)pParams->piSizes, pParams->iCount,
1769                                                    pParams->dwAlignment, pParams->bHeapAffinity, pParams->pHeapAffinity);
1770 
1771     return dwNeeded;
1772 
1773 }
1774 
CalculateSshAndBtSizesRequested(uint32_t dwBtEntriesRequested,uint32_t * pdwSshSize,uint32_t * pdwBtSize)1775 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::CalculateSshAndBtSizesRequested(
1776         uint32_t                    dwBtEntriesRequested,
1777         uint32_t                    *pdwSshSize,
1778         uint32_t                    *pdwBtSize)
1779 {
1780     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
1781 
1782     MHW_FUNCTION_ENTER;
1783 
1784     MHW_CHK_NULL_RETURN(pdwSshSize);
1785     MHW_CHK_NULL_RETURN(pdwBtSize);
1786 
1787     dwBtEntriesRequested =
1788         MOS_ALIGN_CEIL(dwBtEntriesRequested, m_wBtIdxAlignment);
1789     *pdwBtSize  = dwBtEntriesRequested * m_HwSizes.dwSizeBindingTableState;
1790     *pdwSshSize =
1791         (*pdwBtSize) + (dwBtEntriesRequested * m_dwMaxSurfaceStateSize);
1792 
1793     return eStatus;
1794 }
1795 
ReleaseStateHeapDyn(PMHW_STATE_HEAP pStateHeap)1796 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::ReleaseStateHeapDyn(
1797     PMHW_STATE_HEAP pStateHeap)
1798 {
1799     PMHW_STATE_HEAP pFirstHeap;
1800     MOS_STATUS      eStatus = MOS_STATUS_SUCCESS;
1801 
1802     MHW_FUNCTION_ENTER;
1803 
1804     MHW_CHK_NULL_RETURN(pStateHeap);
1805     MHW_CHK_NULL_RETURN(pStateHeap->pBlockManager);
1806 
1807     // Mark state heap for deletion (so size is not accounted for)
1808     pStateHeap->bDeleted = true;
1809 
1810     // Mark blocks for deletion, release heap when all blocks are released
1811     eStatus = pStateHeap->pBlockManager->UnregisterStateHeap(pStateHeap);
1812     if (eStatus != MOS_STATUS_SUCCESS)
1813     {
1814         // The only reason for this condition is in case some blocks are still in submitted state
1815         // The block manager will call this function from within when the last block is released
1816         // In the meantime, this heap will not contain any free blocks for allocation
1817         eStatus = MOS_STATUS_SUCCESS;
1818         return eStatus;
1819     }
1820 
1821     // Find first heap of the chain (so we can figure out if its DSH or ISH!)
1822     for (pFirstHeap = pStateHeap; pFirstHeap->pPrev != nullptr; pFirstHeap = pFirstHeap->pPrev) ;
1823 
1824     // Detach heap from chain
1825     if (pStateHeap->pPrev)
1826     {
1827         pStateHeap->pPrev->pNext = pStateHeap->pNext;
1828     }
1829 
1830     if (pStateHeap->pNext)
1831     {
1832         pStateHeap->pNext->pPrev = pStateHeap->pPrev;
1833     }
1834 
1835     // Update heaps
1836     if (pFirstHeap == m_pDynamicStateHeaps)
1837     {
1838         m_dwNumDsh--;
1839         if (pStateHeap == m_pDynamicStateHeaps)
1840         {
1841             m_pDynamicStateHeaps           = pStateHeap->pNext;
1842             m_pDshBlockManager->SetStateHeap(pStateHeap->pNext);
1843         }
1844     }
1845     else if (pFirstHeap == m_pInstructionStateHeaps)
1846     {
1847         m_dwNumIsh--;
1848         if (pStateHeap == m_pInstructionStateHeaps)
1849         {
1850             m_pInstructionStateHeaps       = pStateHeap->pNext;
1851             m_pIshBlockManager->SetStateHeap(pStateHeap->pNext);
1852         }
1853     }
1854 
1855     // Unlock heap
1856     if (pStateHeap->bKeepLocked)
1857     {
1858         pStateHeap->bKeepLocked = false;
1859         UnLockStateHeap(pStateHeap);
1860     }
1861 
1862     // Free OS resource
1863     MHW_CHK_NULL_RETURN(m_pOsInterface);
1864     m_pOsInterface->pfnFreeResource(m_pOsInterface, &pStateHeap->resHeap);
1865 
1866     // Free MHW State Heap structure
1867     MOS_FreeMemory(pStateHeap);
1868 
1869     return eStatus;
1870 }
1871 
AllocateDynamicBlockDyn(MHW_STATE_HEAP_TYPE StateHeapType,PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)1872 PMHW_STATE_HEAP_MEMORY_BLOCK  XMHW_STATE_HEAP_INTERFACE::AllocateDynamicBlockDyn(
1873         MHW_STATE_HEAP_TYPE                  StateHeapType,
1874         PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)
1875 {
1876     PMHW_STATE_HEAP                *ppStateHeap;
1877     PMHW_BLOCK_MANAGER              pBlockManager = nullptr;
1878     PMHW_STATE_HEAP_MEMORY_BLOCK    pMemoryBlock = nullptr;
1879     PMHW_STATE_HEAP_MEMORY_BLOCK    pAuxBlock;
1880     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
1881     uint32_t                        dwMinSize, dwIncrement, dwMaxSize;
1882 
1883     MHW_FUNCTION_ENTER;
1884     do
1885     {
1886         if (pParams == nullptr)
1887         {
1888             MHW_ASSERTMESSAGE("pParams is nullptr");
1889             eStatus = MOS_STATUS_NULL_POINTER;
1890             break;
1891         }
1892         if (pParams->piSizes == nullptr)
1893         {
1894             MHW_ASSERTMESSAGE("piSizes is nullptr");
1895             eStatus = MOS_STATUS_NULL_POINTER;
1896             break;
1897         }
1898         MHW_ASSERT(pParams->iCount > 0);
1899 
1900         if (StateHeapType == MHW_ISH_TYPE)
1901         {
1902             ppStateHeap   = &m_pInstructionStateHeaps;
1903             pBlockManager = m_pIshBlockManager;
1904             dwMinSize     = m_StateHeapSettings.dwIshSize;
1905             dwIncrement   = m_StateHeapSettings.dwIshIncrement;
1906             dwMaxSize     = m_StateHeapSettings.dwIshMaxSize;
1907         }
1908         else if (StateHeapType == MHW_DSH_TYPE)
1909         {
1910             ppStateHeap   = &m_pDynamicStateHeaps;
1911             pBlockManager = m_pDshBlockManager;
1912             dwMinSize     = m_StateHeapSettings.dwDshSize;
1913             dwIncrement   = m_StateHeapSettings.dwDshIncrement;
1914             dwMaxSize     = m_StateHeapSettings.dwDshMaxSize;
1915         }
1916         else
1917         {
1918             MHW_ASSERTMESSAGE("Unsupported state heap type.");
1919             eStatus = MOS_STATUS_INVALID_PARAMETER;
1920             break;
1921         }
1922 
1923         do
1924         {
1925             // Allocate simple block
1926             if (pParams->iCount == 1)
1927             {
1928                 if (pParams->dwScratchSpace == 0)
1929                 {
1930                     pMemoryBlock = pBlockManager->AllocateBlock((uint32_t)pParams->piSizes[0],
1931                         pParams->dwAlignment,
1932                         pParams->pHeapAffinity);
1933                 }
1934                 else
1935                 {
1936                     pMemoryBlock = pBlockManager->AllocateWithScratchSpace(
1937                         (uint32_t)pParams->piSizes[0],
1938                         pParams->dwAlignment,
1939                         pParams->dwScratchSpace);
1940                 }
1941 
1942                 if (pMemoryBlock)
1943                 {
1944                     pParams->pScratchSpace  = pMemoryBlock->pStateHeap->pScratchSpace;
1945                     pParams->dwScratchSpace = pMemoryBlock->pStateHeap->dwScratchSpace;
1946                 }
1947             }
1948             else
1949             {
1950                 pMemoryBlock = pBlockManager->AllocateMultiple((uint32_t *)pParams->piSizes,
1951                     pParams->iCount,
1952                     pParams->dwAlignment,
1953                     pParams->bHeapAffinity,
1954                     pParams->pHeapAffinity);
1955             }
1956 
1957             // Allocation failed
1958             if (!pMemoryBlock)
1959             {
1960                 uint32_t dwTotalSize = 0;
1961 
1962                 // Do not allow heap to grow automatically
1963                 // Note: Caller may try to clean up the heap, wait or implement a different heap expansion logic
1964                 if (!pParams->bGrow)
1965                 {
1966                     break;
1967                 }
1968 
1969                 // Calculate size of all heaps (do not account heaps already being removed)
1970                 for (PMHW_STATE_HEAP pStateHeap = *ppStateHeap; pStateHeap; pStateHeap = pStateHeap->pNext)
1971                 {
1972                     if (!pStateHeap->bDeleted)
1973                     {
1974                         dwTotalSize += pStateHeap->dwSize;
1975                     }
1976                 }
1977 
1978                 // Did not reach heap size limit - calculate increment to fit all allocations + scratch space (if GSH)
1979                 uint32_t dwExtendSize = 0;
1980                 if (dwTotalSize < dwMaxSize)
1981                 {
1982                     for (int32_t i = 0; i < pParams->iCount; i++)
1983                     {
1984                         dwExtendSize += MOS_ALIGN_CEIL(pParams->piSizes[i], pParams->dwAlignment);
1985                     }
1986                     dwExtendSize = MOS_ALIGN_CEIL(dwExtendSize, dwIncrement);
1987                     dwExtendSize = MOS_ALIGN_CEIL(dwExtendSize + pParams->dwScratchSpace, dwIncrement);
1988                     dwExtendSize = MOS_MAX(dwExtendSize, dwMinSize);
1989 
1990                     eStatus = ExtendStateHeap(StateHeapType, dwExtendSize);
1991                     if (eStatus != MOS_STATUS_SUCCESS)
1992                     {
1993                         MHW_ASSERTMESSAGE("ExtendStateHeap failed");
1994                     }
1995                 }
1996                 else
1997                 {
1998                     break;
1999                 }
2000             }
2001         } while (pMemoryBlock == nullptr);
2002 
2003         // Zero memory blocks
2004         pAuxBlock = pMemoryBlock;
2005         for (int32_t i = pParams->iCount; (pAuxBlock != nullptr) && (i > 0); i--, pAuxBlock = pAuxBlock->pNext)
2006         {
2007             // Set block static flag
2008             pAuxBlock->bStatic = pParams->bStatic;
2009 
2010             // Erase block contents
2011             if (pParams->bZeroAssignedMem)
2012             {
2013                 if (LockStateHeap(pAuxBlock->pStateHeap) != MOS_STATUS_SUCCESS)
2014                 {
2015                     if (eStatus != MOS_STATUS_SUCCESS && pBlockManager != nullptr)
2016                     {
2017                         // Something went wrong - release blocks if already allocated
2018                         for (; pMemoryBlock != nullptr; pMemoryBlock = pAuxBlock)
2019                         {
2020                             pAuxBlock = pMemoryBlock->pNext;         // Get next block (must be done before Mhw_BlockManager_Free)
2021                             pBlockManager->FreeBlock(pMemoryBlock);  // Release block back to "Free" queue
2022                         }
2023                     }
2024 
2025                     return pMemoryBlock;
2026                 }
2027                 MOS_ZeroMemory(pAuxBlock->pDataPtr - pAuxBlock->dwAlignment, pAuxBlock->dwBlockSize);
2028                 if (UnLockStateHeap(pAuxBlock->pStateHeap) != MOS_STATUS_SUCCESS)
2029                 {
2030                     if (eStatus != MOS_STATUS_SUCCESS && pBlockManager != nullptr)
2031                     {
2032                         // Something went wrong - release blocks if already allocated
2033                         for (; pMemoryBlock != nullptr; pMemoryBlock = pAuxBlock)
2034                         {
2035                             pAuxBlock = pMemoryBlock->pNext;         // Get next block (must be done before Mhw_BlockManager_Free)
2036                             pBlockManager->FreeBlock(pMemoryBlock);  // Release block back to "Free" queue
2037                         }
2038                     }
2039 
2040                     return pMemoryBlock;
2041                 }
2042             }
2043         }
2044     } while (false);
2045 
2046     // Failed - release memory blocks back to "Free" queue
2047     if (eStatus != MOS_STATUS_SUCCESS && pBlockManager != nullptr)
2048     {
2049         // Something went wrong - release blocks if already allocated
2050         for (; pMemoryBlock != nullptr; pMemoryBlock = pAuxBlock)
2051         {
2052             pAuxBlock = pMemoryBlock->pNext;            // Get next block (must be done before Mhw_BlockManager_Free)
2053             pBlockManager->FreeBlock(pMemoryBlock);  // Release block back to "Free" queue
2054         }
2055     }
2056 
2057     return pMemoryBlock;
2058 }
2059 
SubmitDynamicBlockDyn(MHW_STATE_HEAP_TYPE StateHeapType,PMHW_STATE_HEAP_MEMORY_BLOCK pBlock,const FrameTrackerTokenFlat * trakcerToken)2060 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::SubmitDynamicBlockDyn(
2061         MHW_STATE_HEAP_TYPE                  StateHeapType,
2062         PMHW_STATE_HEAP_MEMORY_BLOCK         pBlock,
2063         const FrameTrackerTokenFlat          *trakcerToken)
2064 {
2065     PMHW_BLOCK_MANAGER  pBlockManager = nullptr;
2066     MOS_STATUS          eStatus = MOS_STATUS_SUCCESS;
2067 
2068     MHW_FUNCTION_ENTER;
2069 
2070     MHW_CHK_NULL_RETURN(pBlock);
2071 
2072     if (StateHeapType == MHW_ISH_TYPE)
2073     {
2074         pBlockManager = m_pIshBlockManager;
2075     }
2076     else if (StateHeapType == MHW_DSH_TYPE)
2077     {
2078         pBlockManager = m_pDshBlockManager;
2079     }
2080     else
2081     {
2082         MHW_ASSERTMESSAGE("Unsupported state heap type.");
2083         eStatus = MOS_STATUS_INVALID_PARAMETER;
2084         return eStatus;
2085     }
2086 
2087     // Submit block
2088     MHW_CHK_NULL_RETURN(pBlockManager);
2089     MHW_CHK_STATUS_RETURN(pBlockManager->SubmitBlock(pBlock, trakcerToken));
2090 
2091     return eStatus;
2092 }
2093 
FreeDynamicBlockDyn(MHW_STATE_HEAP_TYPE StateHeapType,PMHW_STATE_HEAP_MEMORY_BLOCK pBlock)2094 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::FreeDynamicBlockDyn(
2095         MHW_STATE_HEAP_TYPE                  StateHeapType,
2096         PMHW_STATE_HEAP_MEMORY_BLOCK         pBlock)
2097 {
2098     PMHW_BLOCK_MANAGER  pBlockManager = nullptr;
2099     MOS_STATUS          eStatus = MOS_STATUS_SUCCESS;
2100 
2101     MHW_FUNCTION_ENTER;
2102 
2103     MHW_CHK_NULL_RETURN(pBlock);
2104 
2105     if (StateHeapType == MHW_ISH_TYPE)
2106     {
2107         pBlockManager = m_pIshBlockManager;
2108     }
2109     else if (StateHeapType == MHW_DSH_TYPE)
2110     {
2111         pBlockManager = m_pDshBlockManager;
2112     }
2113     else
2114     {
2115         MHW_ASSERTMESSAGE("Unsupported state heap type.");
2116         eStatus = MOS_STATUS_INVALID_PARAMETER;
2117         return eStatus;
2118     }
2119 
2120     // Free block
2121     MHW_CHK_STATUS_RETURN(pBlockManager->FreeBlock(pBlock));
2122 
2123     return eStatus;
2124 }
2125 
RefreshDynamicHeapDyn(MHW_STATE_HEAP_TYPE StateHeapType)2126 MOS_STATUS XMHW_STATE_HEAP_INTERFACE::RefreshDynamicHeapDyn (
2127     MHW_STATE_HEAP_TYPE         StateHeapType)
2128 {
2129     PMHW_BLOCK_MANAGER  pBlockManager = nullptr;
2130     MOS_STATUS          eStatus = MOS_STATUS_SUCCESS;
2131 
2132     MHW_FUNCTION_ENTER;
2133 
2134     if (StateHeapType == MHW_ISH_TYPE)
2135     {
2136         pBlockManager = m_pIshBlockManager;
2137     }
2138     else if (StateHeapType == MHW_DSH_TYPE)
2139     {
2140         pBlockManager = m_pDshBlockManager;
2141     }
2142     else
2143     {
2144         MHW_ASSERTMESSAGE("Unsupported state heap type.");
2145         eStatus = MOS_STATUS_INVALID_PARAMETER;
2146         return eStatus;
2147     }
2148 
2149     // Free block
2150     MHW_CHK_NULL_RETURN(pBlockManager)
2151     MHW_CHK_STATUS_RETURN(pBlockManager->Refresh());
2152 
2153     return eStatus;
2154 }
2155 
2156