xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/renderhal/renderhal_dsh.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2015-2020, 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      renderhal_dsh.cpp
24 //! \brief         This module implements render engine state heap management functions based     on dynamic state heap (DSH) infrastructure, rather than static state heap.     It allows dynamic allocation and expansion of general state heap (media states)     and instraction state heaps (media kernels) based on demand. It also allows     dynamic configuration of media states based on specific workload requirements,     as well as dynamic allocation of kernel scratch space (spill area).
25 //!
26 #include "renderhal_legacy.h"
27 #include "renderhal_platform_interface.h"
28 
29 // Defined in renderhal.c
30 extern const RENDERHAL_SURFACE_STATE_ENTRY g_cInitSurfaceStateEntry;
31 
32 MOS_STATUS RenderHal_AllocateDebugSurface(
33     PRENDERHAL_INTERFACE     pRenderHal);
34 
35 //!
36 //! \brief    Extend the media state pool
37 //! \details  Extends the media state pool by adding 16 media state objects
38 //! \param    PRENDERHAL_STATE_HEAP pStateHeap
39 //!           [in] Pointer to the state heap
40 //! \return   MOS_STATUS
41 //!           SUCCESS    if media state pool was successfully extended
42 //!           NO_SPACE   if the pool of objects cannot be extended
43 //!
RenderHal_DSH_ExtendMediaStatePool(PRENDERHAL_STATE_HEAP pStateHeap)44 MOS_STATUS RenderHal_DSH_ExtendMediaStatePool(
45     PRENDERHAL_STATE_HEAP pStateHeap)
46 {
47     int32_t iSize;
48     uint8_t *pPtr;
49     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
50 
51     //---------------------------------------
52     MHW_RENDERHAL_CHK_NULL_RETURN(pStateHeap);
53     MHW_RENDERHAL_CHK_NULL_RETURN(pStateHeap->pMediaStatesMemPool);
54     //---------------------------------------
55 
56     int32_t iCount = RENDERHAL_DSH_DYN_STATE_INC;
57 
58     // Extend pool and get pointer to first element of the new pool object
59     PRENDERHAL_MEDIA_STATE_LEGACY      pFirst, pLast, pPrev;
60     PRENDERHAL_MEDIA_STATE_LIST pList = &pStateHeap->FreeStates;
61 
62     uint32_t ID = pStateHeap->pMediaStatesMemPool->m_dwObjCount;
63     pLast = pFirst = (PRENDERHAL_MEDIA_STATE_LEGACY)(pStateHeap->pMediaStatesMemPool->Allocate(iCount));
64     if (!pLast)
65     {
66         eStatus = MOS_STATUS_NO_SPACE;
67         goto finish;
68     }
69 
70     // Increment size of the list
71     pList->iCount += iCount;
72 
73     // Initialize new doubled linked list and internal structure
74     iSize = pStateHeap->pMediaStatesMemPool->m_dwObjSize; // enough for media state and dynamic state objects
75     pPtr  = (uint8_t*) pFirst;
76     for (pPrev = nullptr; iCount > 0; iCount--, pPtr += iSize, pPrev = pLast)
77     {
78         // Create doubled linked list
79         pLast = (PRENDERHAL_MEDIA_STATE_LEGACY) pPtr;
80         pLast->Reserved = ID++;
81         pLast->pPrev    = pPrev;
82         if (pPrev) pPrev->pNext = pLast;
83 
84         // Point to dynamic states (co-located)
85         pLast->pDynamicState = (PRENDERHAL_DYNAMIC_STATE) (pLast + 1);
86     }
87     pLast->pNext = nullptr;
88 
89     // Attach to end of existing pool
90     pFirst->pPrev = pList->pTail;
91     pList->pTail  = pLast;
92     if (pFirst->pPrev)
93         pFirst->pPrev->pNext = pFirst;
94     else
95         pList->pHead = pFirst;
96 
97 finish:
98     return eStatus;
99 }
100 
101 //!
102 //! \brief    Get a media state from the pool
103 //! \details  Returns a pointer to a media state from the pool
104 //!           If pool is empty, the pool is extended (adds 16 media states)
105 //! \param    PRENDERHAL_STATE_HEAP pStateHeap
106 //!           [in] Pointer to the state heap
107 //! \return   PRENDERHAL_MEDIA_STATE pointer to a media state
108 //!
RenderHal_DSH_GetMediaStateFromPool(PRENDERHAL_STATE_HEAP pStateHeap)109 PRENDERHAL_MEDIA_STATE RenderHal_DSH_GetMediaStateFromPool(
110     PRENDERHAL_STATE_HEAP pStateHeap)
111 {
112     MOS_STATUS             eStatus;
113     PRENDERHAL_MEDIA_STATE pMediaState = nullptr;
114 
115     //---------------------------------------
116     if (pStateHeap == nullptr)
117     {
118         MHW_RENDERHAL_ASSERTMESSAGE("Null pointer detected!");
119         return nullptr;
120     }
121     //---------------------------------------
122 
123     PRENDERHAL_MEDIA_STATE_LIST pList = &pStateHeap->FreeStates;
124 
125     // If pool is empty, extend pool of free media states
126     if (pList->iCount == 0)
127     {
128         MHW_RENDERHAL_CHK_STATUS(RenderHal_DSH_ExtendMediaStatePool(pStateHeap));
129     }
130 
131     // Get Element from the head of the list
132     pMediaState = pList->pHead;
133 
134     // Detach element from the list
135     if (pMediaState)
136     {
137         pList->iCount--;
138         pList->pHead = pMediaState->pNext;
139         if (pMediaState->pNext)
140         {
141             pMediaState->pNext->pPrev = nullptr;
142         }
143         else
144         {   // List is now empty - last element was removed
145             pList->pTail = nullptr;
146             MHW_ASSERT(pList->iCount == 0);
147         }
148 
149         pMediaState->pNext = pMediaState->pPrev = nullptr;
150     }
151 
152 finish:
153     return pMediaState;
154 }
155 
156 //!
157 //! \brief    Returns a media state to the pool
158 //! \details  Returns the media state to the pool list
159 //! \param    PRENDERHAL_STATE_HEAP pStateHeap
160 //!           [in] Pointer to the state heap
161 //! \param    PRENDERHAL_MEDIA_STATE  pMediaState
162 //!           [in] Pointer to the media state
163 //! \return   NONE
164 //!
RenderHal_DSH_ReturnMediaStateToPool(PRENDERHAL_STATE_HEAP pStateHeap,PRENDERHAL_MEDIA_STATE pMediaState)165 void RenderHal_DSH_ReturnMediaStateToPool(
166     PRENDERHAL_STATE_HEAP   pStateHeap,
167     PRENDERHAL_MEDIA_STATE  pMediaState)
168 {
169     //---------------------------------------
170     MHW_RENDERHAL_CHK_NULL_NO_STATUS_RETURN(pStateHeap);
171     MHW_RENDERHAL_CHK_NULL_NO_STATUS_RETURN(pMediaState);
172     //---------------------------------------
173 
174     PRENDERHAL_MEDIA_STATE_LIST pList = &pStateHeap->FreeStates;
175 
176     // Attach element to the head of the list
177     pMediaState->pPrev = pList->pTail;
178     pList->pTail = pMediaState;
179     if (pMediaState->pPrev)
180     {
181         pMediaState->pPrev->pNext = pMediaState;
182     }
183     else
184     {   // List was empty - insert first element
185         MHW_ASSERT(pList->iCount == 0);
186         pList->pHead = pMediaState;
187     }
188     pList->iCount++;
189 
190     return;
191 }
192 
193 //!
194 //! \brief    Extend the kernel allocation pool
195 //! \details  Extends the kernel allocation pool by adding 16 kernel allocations
196 //! \param    PRENDERHAL_STATE_HEAP pStateHeap
197 //!           [in] Pointer to the state heap
198 //! \return   MOS_STATUS
199 //!           SUCCESS    if kernel allocation pool was successfully extended
200 //!           NO_SPACE   if the pool of objects cannot be extended
201 //!
RenderHal_DSH_ExtendKernelAllocPool(PRENDERHAL_STATE_HEAP pStateHeap)202 MOS_STATUS RenderHal_DSH_ExtendKernelAllocPool(
203     PRENDERHAL_STATE_HEAP pStateHeap)
204 {
205     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
206 
207     //---------------------------------------
208     MHW_RENDERHAL_CHK_NULL_RETURN(pStateHeap);
209     MHW_RENDERHAL_CHK_NULL_RETURN(pStateHeap->pKernelAllocMemPool);
210     //---------------------------------------
211 
212     int32_t iCount = RENDERHAL_DSH_KRN_ALLOC_INC;
213 
214     // Extend pool and get pointer to first element of the new pool object
215     PRENDERHAL_KRN_ALLOCATION   pFirst, pLast;
216     PRENDERHAL_KRN_ALLOC_LIST   pList = &pStateHeap->KernelAllocationPool;
217 
218     uint32_t ObjID = pStateHeap->pKernelAllocMemPool->m_dwObjCount;
219     pLast = pFirst = (PRENDERHAL_KRN_ALLOCATION)(pStateHeap->pKernelAllocMemPool->Allocate(iCount));
220 
221     if (!pLast)
222     {
223         eStatus = MOS_STATUS_NO_SPACE;
224         goto finish;
225     }
226 
227     // Increment size of the list
228     pList->iCount += iCount;
229 
230     // Initialize new doubled linked list
231     for ( ; iCount > 0; iCount--, pLast++)
232     {
233         pLast->Reserved = ObjID++;
234         pLast->pPrev = pLast - 1;
235         pLast->pNext = pLast + 1;
236         pLast->pList = pList;
237         pLast->szKernelName = nullptr;
238     }
239     pLast--;
240     pLast->pNext = nullptr;
241 
242     // Attach to end of existing pool
243     pFirst->pPrev = pList->pTail;
244     pList->pTail  = pLast;
245     if (pFirst->pPrev)
246     {
247         pFirst->pPrev->pNext = pFirst;
248     }
249     else
250     {
251         pList->pHead = pFirst;
252     }
253 
254 finish:
255     return eStatus;
256 }
257 
258 //!
259 //! \brief    Detach kernel allocation
260 //! \details  Removes the kernel allocation from the current list
261 //! \param    PRENDERHAL_KRN_ALLOCATION pKernel
262 //!           [in] Pointer to the kernel allocation
263 //! \return   NONE
264 //!
RenderHal_DSH_KernelDetach(PRENDERHAL_KRN_ALLOCATION pKernel)265 void RenderHal_DSH_KernelDetach(PRENDERHAL_KRN_ALLOCATION pKernel)
266 {
267     PRENDERHAL_KRN_ALLOC_LIST pList;
268 
269     if (!pKernel || !pKernel->pList) return;
270     pList = pKernel->pList;
271 
272     // Kernel is last in its list
273     if (pKernel->pNext == nullptr)
274     {
275         pList->pTail = pKernel->pPrev;
276     }
277     else
278     {
279         pKernel->pNext->pPrev = pKernel->pPrev;
280     }
281 
282     // Kernel is first in its list
283     if (pKernel->pPrev == nullptr)
284     {
285         pList->pHead = pKernel->pNext;
286     }
287     else
288     {
289         pKernel->pPrev->pNext = pKernel->pNext;
290     }
291 
292     pKernel->pNext = nullptr;
293     pKernel->pPrev = nullptr;
294     pKernel->pList = nullptr;
295     pList->iCount--;
296 }
297 
298 //!
299 //! \brief    Removes kernel allocation from current list and attaches to designated list
300 //! \details  Removes the kernel allocation from the current list (pKernel->pList)
301 //|           and attaches kernel to pList (passed in as a parameter)
302 //! \param    PRENDERHAL_KRN_ALLOC_LIST pList
303 //!           [in] Pointer to the kernel allocation list to attach to
304 //! \param    PRENDERHAL_KRN_ALLOCATION pKernel
305 //!           [in] Pointer to the kernel allocation
306 //! \param    bool bHead
307 //!           [in] Indicates whether to attach to head of list or tail
308 //! \return   NONE
309 //!
RenderHal_DSH_KernelAttach(PRENDERHAL_KRN_ALLOC_LIST pList,PRENDERHAL_KRN_ALLOCATION pKernel,bool bHead)310 void RenderHal_DSH_KernelAttach(PRENDERHAL_KRN_ALLOC_LIST pList, PRENDERHAL_KRN_ALLOCATION pKernel, bool bHead)
311 {
312     if (!pList || !pKernel) return;
313 
314     // Detach from current list
315     if (pKernel->pList)
316     {
317         RenderHal_DSH_KernelDetach(pKernel);
318     }
319 
320     if (bHead)
321     {
322         pKernel->pPrev = nullptr;
323         pKernel->pNext = pList->pHead;
324         pList->pHead   = pKernel;
325         if (pKernel->pNext)
326         {
327             pKernel->pNext->pPrev = pKernel;
328         }
329         else
330         {
331             pList->pTail = pKernel;
332         }
333     }
334     else
335     {
336         pKernel->pPrev = pList->pTail;
337         pKernel->pNext = nullptr;
338         pList->pTail   = pKernel;
339         if (pKernel->pPrev)
340         {
341             pKernel->pPrev->pNext = pKernel;
342         }
343         else
344         {
345             pList->pHead = pKernel;
346         }
347     }
348 
349     pKernel->pList = pList;
350     pList->iCount++;
351 }
352 
353 //!
354 //! \brief    Get a kernel allocation from the pool
355 //! \details  Returns a pointer to the kernel allocation from the pool
356 //!           If pool is empty, the pool is extended (adds 16 kernel allocations)
357 //! \param    PRENDERHAL_STATE_HEAP pStateHeap
358 //!           [in] Pointer to the state heap
359 //! \return   PRENDERHAL_KRN_ALLOCATION pointer to a kernel allocation
360 //!
RenderHal_DSH_GetKernelAllocationFromPool(PRENDERHAL_STATE_HEAP pStateHeap)361 PRENDERHAL_KRN_ALLOCATION RenderHal_DSH_GetKernelAllocationFromPool(PRENDERHAL_STATE_HEAP pStateHeap)
362 {
363     MOS_STATUS                eStatus = MOS_STATUS_SUCCESS;
364     PRENDERHAL_KRN_ALLOCATION pKernelAllocation = nullptr;
365 
366     MHW_RENDERHAL_CHK_NULL(pStateHeap);
367 
368     if (pStateHeap->KernelAllocationPool.iCount == 0)
369     {
370         MHW_RENDERHAL_CHK_STATUS(RenderHal_DSH_ExtendKernelAllocPool(pStateHeap));
371     }
372 
373     pKernelAllocation = pStateHeap->KernelAllocationPool.pHead;
374     RenderHal_DSH_KernelDetach(pKernelAllocation);
375 
376 finish:
377     return pKernelAllocation;
378 }
379 
380 //!
381 //! \brief    Touch dynamic kernel
382 //! \details  Updates sync tag on kernel allocation
383 //!           Moves kernel to the tail of the pStateHeap->KernelsSubmitted list
384 //!           Submits the dynamic memory block
385 //!           Updates kernel usage
386 //! \param    PRENDERHAL_INTERFACE      pRenderHal
387 //!           [in] Pointer to the renderhal interface
388 //! \param    PRENDERHAL_KRN_ALLOCATION pKernelAllocation
389 //!           [in] Pointer to the kernel allocation
390 //! \return   NONE
391 //!
RenderHal_DSH_TouchDynamicKernel(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_KRN_ALLOCATION pKernelAllocation)392 void RenderHal_DSH_TouchDynamicKernel(
393     PRENDERHAL_INTERFACE      pRenderHal,
394     PRENDERHAL_KRN_ALLOCATION pKernelAllocation)
395 {
396     PRENDERHAL_STATE_HEAP      pStateHeap;
397     PXMHW_STATE_HEAP_INTERFACE pMhwStateHeap;
398 
399     if (pRenderHal == nullptr || pRenderHal->pStateHeap == nullptr || pKernelAllocation == nullptr)
400     {
401         return;
402     }
403 
404     pStateHeap    = pRenderHal->pStateHeap;
405     pMhwStateHeap = pRenderHal->pMhwStateHeap;
406 
407     // Set sync tag, for deallocation control
408     pKernelAllocation->dwFlags = RENDERHAL_KERNEL_ALLOCATION_LOCKED;
409     FrameTrackerTokenFlat_SetProducer(&pKernelAllocation->trackerToken, &pRenderHal->trackerProducer);
410     FrameTrackerTokenFlat_Merge(&pKernelAllocation->trackerToken,
411                                 pRenderHal->currentTrackerIndex,
412                                 pRenderHal->trackerProducer.GetNextTracker(pRenderHal->currentTrackerIndex));
413 
414     // Move kernel to the tail of the submitted list (list is sorted with the most recently used at the end)
415     RenderHal_DSH_KernelAttach(&pStateHeap->KernelsSubmitted, pKernelAllocation, false);
416 
417     // Update memory block
418     pMhwStateHeap->SubmitDynamicBlockDyn(MHW_ISH_TYPE, pKernelAllocation->pMemoryBlock, &pKernelAllocation->trackerToken);
419 
420     // Update kernel usage - this is where kernels age if they are not constantly used, and may be removed
421     pKernelAllocation->dwCount++;
422 }
423 
424 //!
425 //! \brief    Searches the hash table for the kernel
426 //! \details  Searches the hash table for the kernel using the UniqID and CacheID to determine if the
427 //!           kernel is already allocated in the ISH
428 //! \param    PRENDERHAL_INTERFACE      pRenderHal
429 //!           [in] Pointer to the renderhal interface
430 //! \param    int32_t iUniqID
431 //!           [in] unique kernel identifier
432 //! \param    int32_t iCacheID
433 //!           [in] cache identifier
434 //! \return   PRENDERHAL_KRN_ALLOCATION
435 //!           pKernelAllocation    if kernel is found in hash table
436 //!           nullptr              otherwise
437 //!
RenderHal_DSH_SearchDynamicKernel(PRENDERHAL_INTERFACE pRenderHal,int32_t iUniqID,int32_t iCacheID)438 PRENDERHAL_KRN_ALLOCATION RenderHal_DSH_SearchDynamicKernel(PRENDERHAL_INTERFACE pRenderHal, int32_t iUniqID, int32_t iCacheID)
439 {
440     PRENDERHAL_STATE_HEAP_LEGACY    pStateHeap;
441     PRENDERHAL_KRN_ALLOCATION       pKernelAllocation = nullptr;
442 
443     pStateHeap = (pRenderHal) ? ((PRENDERHAL_STATE_HEAP_LEGACY)pRenderHal->pStateHeap) : nullptr;
444     if (pStateHeap)
445     {
446         uint16_t wSearchIndex = 0;
447         pKernelAllocation = (PRENDERHAL_KRN_ALLOCATION) pStateHeap->kernelHashTable.Search(iUniqID, iCacheID, wSearchIndex);
448     }
449 
450     return pKernelAllocation;
451 }
452 
453 //!
454 //! \brief    Allocates a kernel allocation
455 //! \details  Searches the hash table for the kernel and if not found
456 //!           gets a kernel allocation from the pool then
457 //!           registers it in the hash table and attaches it to the allocated list
458 //!           returns a pointer to the kernel allocation
459 //! \param    PRENDERHAL_INTERFACE      pRenderHal
460 //!           [in] Pointer to the renderhal interface
461 //! \param    int32_t iUniqID
462 //!           [in] unique kernel identifier
463 //! \param    int32_t iCacheID
464 //!           [in] cache identifier
465 //! \return   PRENDERHAL_KRN_ALLOCATION
466 //!
RenderHal_DSH_AllocateDynamicKernel(PRENDERHAL_INTERFACE pRenderHal,int32_t iUniqID,int32_t iCacheID)467 PRENDERHAL_KRN_ALLOCATION RenderHal_DSH_AllocateDynamicKernel(PRENDERHAL_INTERFACE pRenderHal, int32_t iUniqID, int32_t iCacheID)
468 {
469     PRENDERHAL_STATE_HEAP_LEGACY    pStateHeap;
470     PRENDERHAL_KRN_ALLOCATION       pKernelAllocation = nullptr;
471     uint16_t                        wSearchIndex = 0;
472     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
473 
474     pStateHeap = (pRenderHal) ? ((PRENDERHAL_STATE_HEAP_LEGACY)pRenderHal->pStateHeap) : nullptr;
475     if (pStateHeap == nullptr)
476     {
477         goto finish;
478     }
479 
480     pKernelAllocation = (PRENDERHAL_KRN_ALLOCATION)pStateHeap->kernelHashTable.Search(iUniqID, iCacheID, wSearchIndex);
481 
482     if (!pKernelAllocation)
483     {
484         // Get new kernel allocation entry
485         pKernelAllocation = RenderHal_DSH_GetKernelAllocationFromPool(pStateHeap);
486         MHW_RENDERHAL_CHK_NULL(pKernelAllocation);
487 
488         // Clear kernel allocation entry, setup kernel uniq id
489         uint32_t Reserved = pKernelAllocation->Reserved; // Preserve before
490         MOS_ZeroMemory(pKernelAllocation, sizeof(RENDERHAL_KRN_ALLOCATION));
491         pKernelAllocation->dwFlags  = RENDERHAL_KERNEL_ALLOCATION_FREE;    // Krn allocation does not point to a kernel
492         pKernelAllocation->Reserved = Reserved;
493         pKernelAllocation->iKUID    = iUniqID;
494         pKernelAllocation->iKCID    = iCacheID;
495 
496         // Register kernel in hash table to speed up future search
497         pStateHeap->kernelHashTable.Register(iUniqID, iCacheID, pKernelAllocation);
498 
499         // Insert kernel in allocated list
500         RenderHal_DSH_KernelAttach(&pStateHeap->KernelsAllocated, pKernelAllocation, false);
501     }
502 
503 finish:
504     return pKernelAllocation;
505 }
506 
507 //!
508 //! \brief    Unregister a kernel
509 //! \details  Frees the memory block of the kernel in the ISH
510 //!           removes the kernel from the hash table and
511 //!           attaches the kernel to the allocation pool
512 //! \param    PRENDERHAL_INTERFACE      pRenderHal
513 //!           [in] Pointer to the renderhal interface
514 //! \param    PRENDERHAL_KRN_ALLOCATION pKernelAllocation
515 //!           [in] Pointer to the kernel allocation
516 //! \return   MOS_STATUS
517 //!
RenderHal_DSH_UnregisterKernel(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_KRN_ALLOCATION pKernelAllocation)518 MOS_STATUS RenderHal_DSH_UnregisterKernel(PRENDERHAL_INTERFACE pRenderHal, PRENDERHAL_KRN_ALLOCATION pKernelAllocation)
519 {
520     PRENDERHAL_STATE_HEAP_LEGACY    pStateHeap;
521     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
522 
523     pStateHeap = (pRenderHal) ? ((PRENDERHAL_STATE_HEAP_LEGACY)pRenderHal->pStateHeap) : nullptr;
524     if (pStateHeap == nullptr)
525     {
526         goto finish;
527     }
528 
529     // Free kernel before releasing
530     if (pKernelAllocation->pMemoryBlock)
531     {
532         // Get new kernel allocation entry
533         pRenderHal->pMhwStateHeap->FreeDynamicBlockDyn(MHW_ISH_TYPE, pKernelAllocation->pMemoryBlock);
534         pKernelAllocation->pMemoryBlock = nullptr;
535     }
536 
537     pStateHeap->kernelHashTable.Unregister(pKernelAllocation->iKUID, pKernelAllocation->iKCID);
538 
539     // Return the kernel allocation to pool
540     RenderHal_DSH_KernelAttach(&pStateHeap->KernelAllocationPool, pKernelAllocation, false);
541 
542 finish:
543     return eStatus;
544 }
545 
546 //!
547 //! \brief    Allocate GSH, SSH, ISH control structures and heaps
548 //! \details  Allocates State Heap control structure (system memory)
549 //!           and associated State Buffer in gfx/sys memory (GSH,ISH,SSH)
550 //!           initializes the State Heap control structure and state buffers
551 //!
552 //! \param    PRENDERHAL_INTERFACE pRenderHal
553 //!           [in] Pointer to Rendering Interface Structure
554 //! \param    PRENDERHAL_STATE_HEAP_SETTINGS pSettings
555 //!           [in] Pointer to state heap settings (GSH/SSH/ISH)
556 //! \return   MOS_STATUS
557 //!           SUCCESS if state heaps were successfully allocated and initialized
558 //!           OTHER   if bad parameters or allocation failed
559 //!
RenderHal_DSH_AllocateStateHeaps(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_STATE_HEAP_SETTINGS pSettings)560 MOS_STATUS RenderHal_DSH_AllocateStateHeaps(
561     PRENDERHAL_INTERFACE           pRenderHal,
562     PRENDERHAL_STATE_HEAP_SETTINGS pSettings)
563 {
564     MHW_STATE_HEAP_SETTINGS      MhwStateHeapSettings;
565     PXMHW_STATE_HEAP_INTERFACE   pMhwStateHeap;
566     MhwRenderInterface           *pMhwRender;
567     PMHW_RENDER_STATE_SIZES      pHwSizes;
568     PRENDERHAL_STATE_HEAP        pStateHeap = nullptr;
569     MOS_STATUS                   eStatus;
570     uint32_t                     iSize = 0;
571     PRENDERHAL_INTERFACE_LEGACY  pRenderHalLegacy = (PRENDERHAL_INTERFACE_LEGACY)pRenderHal;
572     // Initialize locals
573     eStatus          = MOS_STATUS_UNKNOWN;
574 
575     //---------------------------------------
576     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy);
577     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pOsInterface);
578     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pMhwRenderInterface);
579     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pStateHeap);
580     MHW_RENDERHAL_CHK_NULL(pSettings);
581 
582     // verify GSH parameters and alignments
583     MHW_RENDERHAL_ASSERT((pSettings->iSyncSize        % RENDERHAL_SYNC_BLOCK_ALIGN)   == 0);
584     MHW_RENDERHAL_ASSERT((pSettings->iCurbeSize       % RENDERHAL_URB_BLOCK_ALIGN)    == 0);
585     MHW_RENDERHAL_ASSERT((pSettings->iKernelHeapSize  % RENDERHAL_KERNEL_BLOCK_ALIGN) == 0);
586     MHW_RENDERHAL_ASSERT((pSettings->iKernelBlockSize % RENDERHAL_KERNEL_BLOCK_ALIGN) == 0);
587     // verify SSH parameters
588     MHW_RENDERHAL_ASSERT(pSettings->iBindingTables >= RENDERHAL_SSH_BINDING_TABLES_MIN);
589     MHW_RENDERHAL_ASSERT(pSettings->iBindingTables <= RENDERHAL_SSH_BINDING_TABLES_MAX);
590     MHW_RENDERHAL_ASSERT(pSettings->iSurfaceStates >= RENDERHAL_SSH_SURFACE_STATES_MIN);
591     MHW_RENDERHAL_ASSERT(pSettings->iSurfaceStates <= RENDERHAL_SSH_SURFACE_STATES_MAX);
592     MHW_RENDERHAL_ASSERT(pSettings->iSurfacesPerBT >= RENDERHAL_SSH_SURFACES_PER_BT_MIN);
593     MHW_RENDERHAL_ASSERT(pSettings->iSurfacesPerBT <= RENDERHAL_SSH_SURFACES_PER_BT_MAX);
594     //---------------------------------------
595 
596     pMhwRender  = pRenderHalLegacy->pMhwRenderInterface;
597     pStateHeap  = pRenderHalLegacy->pStateHeap;
598     pHwSizes    = pRenderHalLegacy->pHwSizes;
599 
600     // Reset media state lists
601     MOS_ZeroMemory(&pStateHeap->FreeStates           , sizeof(RENDERHAL_MEDIA_STATE_LIST));
602     MOS_ZeroMemory(&pStateHeap->ReservedStates       , sizeof(RENDERHAL_MEDIA_STATE_LIST));
603     MOS_ZeroMemory(&pStateHeap->SubmittedStates      , sizeof(RENDERHAL_MEDIA_STATE_LIST));
604     MOS_ZeroMemory(&pStateHeap->KernelsAllocated     , sizeof(RENDERHAL_KRN_ALLOC_LIST));
605     MOS_ZeroMemory(&pStateHeap->KernelsSubmitted     , sizeof(RENDERHAL_KRN_ALLOC_LIST));
606     MOS_ZeroMemory(&pStateHeap->KernelAllocationPool , sizeof(RENDERHAL_KRN_ALLOC_LIST));
607 
608     // Create pool of media state objects
609     iSize = sizeof(RENDERHAL_MEDIA_STATE_LEGACY) + sizeof(RENDERHAL_DYNAMIC_STATE) + 16; // Media state object + Dynamic states object (co-located)
610 
611     pStateHeap->pMediaStatesMemPool = MOS_New(MHW_MEMORY_POOL, iSize, (uint32_t)sizeof(void *));
612     MHW_RENDERHAL_CHK_NULL(pStateHeap->pMediaStatesMemPool);
613 
614     MHW_RENDERHAL_CHK_STATUS(RenderHal_DSH_ExtendMediaStatePool(pStateHeap));
615 
616     //-------------------------------------------------------------------------
617     // Calculate offsets/sizes in GSH
618     //-------------------------------------------------------------------------
619     // Synchronization, debugging data
620     pStateHeap->dwOffsetSync = 0;
621     pStateHeap->dwSizeSync   = pSettings->iSyncSize;
622 
623     // Synchronization
624     pStateHeap->dwNextTag    = 0;
625     pStateHeap->dwSyncTag    = 0;
626     pStateHeap->dwFrameId    = 0;
627 
628     //----------------------------------
629     // Instruction State Heap
630     //----------------------------------
631     // Kernel Spill Area - allocated on demand
632     pStateHeap->dwScratchSpaceSize = 0;
633 
634     //----------------------------------
635     // Surface State Heap
636     //----------------------------------
637     // Reset initial SSH allocations
638     pStateHeap->iCurSshBufferIndex    = 0;
639     pStateHeap->iCurrentBindingTable  = 0;
640     pStateHeap->iCurrentSurfaceState  = 0;
641 
642     // Calculate size of each Binding Table
643     pStateHeap->iBindingTableSize =
644         MOS_ALIGN_CEIL(pSettings->iSurfacesPerBT * pHwSizes->dwSizeBindingTableState, pSettings->iBTAlignment);
645 
646     // Calculate memory size to store all binding tables and surface states
647     pStateHeap->dwSizeSSH = pSettings->iBindingTables * pStateHeap->iBindingTableSize +
648                             pSettings->iSurfaceStates *
649                             pRenderHalLegacy->pRenderHalPltInterface->GetSurfaceStateCmdSize();
650     pRenderHalLegacy->dwIndirectHeapSize = MOS_ALIGN_CEIL(pStateHeap->dwSizeSSH, MHW_PAGE_SIZE);
651 
652     // Allocate local copy of SSH
653     pStateHeap->pSshBuffer = (uint8_t*)MOS_AllocAndZeroMemory(pStateHeap->dwSizeSSH);
654     if (!pStateHeap->pSshBuffer)
655     {
656         MHW_RENDERHAL_ASSERTMESSAGE("Fail to Allocate SSH buffer.");
657         eStatus = MOS_STATUS_NO_SPACE;
658         goto finish;
659     }
660 
661     pStateHeap->iBindingTableOffset  = 0;
662     pStateHeap->iSurfaceStateOffset  = pSettings->iBindingTables * pStateHeap->iBindingTableSize;
663     pStateHeap->pSurfaceEntry        = (PRENDERHAL_SURFACE_STATE_ENTRY) MOS_AllocAndZeroMemory(pSettings->iSurfaceStates * sizeof(RENDERHAL_SURFACE_STATE_ENTRY));
664     MHW_RENDERHAL_CHK_NULL(pStateHeap->pSurfaceEntry);
665 
666     //----------------------------------
667     // Allocate Instruction State Heap in MHW
668     //----------------------------------
669     MhwStateHeapSettings.dwIshSize         = pRenderHalLegacy->DynamicHeapSettings.dwIshInitialSize;
670     MhwStateHeapSettings.m_keepIshLocked   = true;
671     MhwStateHeapSettings.dwNumSyncTags     = pSettings->iSyncSize;
672     MhwStateHeapSettings.dwIshIncrement    = pRenderHalLegacy->DynamicHeapSettings.dwIshSizeIncrement;
673     MhwStateHeapSettings.dwIshMaxSize      = pRenderHalLegacy->DynamicHeapSettings.dwIshMaximumSize;
674 
675     MHW_RENDERHAL_CHK_STATUS(pMhwRender->AllocateHeaps(MhwStateHeapSettings));
676     MHW_RENDERHAL_CHK_NULL(pMhwRender->m_stateHeapInterface);
677     pMhwStateHeap = pRenderHalLegacy->pMhwStateHeap = pMhwRender->m_stateHeapInterface->pStateHeapInterface;
678 
679     // Size of a Media ID entry
680     pStateHeap->dwSizeMediaID = pHwSizes->dwSizeInterfaceDescriptor;
681 
682     // Not used in Dynamic mode - heaps may change
683     pRenderHalLegacy->pOsInterface->pfnResetResource(&pStateHeap->GshOsResource);
684     pStateHeap->pGshBuffer = nullptr;
685     pStateHeap->bGshLocked = false;
686 
687     pRenderHalLegacy->pOsInterface->pfnResetResource(&pStateHeap->IshOsResource);
688     pStateHeap->pIshBuffer = nullptr;
689     pStateHeap->bIshLocked = false;
690 
691     // Setup pointer to sync tags
692     pStateHeap->pSync = (uint32_t *)pRenderHalLegacy->pMhwStateHeap->GetCmdBufIdGlobalPointer();
693 
694     // Reset pool of Kernel allocations objects
695     pStateHeap->pKernelAllocMemPool = MOS_New(MHW_MEMORY_POOL,
696                                 (uint32_t)sizeof(RENDERHAL_KRN_ALLOCATION),
697                                 (uint32_t)sizeof(void *));
698     MHW_RENDERHAL_CHK_NULL(pStateHeap->pKernelAllocMemPool);
699 
700     MHW_RENDERHAL_CHK_STATUS(RenderHal_DSH_ExtendKernelAllocPool(pStateHeap));
701 
702     eStatus = MOS_STATUS_SUCCESS;
703 
704 finish:
705     if (eStatus != MOS_STATUS_SUCCESS)
706     {
707         // Free SSH buffer
708         if (pStateHeap)
709         {
710             if (pStateHeap->pSurfaceEntry)
711             {
712                 MOS_FreeMemory(pStateHeap->pSurfaceEntry);
713             }
714 
715             if (pStateHeap->pSshBuffer)
716             {
717                 MOS_FreeMemory(pStateHeap->pSshBuffer);
718             }
719         }
720     }
721 
722     return eStatus;
723 }
724 
725 //!
726 //! \brief    Free State Heaps (including MHW interfaces)
727 //! \details  Free State Heap resources allocated by RenderHal
728 //! \param    PRENDERHAL_INTERFACE pRenderHal
729 //!           [in] Pointer to Render Hal Interface
730 //! \return   MOS_STATUS
731 //!
RenderHal_DSH_FreeStateHeaps(PRENDERHAL_INTERFACE pRenderHal)732 MOS_STATUS RenderHal_DSH_FreeStateHeaps(PRENDERHAL_INTERFACE pRenderHal)
733 {
734     PMOS_INTERFACE                  pOsInterface;
735     PRENDERHAL_STATE_HEAP_LEGACY    pStateHeap;
736     MOS_STATUS                      eStatus;
737 
738     //------------------------------------------------
739     MHW_RENDERHAL_CHK_NULL(pRenderHal);
740     MHW_RENDERHAL_CHK_NULL(pRenderHal->pOsInterface);
741     MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap);
742     //------------------------------------------------
743 
744     eStatus      = MOS_STATUS_UNKNOWN;
745 
746     pOsInterface = pRenderHal->pOsInterface;
747     pStateHeap   = (PRENDERHAL_STATE_HEAP_LEGACY)pRenderHal->pStateHeap;
748 
749     // Free Surface State Entries
750     if (pStateHeap->pSurfaceEntry)
751     {
752         // Free MOS surface in surface state entry
753         for (int32_t index = 0; index < pRenderHal->StateHeapSettings.iSurfaceStates; ++index) {
754             PRENDERHAL_SURFACE_STATE_ENTRY entry = pStateHeap->pSurfaceEntry + index;
755             MOS_SafeFreeMemory(entry->pSurface);
756             entry->pSurface = nullptr;
757         }
758 
759         MOS_FreeMemory(pStateHeap->pSurfaceEntry);
760         pStateHeap->pSurfaceEntry = nullptr;
761     }
762 
763     // Free SSH Resource
764     if (pStateHeap->pSshBuffer)
765     {
766         MOS_FreeMemory(pStateHeap->pSshBuffer);
767         pStateHeap->pSshBuffer = nullptr;
768     }
769 
770     if(pStateHeap->pMediaStatesMemPool)
771     {
772         MOS_Delete(pStateHeap->pMediaStatesMemPool);
773         pStateHeap->pMediaStatesMemPool = nullptr;
774     }
775 
776     if(pStateHeap->pKernelAllocMemPool)
777     {
778         MOS_Delete(pStateHeap->pKernelAllocMemPool);
779         pStateHeap->pKernelAllocMemPool = nullptr;
780     }
781 
782     // Free kernel hash table
783     pStateHeap->kernelHashTable.Free();
784 
785     // Free State Heap Control structure
786     MOS_AlignedFreeMemory(pStateHeap);
787     pRenderHal->pStateHeap = nullptr;
788 
789     pRenderHal->pRenderHalPltInterface->FreeScratchSpaceBuffer(pRenderHal);
790 
791     eStatus = MOS_STATUS_SUCCESS;
792 
793 finish:
794     return eStatus;
795 }
796 
797 //!
798 //! \brief    Assign memory block in state heap
799 //! \param    RENDERHAL_TR_RESOURCE trackerInfo
800 //!           [in] Pointer to tracker resource
801 //! \param    HeapManager heapManager
802 //!           [in] Pointer to heap manager
803 //! \param    MemoryBlock block
804 //!           [out] Pointer to memory block
805 //! \param    uint32_t size
806 //!           [in] size of requested memory block
807 //! \return   MOS_STATUS
808 //!
RenderHal_DSH_AssignSpaceInStateHeap(uint32_t trackerIndex,FrameTrackerProducer * trackerProducer,HeapManager * heapManager,MemoryBlock * block,uint32_t size)809 MOS_STATUS RenderHal_DSH_AssignSpaceInStateHeap(
810     uint32_t trackerIndex,
811     FrameTrackerProducer *trackerProducer,
812     HeapManager *heapManager,
813     MemoryBlock *block,
814     uint32_t size)
815 {
816     MOS_STATUS eStatus     = MOS_STATUS_SUCCESS;
817     uint32_t   spaceNeeded = 0;
818     std::vector<MemoryBlock> blocks;
819     std::vector<uint32_t> blockSizes;
820 
821     MemoryBlockManager::AcquireParams acquireParams =
822         MemoryBlockManager::AcquireParams(trackerProducer->GetNextTracker(trackerIndex),
823                                           blockSizes);
824     acquireParams.m_trackerIndex = trackerIndex; // use the first tracker only
825 
826     MHW_RENDERHAL_CHK_NULL(heapManager);
827     MHW_RENDERHAL_CHK_NULL(block);
828     MHW_RENDERHAL_CHK_NULL(trackerProducer);
829 
830     if (blockSizes.empty())
831     {
832         blockSizes.emplace_back(size);
833     }
834     else
835     {
836         blockSizes[0] = size;
837     }
838 
839     MHW_RENDERHAL_CHK_STATUS(heapManager->AcquireSpace(acquireParams, blocks, spaceNeeded));
840 
841     if (blocks.empty())
842     {
843         MHW_RENDERHAL_ASSERTMESSAGE("No blocks were acquired");
844         return MOS_STATUS_UNKNOWN;
845     }
846     if (!(blocks[0].IsValid()))
847     {
848         MHW_RENDERHAL_ASSERTMESSAGE("No blocks were acquired");
849         return MOS_STATUS_UNKNOWN;
850     }
851 
852     *block = blocks[0];
853 
854     // zero memory block
855     block->AddData(nullptr, 0, 0, true);
856 
857 finish:
858     return eStatus;
859 }
860 
861 //!
862 //! \brief    Refresh Sync
863 //! \details  Update Sync tags
864 //! \param    PRENDERHAL_INTERFACE pRenderHal
865 //!           [in] Pointer to Hardware Interface Structure
866 //! \return   MOS_STATUS
867 //!
RenderHal_DSH_RefreshSync(PRENDERHAL_INTERFACE pRenderHal)868 MOS_STATUS RenderHal_DSH_RefreshSync(PRENDERHAL_INTERFACE pRenderHal)
869 {
870     PRENDERHAL_STATE_HEAP       pStateHeap;
871     PRENDERHAL_MEDIA_STATE      pCurMediaState;
872     PRENDERHAL_MEDIA_STATE      pNextMediaState;
873     PRENDERHAL_DYNAMIC_STATE    pDynamicState;
874     PMHW_BATCH_BUFFER           pBatchBuffer;
875     uint32_t                    dwCurrentTag;
876     uint32_t                    dwCurrentFrameId;
877     int32_t                     iStatesInUse;
878     int32_t                     iBuffersInUse;
879     int32_t                     iKernelsInUse;
880     MOS_STATUS                  eStatus;
881     MOS_NULL_RENDERING_FLAGS    NullRenderingFlags;
882     PXMHW_STATE_HEAP_INTERFACE  pMhwStateHeap;
883     PRENDERHAL_MEDIA_STATE_LIST pList;
884     PRENDERHAL_KRN_ALLOCATION   pKrnAllocation, pNext;
885 
886     //----------------------------------
887     MHW_RENDERHAL_CHK_NULL(pRenderHal);
888     MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap);
889     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwStateHeap);
890     //----------------------------------
891 
892     eStatus         = MOS_STATUS_UNKNOWN;
893 
894     // GSH must be locked
895     pStateHeap    = pRenderHal->pStateHeap;
896     pMhwStateHeap = pRenderHal->pMhwStateHeap;
897     if (!pMhwStateHeap->GetCmdBufIdGlobalPointer())
898     {
899         goto finish;
900     }
901 
902     // Most recent tags
903     pStateHeap->dwSyncTag = dwCurrentTag     = pStateHeap->pSync[0];
904 
905     // Refresh batch buffers
906     iBuffersInUse = 0;
907     pBatchBuffer  = pRenderHal->pBatchBufferList;
908 
909     NullRenderingFlags  = pRenderHal->pOsInterface->pfnGetNullHWRenderFlags(pRenderHal->pOsInterface);
910 
911     for (; pBatchBuffer != nullptr; pBatchBuffer = pBatchBuffer->pNext)
912     {
913         if (!pBatchBuffer->bBusy) continue;
914 
915         // Clear BB busy flag when Sync Tag is reached
916         if ((int32_t)(dwCurrentTag - pBatchBuffer->dwSyncTag) > 0 ||
917             NullRenderingFlags.VPGobal)
918         {
919             pBatchBuffer->bBusy = false;
920         }
921         else
922         {
923             iBuffersInUse++;
924         }
925     }
926 
927     // Refresh media states
928     pList = &(pStateHeap->SubmittedStates);
929 
930     pNextMediaState = nullptr;
931     pCurMediaState  = pList->pHead;
932     iStatesInUse    = 0;
933     for (; pCurMediaState != nullptr; pCurMediaState = pNextMediaState)
934     {
935         // Save next media state before moving current state back to pool (if complete)
936         pNextMediaState = pCurMediaState->pNext;
937 
938         if (!pCurMediaState->bBusy) continue;
939 
940         // The condition below is valid when sync tag wraps from 2^32-1 to 0
941         if (FrameTrackerTokenFlat_IsExpired(&pCurMediaState->trackerToken))
942         {
943             PRENDERHAL_MEDIA_STATE_LEGACY pCurMediaStateLegacy = (PRENDERHAL_MEDIA_STATE_LEGACY)pCurMediaState;
944             pDynamicState = pCurMediaStateLegacy->pDynamicState;
945             pCurMediaState->bBusy = false;
946             if (pRenderHal->bKerneltimeDump)
947             {
948                 uint64_t uiNS;
949                 uint8_t *pCurrentPtr;
950                 uint64_t uiStartTime;
951                 uint64_t uiEndTime;
952                 uint64_t uiDiff;
953                 double  TimeMS;
954                 uint32_t uiComponent;
955                 uint32_t performanceSize = sizeof(uint64_t) * 2 + sizeof(RENDERHAL_COMPONENT);
956                 uint8_t *data = (uint8_t*)MOS_AllocAndZeroMemory(performanceSize);
957                 if (data == nullptr)
958                 {
959                     eStatus = MOS_STATUS_NO_SPACE;
960                     goto finish;
961                 }
962                 // Dump Kernel execution time when media state is being freed
963                 pDynamicState->memoryBlock.ReadData(data, pDynamicState->Performance.dwOffset, performanceSize);
964                 pCurrentPtr = data;
965                 uiStartTime = *((uint64_t *)pCurrentPtr);
966                 pCurrentPtr += sizeof(uint64_t);
967                 uiEndTime = *((uint64_t *)pCurrentPtr);
968                 pCurrentPtr += sizeof(uint64_t);
969                 uiComponent = *((RENDERHAL_COMPONENT *)pCurrentPtr);
970                 if (uiComponent < (uint32_t)RENDERHAL_COMPONENT_COUNT)
971                 {
972                     // Convert ticks to ns
973                     uiDiff = uiEndTime - uiStartTime;
974                     uiNS = 0;
975                     pRenderHal->pfnConvertToNanoSeconds(pRenderHal, uiDiff, &uiNS);
976 
977                     TimeMS = ((double)uiNS) / (1000 * 1000); // Convert to ms (double)
978 
979                     pRenderHal->kernelTime[uiComponent] += TimeMS;
980                 }
981 
982                 MOS_SafeFreeMemory(data);
983             }
984 
985             // Detach from submitted states, return to pool
986             *((pCurMediaState->pNext) ? &(pCurMediaState->pNext->pPrev) : &(pList->pTail)) = pCurMediaState->pPrev;
987             *((pCurMediaState->pPrev) ? &(pCurMediaState->pPrev->pNext) : &(pList->pHead)) = pCurMediaState->pNext;
988             pCurMediaState->pPrev = pCurMediaState->pNext = nullptr;
989             pList->iCount--;
990 
991             // Return media state object back to pool
992             RenderHal_DSH_ReturnMediaStateToPool(pStateHeap, pCurMediaState);
993         }
994         else
995         {
996             iStatesInUse++;
997         }
998     }
999 
1000     // Refresh kernels
1001     iKernelsInUse  = 0;
1002     pKrnAllocation = pStateHeap->KernelsSubmitted.pHead;
1003     for ( ; pKrnAllocation != nullptr; pKrnAllocation = pNext)
1004     {
1005         pNext = pKrnAllocation->pNext;
1006 
1007         // Move kernels back to allocated list (kernel remains cached)
1008         if (FrameTrackerTokenFlat_IsExpired(&pKrnAllocation->trackerToken))
1009         {
1010             RenderHal_DSH_KernelAttach(&pStateHeap->KernelsAllocated, pKrnAllocation, false);
1011 
1012             // Kernel block is flagged for removal (growing ISH) - delete block, mark kernel as stale
1013             if (pKrnAllocation->pMemoryBlock && pKrnAllocation->pMemoryBlock->bDelete)
1014             {
1015                 pMhwStateHeap->FreeDynamicBlockDyn(MHW_ISH_TYPE, pKrnAllocation->pMemoryBlock);
1016                 pKrnAllocation->dwFlags = RENDERHAL_KERNEL_ALLOCATION_USED;
1017             }
1018             else
1019             {
1020                 // Mark kernel as in use, not locked
1021                 pKrnAllocation->dwFlags = RENDERHAL_KERNEL_ALLOCATION_USED;
1022             }
1023         }
1024         else
1025         {
1026             iKernelsInUse++;
1027         }
1028     }
1029 
1030     // Refresh blocks
1031     pMhwStateHeap->RefreshDynamicHeapDyn(MHW_ISH_TYPE);
1032 
1033     // Save number of states/buffers in use
1034     pRenderHal->iBuffersInUse     = iBuffersInUse;
1035     pRenderHal->iKernelsInUse     = iKernelsInUse;
1036     pRenderHal->iMediaStatesInUse = iStatesInUse;
1037 
1038     eStatus = MOS_STATUS_SUCCESS;
1039 
1040 finish:
1041     return eStatus;
1042 }
1043 
1044 //!
1045 //! \brief    Extend the kernel state heap
1046 //! \details  Increases the size of the ISH (up to the maximum size)
1047 //!           Flags all submitted and allocated kernels as "stale" so can reload into new heap
1048 //!           Allocates new ISH and deletes old heap
1049 //!           Moves SIP binary to new heap
1050 //! \param    PRENDERHAL_STATE_HEAP pStateHeap
1051 //!           [in] Pointer to the state heap
1052 //! \param    uint32_t dwAdditionalKernelSpaceNeeded
1053 //!           [in] amount of additional space needed for kernel
1054 //! \return   MOS_STATUS
1055 //!
RenderHal_DSH_ExpandKernelStateHeap(PRENDERHAL_INTERFACE pRenderHal,uint32_t dwAdditionalKernelSpaceNeeded)1056 MOS_STATUS RenderHal_DSH_ExpandKernelStateHeap(
1057     PRENDERHAL_INTERFACE pRenderHal,
1058     uint32_t             dwAdditionalKernelSpaceNeeded)
1059 {
1060     PXMHW_STATE_HEAP_INTERFACE pMhwStateHeap;
1061     PRENDERHAL_KRN_ALLOCATION pKrnAllocation;
1062     PRENDERHAL_STATE_HEAP     pStateHeap;
1063     uint32_t                  dwNewSize;
1064     MOS_STATUS                eStatus = MOS_STATUS_SUCCESS;
1065     PMHW_STATE_HEAP              pOldInstructionHeap;
1066     PMHW_STATE_HEAP_MEMORY_BLOCK pOldSipKernelBlock;
1067     PRENDERHAL_INTERFACE_LEGACY pRenderHalLegacy = static_cast<PRENDERHAL_INTERFACE_LEGACY>(pRenderHal);
1068 
1069     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy);
1070     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pStateHeap);
1071     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pMhwStateHeap);
1072 
1073     pMhwStateHeap = pRenderHalLegacy->pMhwStateHeap;
1074     pStateHeap    = pRenderHalLegacy->pStateHeap;
1075 
1076     // Increase size of the ISH (up to max size)
1077     dwNewSize = MOS_ALIGN_CEIL(pMhwStateHeap->GetISHPointer()->dwSize + dwAdditionalKernelSpaceNeeded,
1078                                pRenderHalLegacy->DynamicHeapSettings.dwIshSizeIncrement);
1079     if (dwNewSize > pRenderHalLegacy->DynamicHeapSettings.dwIshMaximumSize)
1080     {
1081         goto finish;
1082     }
1083 
1084     // Flag all submitted kernels as "stale", so they can be reloaded into the new heap
1085     for (pKrnAllocation = pStateHeap->KernelsSubmitted.pHead; pKrnAllocation != nullptr; pKrnAllocation = pKrnAllocation->pNext)
1086     {
1087         pKrnAllocation->dwFlags = RENDERHAL_KERNEL_ALLOCATION_STALE;
1088         if (pKrnAllocation->pMemoryBlock)
1089         {
1090             pKrnAllocation->pMemoryBlock->bStatic = false;
1091             MHW_RENDERHAL_CHK_STATUS(pMhwStateHeap->FreeDynamicBlockDyn(MHW_ISH_TYPE, pKrnAllocation->pMemoryBlock));
1092             pKrnAllocation->pMemoryBlock = nullptr;
1093         }
1094     }
1095 
1096     // Flag all kernels allocated as "stale", so they can be reloaded into the new heap
1097     for (pKrnAllocation = pStateHeap->KernelsAllocated.pHead; pKrnAllocation != nullptr; pKrnAllocation = pKrnAllocation->pNext)
1098     {
1099         pKrnAllocation->dwFlags = RENDERHAL_KERNEL_ALLOCATION_STALE;
1100         if (pKrnAllocation->pMemoryBlock)
1101         {
1102             MHW_RENDERHAL_CHK_STATUS(pMhwStateHeap->FreeDynamicBlockDyn(MHW_ISH_TYPE, pKrnAllocation->pMemoryBlock));
1103             pKrnAllocation->pMemoryBlock = nullptr;
1104         }
1105     }
1106 
1107     // Get SIP kernel block prior to expansion
1108     // NOTE: SIP kernel block is NOT associated with any KRN allocation and will be freed after copying to the new heap
1109     pOldInstructionHeap = pMhwStateHeap->GetISHPointer();
1110     pOldSipKernelBlock  = pOldInstructionHeap->pDebugKernel;
1111 
1112     // Allocate new instruction state heap
1113     MHW_RENDERHAL_CHK_STATUS(pMhwStateHeap->ExtendStateHeap(MHW_ISH_TYPE, dwNewSize));
1114 
1115     // Copy SIP kernel into the newly loaded ISH, mark old SIP block to be released when no longer in use
1116     if (pOldSipKernelBlock)
1117     {
1118         MHW_RENDERHAL_CHK_STATUS(pRenderHalLegacy->pfnLoadSipKernel(pRenderHalLegacy, pOldSipKernelBlock->pDataPtr, pOldSipKernelBlock->dwDataSize));
1119         pOldSipKernelBlock->bStatic = false;
1120         pOldInstructionHeap->pDebugKernel = nullptr;
1121     }
1122 
1123     // Free old instruction state heap
1124     MHW_RENDERHAL_CHK_STATUS(pMhwStateHeap->ReleaseStateHeapDyn(pOldInstructionHeap));
1125 
1126 finish:
1127     return eStatus;
1128 }
1129 
1130 //!
1131 //! \brief    Refresh available space in Dynamic ISH, create space by either unloading
1132 //!           expired kernels or expanding the ISH (up to its max size)
1133 //! \details  Refresh space in Dynamic ISH, creating contiguous space for kernel load
1134 //! \param    PRENDERHAL_INTERFACE pRenderHal
1135 //!           [in] Pointer to Hardware Interface Structure
1136 //! \param    uint32_t dwSpaceNeeded
1137 //!           [in] Space needed in dynamic ISH for new kernel to be loaded
1138 //! \return   MOS_STATUS
1139 //!
RenderHal_DSH_RefreshDynamicKernels(PRENDERHAL_INTERFACE pRenderHal,uint32_t dwSpaceNeeded,uint32_t * pdwSizes,int32_t iCount)1140 MOS_STATUS RenderHal_DSH_RefreshDynamicKernels(
1141     PRENDERHAL_INTERFACE        pRenderHal,
1142     uint32_t                    dwSpaceNeeded,
1143     uint32_t                    *pdwSizes,
1144     int32_t                     iCount)
1145 {
1146     uint32_t                            TempArray[1] = { dwSpaceNeeded };
1147     MHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS Params;
1148     PRENDERHAL_STATE_HEAP               pStateHeap;
1149     PXMHW_STATE_HEAP_INTERFACE          pMhwStateHeap;
1150     PRENDERHAL_KRN_ALLOCATION           pKrnAllocation, pNext;
1151     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
1152 
1153     MHW_RENDERHAL_CHK_NULL(pRenderHal);
1154     MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap);
1155     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwStateHeap);
1156 
1157     pStateHeap    = pRenderHal->pStateHeap;
1158     pMhwStateHeap = pRenderHal->pMhwStateHeap;
1159 
1160     // Release move kernels from submitted back to allocated list according to Sync Tag
1161     pRenderHal->pfnRefreshSync(pRenderHal);
1162 
1163     // No block sizes provided, assume that the space requested must be contiguous
1164     if (!pdwSizes)
1165     {
1166         pdwSizes = TempArray;
1167         iCount   = 1;
1168     }
1169 
1170     // The function below will calculate how much space is still needed in state heap
1171     // considering the size of the blocks provided. This function accounts for fragmentation,
1172     // so even if the heap has enough space, the call may still return a non-zero value.
1173 
1174     Params.piSizes       = (int32_t*)pdwSizes;
1175     Params.iCount        = iCount;
1176     Params.dwAlignment   = 0;
1177     Params.bHeapAffinity = true;
1178     Params.pHeapAffinity = pMhwStateHeap->GetISHPointer(); // only search for space in active heap
1179     Params.dwScratchSpace= 0;
1180 
1181     dwSpaceNeeded = pMhwStateHeap->CalculateSpaceNeededDyn(MHW_ISH_TYPE, &Params);
1182 
1183     // Implementation note:
1184     // Kernels are moved from the KernelsAllocated list to the KernelsSubmitted
1185     // list whenever they are used via pfnTouchDynamicKernel function. When complete
1186     // they are moved back to end end of the KernelsAllocated list via pfnRefreshSync.
1187     // As a result, the allocation list is always sorted based on recent usage
1188     // (older kernels remain at the head of the list)
1189     //
1190     // The caching algorithm tries to find a balance between amount of times
1191     // the kernels was used, and how recently it was used - so kernels that are
1192     // heavily used but at the beginning of the list are less likely to be removed
1193     // compared with a kernel that was barely used (dwCount)
1194     //
1195     // IMPORTANT - Only one kernel allocation entry per Kernel UID (1:1 mapping)
1196     //
1197 
1198     pKrnAllocation = pStateHeap->KernelsAllocated.pHead;
1199     for ( ; (pKrnAllocation != nullptr) && (dwSpaceNeeded > 0); pKrnAllocation = pNext)
1200     {
1201         pNext = pKrnAllocation->pNext;
1202 
1203         if (pKrnAllocation->pMemoryBlock && pKrnAllocation->dwFlags != RENDERHAL_KERNEL_ALLOCATION_LOCKED)
1204         {
1205             // Only count this as available space if the block is in current heap!
1206             if (pKrnAllocation->pMemoryBlock->pStateHeap == pMhwStateHeap->GetISHPointer())
1207             {
1208                 dwSpaceNeeded -= MOS_MIN(dwSpaceNeeded, pKrnAllocation->pMemoryBlock->dwBlockSize);
1209             }
1210 
1211             MHW_RENDERHAL_CHK_STATUS(pMhwStateHeap->FreeDynamicBlockDyn(MHW_ISH_TYPE, pKrnAllocation->pMemoryBlock));
1212             pKrnAllocation->pMemoryBlock = nullptr;
1213             pKrnAllocation->dwOffset     = 0;
1214             pKrnAllocation->dwFlags      = RENDERHAL_KERNEL_ALLOCATION_REMOVED;
1215         }
1216     }
1217 
1218     // Failed to remove enough kernels
1219     if (dwSpaceNeeded > 0)
1220     {
1221         eStatus = MOS_STATUS_UNKNOWN;
1222     }
1223 
1224 finish:
1225     return eStatus;
1226 }
1227 
RenderHal_DSH_ResetDynamicKernels(PRENDERHAL_INTERFACE pRenderHal)1228 void RenderHal_DSH_ResetDynamicKernels(
1229     PRENDERHAL_INTERFACE        pRenderHal)
1230 {
1231     return;
1232 }
1233 
1234 //!
1235 //! \brief    Load Kernel using dynamic state heap model
1236 //! \details  Load a kernel from cache into GSH; do not unload kernels
1237 //! \param    PRENDERHAL_INTERFACE pRenderHal
1238 //!           [in] Pointer to Hardware Interface Structure
1239 //! \param    PCRENDERHAL_KERNEL_PARAM pParameters
1240 //!           [in] Pointer to Kernel Parameters
1241 //! \param    PMHW_KERNEL_PARAMS pKernel
1242 //!           [in] Pointer to Kernel entry
1243 //! \param    Kdll_CacheEntry pKernelEntry
1244 //!           [in] The cache entry pointer maintaining the load status.
1245 //!                For cache entries from local variable,
1246 //!                set it to nullptr to avoid memory corruption
1247 //! \return   int32_t
1248 //!           Index to a kernel allocation index
1249 //!           -1 if invalid parameters, no available space and no
1250 //!            deallocation possible
1251 //!
RenderHal_DSH_LoadDynamicKernel(PRENDERHAL_INTERFACE pRenderHal,PCRENDERHAL_KERNEL_PARAM pParameters,PMHW_KERNEL_PARAM pKernel,uint32_t * pdwLoaded)1252 PRENDERHAL_KRN_ALLOCATION RenderHal_DSH_LoadDynamicKernel(
1253     PRENDERHAL_INTERFACE        pRenderHal,
1254     PCRENDERHAL_KERNEL_PARAM    pParameters,
1255     PMHW_KERNEL_PARAM           pKernel,
1256     uint32_t                    *pdwLoaded)
1257 {
1258     MHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS Params;              // Block allocation parameters
1259     PRENDERHAL_STATE_HEAP_LEGACY        pStateHeap;          // Renderhal State Heap control structure
1260     PXMHW_STATE_HEAP_INTERFACE   pMhwStateHeap;              // Dynamic MHW state heap interface
1261     PRENDERHAL_KRN_ALLOCATION    pKernelAllocation = nullptr;   // Kernel Allocation
1262     PMHW_STATE_HEAP_MEMORY_BLOCK pKernelMemoryBlock;         // Memory block in ISH where kernel is loaded
1263     int32_t                      iKernelSize;                // Kernel size
1264     int32_t                      iKernelUniqueID;            // Kernel unique ID
1265     int32_t                      iKernelCacheID;             // Kernel cache ID
1266     uint16_t                     wSearchIndex = 0;
1267     MOS_STATUS                   eStatus = MOS_STATUS_SUCCESS;
1268 
1269     MHW_RENDERHAL_CHK_NULL(pRenderHal);
1270     MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap);
1271     MHW_RENDERHAL_CHK_NULL(pParameters);
1272     MHW_RENDERHAL_CHK_NULL(pKernel);
1273 
1274     pStateHeap = (PRENDERHAL_STATE_HEAP_LEGACY)pRenderHal->pStateHeap;
1275     pMhwStateHeap = pRenderHal->pMhwStateHeap;
1276 
1277     // Validate parameters
1278     if (pKernel->iSize == 0)
1279     {
1280         eStatus = MOS_STATUS_INVALID_PARAMETER;
1281         MHW_RENDERHAL_NORMALMESSAGE("Failed to load kernel - invalid parameters.");
1282         goto finish;
1283     }
1284 
1285     // Kernel parameters
1286     iKernelSize     = pKernel->iSize;
1287     iKernelUniqueID = pKernel->iKUID;
1288     iKernelCacheID  = pKernel->iKCID;
1289 
1290     pKernelAllocation = (PRENDERHAL_KRN_ALLOCATION)pStateHeap->kernelHashTable.Search(iKernelUniqueID, iKernelCacheID, wSearchIndex);
1291 
1292     // Kernel already loaded
1293     if (pKernelAllocation)
1294     {
1295         // found match and Update kernel usage
1296         pRenderHal->pfnTouchDynamicKernel(pRenderHal, pKernelAllocation);
1297 
1298         // Increment reference counter
1299         pKernel->bLoaded = 1;
1300 
1301         goto finish;
1302     }
1303 
1304     // Get new kernel allocation entry
1305     pKernelAllocation = RenderHal_DSH_GetKernelAllocationFromPool(pRenderHal->pStateHeap);
1306     MHW_RENDERHAL_CHK_NULL(pKernelAllocation);
1307 
1308     // Simple allocation - get next kernel allocation entry available from pool
1309 
1310     // Prepare Media State Allocation in DSH
1311     Params.piSizes          = &iKernelSize;
1312     Params.iCount           = 1;
1313     Params.dwAlignment      = RENDERHAL_KERNEL_BLOCK_ALIGN;
1314     Params.bHeapAffinity    = 0;
1315     Params.pHeapAffinity    = 0;
1316     Params.dwScratchSpace   = 0;
1317     Params.pScratchSpace    = nullptr;
1318     Params.bZeroAssignedMem = 0;
1319     Params.bStatic          = true;
1320     Params.bGrow            = 0;
1321 
1322     pKernelMemoryBlock = pMhwStateHeap->AllocateDynamicBlockDyn(MHW_ISH_TYPE, &Params);
1323 
1324     // Here is where the dynamic state heap comes into play - by expanding ISH on demand to load a new kernel (ISH can literally start from size 0)
1325     if (!pKernelMemoryBlock)
1326     {
1327         // Extend ISH, making enough room to load the new kernel
1328         MHW_RENDERHAL_CHK_STATUS(RenderHal_DSH_ExpandKernelStateHeap(pRenderHal, iKernelSize));
1329 
1330         // Try again to load the kernel - this should now work, unless something went wrong with the allocation (max size reached)
1331         pKernelMemoryBlock = pMhwStateHeap->AllocateDynamicBlockDyn(MHW_ISH_TYPE, &Params);
1332     }
1333 
1334     // Failed to load kernel
1335     if (!pKernelMemoryBlock)
1336     {
1337         MHW_RENDERHAL_NORMALMESSAGE("Failed to load kernel - no space available in GSH.");
1338         // Return the kernel allocation to pool
1339         RenderHal_DSH_KernelAttach(&pStateHeap->KernelAllocationPool, pKernelAllocation, false);
1340         pKernelAllocation = nullptr;
1341         goto finish;
1342     }
1343 
1344     // Allocate kernel
1345     pKernelAllocation->iKID            = -1;
1346     pKernelAllocation->iKUID           = iKernelUniqueID;
1347     pKernelAllocation->iKCID           = iKernelCacheID;
1348     FrameTrackerTokenFlat_Clear(&pKernelAllocation->trackerToken);
1349     pKernelAllocation->dwOffset        = pKernelMemoryBlock->dwDataOffset;  // NOT USED IN DSH - KEPT FOR DEBUG SUPPORT
1350     pKernelAllocation->iSize           = pKernelMemoryBlock->dwDataSize;    // NOT USED IN DSH - KEPT FOR DEBUG SUPPORT
1351     pKernelAllocation->dwFlags         = RENDERHAL_KERNEL_ALLOCATION_USED;
1352     pKernelAllocation->dwCount         = 0;  // will be updated by "TouchKernel"
1353     pKernelAllocation->Params          = *pParameters;
1354     pKernelAllocation->pKernelEntry    = nullptr; // CURRENTLY NOT USED
1355     pKernelAllocation->iAllocIndex     = -1;   // DSH NOT USED
1356     pKernelAllocation->pMemoryBlock    = pKernelMemoryBlock;
1357 
1358     // Copy kernel data - securely erase unused part of the block
1359     MOS_SecureMemcpy(pKernelMemoryBlock->pDataPtr, iKernelSize, pKernel->pBinary, iKernelSize);
1360     if (iKernelSize < (int32_t)pKernelMemoryBlock->dwDataSize)
1361     {
1362         MOS_ZeroMemory((uint8_t*)pKernelMemoryBlock->pDataPtr + iKernelSize, pKernelMemoryBlock->dwDataSize - iKernelSize);
1363     }
1364 
1365 finish:
1366     // Move kernel to the tail of the list of kernels (head of the list contains oldest kernels)
1367     if (pKernelAllocation)
1368     {
1369         // Move kernel allocation to end of list of kernels (sorted by usage)
1370         pRenderHal->pfnTouchDynamicKernel(pRenderHal, pKernelAllocation);
1371     }
1372 
1373     // Return kernel allocation
1374     return pKernelAllocation;
1375 }
1376 
1377 //!
1378 //! \brief    Unload Kernel using dynamic model
1379 //! \details  Unload a kernel from GSH, free kernel heap space
1380 //!           Notify that the kernel has been unloaded (for tracking)
1381 //! \param    PRENDERHAL_INTERFACE pRenderHal
1382 //!           [in] Pointer to Hardware Interface Structure
1383 //! \param    int32_t iKernelAllocationID
1384 //!           [in] Kernel allocation index in GSH
1385 //! \return   MOS_STATUS
1386 //!           true if success
1387 //!           false if invalid parameters or if kernel cannot be unloaded
1388 //!
RenderHal_DSH_UnloadDynamicKernel(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_KRN_ALLOCATION pKernelAllocation)1389 MOS_STATUS RenderHal_DSH_UnloadDynamicKernel(
1390     PRENDERHAL_INTERFACE        pRenderHal,
1391     PRENDERHAL_KRN_ALLOCATION   pKernelAllocation)
1392 {
1393     PRENDERHAL_STATE_HEAP       pStateHeap;
1394     MOS_STATUS                  eStatus;
1395 
1396     //---------------------------------------
1397     MHW_RENDERHAL_CHK_NULL(pRenderHal);
1398     MHW_RENDERHAL_CHK_NULL(pKernelAllocation);
1399     MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap);
1400     //---------------------------------------
1401 
1402     eStatus    = MOS_STATUS_UNKNOWN;
1403     pStateHeap = pRenderHal->pStateHeap;
1404 
1405     //---------------------------------------
1406     MHW_RENDERHAL_CHK_NULL(pStateHeap->pKernelAllocation);
1407     //---------------------------------------
1408 
1409     // Kernel already free - return it to pool
1410     if (pKernelAllocation->dwFlags == RENDERHAL_KERNEL_ALLOCATION_FREE)
1411     {
1412         goto finish;
1413     }
1414 
1415     // Update Sync tags
1416     MHW_RENDERHAL_CHK_STATUS(pRenderHal->pfnRefreshSync(pRenderHal));
1417 
1418     // Check if kernel may be unloaded
1419     if (!FrameTrackerTokenFlat_IsExpired(&pKernelAllocation->trackerToken))
1420     {
1421         goto finish;
1422     }
1423 
1424     // Release kernel entry (Offset/size may be used for reallocation)
1425     pKernelAllocation->iKID             = -1;
1426     pKernelAllocation->iKUID            = -1;
1427     pKernelAllocation->iKCID            = -1;
1428     FrameTrackerTokenFlat_Clear(&pKernelAllocation->trackerToken);
1429     pKernelAllocation->dwFlags          = RENDERHAL_KERNEL_ALLOCATION_FREE;
1430     pKernelAllocation->dwCount          = 0;
1431     pKernelAllocation->pKernelEntry     = nullptr;
1432 
1433     eStatus = MOS_STATUS_SUCCESS;
1434 
1435 finish:
1436     return eStatus;
1437 }
1438 
1439 //!
1440 //! \brief    Load Debug Kernel
1441 //! \details  Load SIP Debug kernel from cache into GSH.
1442 //!           Replace debug surface binding table index with the specified value.
1443 //! \param    PRENDERHAL_INTERFACE pRenderHal
1444 //!           [in] Pointer to Hardware Interface Structure
1445 //! \param    void   *pSipKernel
1446 //!           [in] Pointer to Debug (Sip) Kernel binary
1447 //! \param    uint32_t dwSipSize
1448 //!           [in] Debug (Sip) Kernel size
1449 //! \return   MOS_STATUS
1450 //!
RenderHal_DSH_LoadSipKernel(PRENDERHAL_INTERFACE pRenderHal,void * pSipKernel,uint32_t dwSipSize)1451 MOS_STATUS RenderHal_DSH_LoadSipKernel(
1452     PRENDERHAL_INTERFACE    pRenderHal,
1453     void                    *pSipKernel,
1454     uint32_t                dwSipSize)
1455 {
1456     PXMHW_STATE_HEAP_INTERFACE   pMhwStateHeap;
1457     PMHW_STATE_HEAP              pInstructionStateHeap = nullptr;
1458     PMHW_STATE_HEAP_MEMORY_BLOCK pIshMemoryBlock;
1459     MHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS Params;
1460     MOS_STATUS                   eStatus = MOS_STATUS_SUCCESS;
1461 
1462     MHW_RENDERHAL_CHK_NULL(pRenderHal);
1463     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwStateHeap);
1464 
1465     pMhwStateHeap = pRenderHal->pMhwStateHeap;
1466 
1467     // Mark previous SIP kernel for auto-release so it can be replaced
1468     pInstructionStateHeap = pMhwStateHeap->GetISHPointer();
1469     MHW_RENDERHAL_CHK_NULL(pInstructionStateHeap);
1470     if (pInstructionStateHeap->pDebugKernel)
1471     {
1472         pInstructionStateHeap->pDebugKernel->bStatic = false;
1473         pInstructionStateHeap->pDebugKernel = nullptr;
1474     }
1475 
1476     // If SIP size is zero or binary is nullptr, goto finish (SIP kernel unloaded)
1477     if (dwSipSize == 0 || pSipKernel == nullptr)
1478     {
1479         goto finish;
1480     }
1481 
1482     // Allocate new block for Debug (SIP) kernel
1483     MOS_ZeroMemory(&Params, sizeof(Params));
1484     Params.piSizes           = (int32_t*)&dwSipSize;
1485     Params.iCount            = 1;
1486     Params.dwAlignment       = RENDERHAL_KERNEL_BLOCK_ALIGN;
1487     Params.bHeapAffinity     = true;
1488     Params.pHeapAffinity     = pInstructionStateHeap;
1489     Params.dwScratchSpace    = 0;
1490     Params.pScratchSpace     = nullptr;
1491     Params.bZeroAssignedMem  = false;
1492     Params.bStatic           = true;
1493     Params.bGrow             = false;
1494 #ifdef MHW_DYNAMIC_STATE_HEAP_DEBUGGING
1495     Params.dwBlockType       = MHW_BLOCK_DATA_SIP_KERNEL;
1496     Params.pClientObject     = nullptr;
1497 #endif
1498     pIshMemoryBlock = pInstructionStateHeap->pDebugKernel = pMhwStateHeap->AllocateDynamicBlockDyn(MHW_ISH_TYPE, &Params);
1499     if (!pIshMemoryBlock)
1500     {
1501         eStatus = MOS_STATUS_NO_SPACE;
1502         goto finish;
1503     }
1504 
1505     // Copy SIP Debug kernel into SIP location in ISH (Instruction State Heap)
1506     MOS_SecureMemcpy(pIshMemoryBlock->pDataPtr, dwSipSize, pSipKernel, dwSipSize);
1507 
1508 finish:
1509     return eStatus;
1510 }
1511 
1512 //!
1513 //! \brief    Send SIP state command
1514 //! \details  Send SIP state command pointing to the SIP kernel.
1515 //! \param    PRENDERHAL_INTERFACE pRenderHal
1516 //!           [in] Pointer to Hardware Interface Structure
1517 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
1518 //!           [in] Pointer to Command Buffer
1519 //! \return   MOS_STATUS
1520 //!
RenderHal_DSH_SendSipStateCmd(PRENDERHAL_INTERFACE pRenderHal,PMOS_COMMAND_BUFFER pCmdBuffer)1521 MOS_STATUS RenderHal_DSH_SendSipStateCmd(
1522     PRENDERHAL_INTERFACE  pRenderHal,
1523     PMOS_COMMAND_BUFFER   pCmdBuffer)
1524 {
1525     PMHW_STATE_HEAP_MEMORY_BLOCK pSipMemoryBlock;
1526     PRENDERHAL_INTERFACE_LEGACY  pRenderHalLegacy = (PRENDERHAL_INTERFACE_LEGACY)pRenderHal;
1527 
1528     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1529 
1530     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy);
1531     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pMhwStateHeap);
1532     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pMhwRenderInterface);
1533 
1534     pSipMemoryBlock = pRenderHalLegacy->pMhwStateHeap->GetISHPointer()->pDebugKernel;
1535 
1536     if ((pRenderHalLegacy->bSIPKernel || pRenderHalLegacy->bCSRKernel) && pSipMemoryBlock != nullptr)
1537     {
1538         MhwRenderInterface *pMhwRender        = pRenderHalLegacy->pMhwRenderInterface;
1539         pRenderHalLegacy->SipStateParams.bSipKernel = true;
1540         pRenderHalLegacy->SipStateParams.dwSipBase  = pSipMemoryBlock->dwDataOffset;
1541         eStatus = pMhwRender->AddSipStateCmd(pCmdBuffer, &pRenderHalLegacy->SipStateParams);
1542     }
1543     else
1544     {   // Fail - SIP kernel not loaded
1545         eStatus = MOS_STATUS_UNKNOWN;
1546     }
1547 
1548 finish:
1549     return eStatus;
1550 }
1551 //!
1552 //! \brief    Allocate Media ID
1553 //! \details  Allocates an setup Interface Descriptor for Media Pipeline
1554 //!           Kernel        must be preloaded using pfnLoadKernel
1555 //!           Curbe         must be allocated using pfnAllocateCurbe
1556 //!           Binding Table must be allocated using pfnAllocateBindingTable
1557 //! \param    PRENDERHAL_INTERFACE pRenderHal
1558 //!           [in] Pointer to Hardware Interface Structure
1559 //! \param    int32_t iKernelAllocationID
1560 //!           [in] Kernel Allocation ID
1561 //! \param    int32_t iBindingTableID
1562 //!           [in] Binding Table ID
1563 //! \param    int32_t iCurbeOffset
1564 //!           [in] Curbe Offset (from Curbe base)
1565 //! \param    int32_t iCurbeLength
1566 //!           [in] Curbe Length
1567 //! \param    int32_t iCrsThrdConstDataLn
1568 //!           [in] Cross Thread constant data length
1569 //! \param    PMHW_GPGPU_WALKER_PARAMS pGpGpuWalkerParams
1570 //!           [in] Pointer to GpGpu Walker Params
1571 //! \return   int32_t
1572 //!           Media Interface descriptor ID
1573 //!           -1 if invalid parameters, no ID entry available in GSH
1574 //!
RenderHal_DSH_AllocateDynamicMediaID(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_KRN_ALLOCATION pKernelAllocation,int32_t iBindingTableID,int32_t iCurbeOffset,int32_t iCurbeLength,int32_t iCrsThrdConstDataLn,PMHW_GPGPU_WALKER_PARAMS pGpGpuWalkerParams)1575 int32_t RenderHal_DSH_AllocateDynamicMediaID(
1576     PRENDERHAL_INTERFACE        pRenderHal,
1577     PRENDERHAL_KRN_ALLOCATION   pKernelAllocation,
1578     int32_t                     iBindingTableID,
1579     int32_t                     iCurbeOffset,
1580     int32_t                     iCurbeLength,
1581     int32_t                     iCrsThrdConstDataLn,
1582     PMHW_GPGPU_WALKER_PARAMS    pGpGpuWalkerParams)
1583 {
1584     PRENDERHAL_MEDIA_STATE_LEGACY   pMediaState;
1585     PRENDERHAL_DYNAMIC_STATE        pDynamicState;
1586     PRENDERHAL_KRN_ALLOCATION       *pKrnAllocationTable;
1587     int32_t                         iCurbeSize;
1588     int32_t                         iInterfaceDescriptor;
1589     RENDERHAL_INTERFACE_DESCRIPTOR_PARAMS InterfaceDescriptorParams;
1590 
1591     iInterfaceDescriptor = -1;
1592 
1593     // Validate Renderhal and state heap
1594     if (pRenderHal == nullptr || pRenderHal->pStateHeap == nullptr)
1595     {
1596         MHW_RENDERHAL_ASSERTMESSAGE("Invalid State.");
1597         goto finish;
1598     }
1599 
1600     // Obtain pointer to current media state
1601     pMediaState = (PRENDERHAL_MEDIA_STATE_LEGACY)pRenderHal->pStateHeap->pCurMediaState;
1602     if (pMediaState == nullptr || pMediaState->pDynamicState == nullptr)
1603     {
1604         MHW_RENDERHAL_ASSERTMESSAGE("Invalid Media State.");
1605         goto finish;
1606     }
1607 
1608     // Obtain pointer to dynamic media state
1609     pDynamicState = pMediaState->pDynamicState;
1610 
1611     // Validate kernel allocation ID (kernel must be pre-loaded into GSH)
1612     if (pKernelAllocation == nullptr            ||                      // Allocation must be valid
1613         pKernelAllocation->pMemoryBlock == nullptr ||                      // Kernel must be loaded
1614         //pKernelAllocation->dwFlags == RENDERHAL_KERNEL_ALLOCATION_FREE ||  kernel may be reused
1615         pKernelAllocation->iSize == 0)                                  // Size must be valid
1616     {
1617         MHW_RENDERHAL_ASSERTMESSAGE("Invalid Kernel Allocation");
1618         goto finish;
1619     }
1620 
1621     // Check Curbe allocation (CURBE_Lenght is in 256-bit count -> convert to bytes)
1622     iCurbeSize = iCurbeLength;
1623     if (iCurbeSize <= 0)
1624     {
1625         // Curbe is not used by the kernel
1626         iCurbeSize = iCurbeOffset = 0;
1627     }
1628     // Validate Curbe Offset (curbe must be pre-allocated)
1629     else if ( iCurbeOffset < 0 ||                                           // Not allocated
1630              (iCurbeOffset & 0x1F) != 0 ||                                  // Invalid alignment
1631              (iCurbeOffset + iCurbeSize) > pDynamicState->Curbe.iCurrent)   // Invalid size
1632     {
1633         MHW_RENDERHAL_ASSERTMESSAGE("Invalid Curbe Allocation.");
1634         goto finish;
1635     }
1636 
1637     // Try to reuse interface descriptor (for 2nd level buffer optimizations)
1638     // Check if ID already in use by another kernel - must use a different ID
1639     pKrnAllocationTable  = pDynamicState->pKrnAllocations;
1640     iInterfaceDescriptor = pKernelAllocation->iKID;
1641     if (iInterfaceDescriptor >= 0 &&                                            // If kernel has a preferred interface descriptor
1642         pKrnAllocationTable[iInterfaceDescriptor] != pKernelAllocation)         // AND the interface descriptor is used by another kernel ....
1643     {
1644         iInterfaceDescriptor = -1;                                              // Choose another media interface descriptor
1645     }
1646 
1647     // Search available ID in current media state heap
1648     if (iInterfaceDescriptor < 0)
1649     {
1650         int32_t iMax = pDynamicState->MediaID.iCount;
1651         for (iInterfaceDescriptor = 0;
1652              iInterfaceDescriptor < iMax;
1653              iInterfaceDescriptor++)
1654         {
1655             if (pKrnAllocationTable[iInterfaceDescriptor] == nullptr)
1656             {
1657                 break;
1658             }
1659         }
1660 
1661         // All IDs are in use - fail
1662         if (iInterfaceDescriptor >= iMax)
1663         {
1664             MHW_RENDERHAL_ASSERTMESSAGE("No Interface Descriptor available.");
1665             iInterfaceDescriptor = -1;
1666             goto finish;
1667         }
1668     }
1669 
1670     if (iInterfaceDescriptor >= pDynamicState->MediaID.iCount)
1671     {
1672         MHW_RENDERHAL_ASSERTMESSAGE("Invalid Interface Descriptor.");
1673         iInterfaceDescriptor = -1;
1674         goto finish;
1675     }
1676 
1677     MOS_ZeroMemory((void *)&InterfaceDescriptorParams, sizeof(InterfaceDescriptorParams));
1678 
1679     InterfaceDescriptorParams.iMediaID            = iInterfaceDescriptor;
1680     InterfaceDescriptorParams.iBindingTableID     = iBindingTableID;
1681     InterfaceDescriptorParams.iCurbeOffset        = iCurbeOffset;
1682     InterfaceDescriptorParams.iCurbeLength        = iCurbeLength;
1683     InterfaceDescriptorParams.iCrsThrdConstDataLn = iCrsThrdConstDataLn;
1684 
1685     // barrier and slm
1686     if (pGpGpuWalkerParams && pGpGpuWalkerParams->GpGpuEnable)
1687     {
1688         InterfaceDescriptorParams.blBarrierEnable = true;
1689         InterfaceDescriptorParams.iNumberThreadsInGroup = pGpGpuWalkerParams->ThreadWidth * pGpGpuWalkerParams->ThreadHeight;
1690         InterfaceDescriptorParams.iSLMSize = pGpGpuWalkerParams->SLMSize; // The shift will be handled by pfnEncodeSLMSize()
1691         InterfaceDescriptorParams.blGlobalBarrierEnable = false;   // BDW+, default is 0
1692     }
1693     else //Reset barrier and slm setting since they may be set before
1694     {
1695         InterfaceDescriptorParams.blBarrierEnable = false;
1696         InterfaceDescriptorParams.iNumberThreadsInGroup = pRenderHal->dwMinNumberThreadsInGroup;
1697         InterfaceDescriptorParams.iSLMSize = 0;
1698         InterfaceDescriptorParams.iCrsThrdConstDataLn &= pRenderHal->dwMaskCrsThdConDataRdLn;
1699         InterfaceDescriptorParams.blGlobalBarrierEnable = false;   // BDW+, default is 0
1700     }
1701 
1702     // Setup Media ID entry - this call could be HW dependent
1703     if (MOS_STATUS_SUCCESS != pRenderHal->pfnSetupInterfaceDescriptor(
1704                                              pRenderHal,
1705                                              pMediaState,
1706                                              pKernelAllocation,
1707                                              &InterfaceDescriptorParams))
1708     {
1709         MHW_RENDERHAL_ASSERTMESSAGE("Failed to setup Interface Descriptor.");
1710         iInterfaceDescriptor = -1;
1711         goto finish;
1712     }
1713 
1714     // Set kernel allocation for the current Media ID
1715     pKrnAllocationTable[iInterfaceDescriptor] = pKernelAllocation;
1716 
1717     // Set preferred Media ID for the current kernel
1718     // This is necessary for 2nd level BB optimization.
1719     if (pKernelAllocation->iKID < 0)
1720     {
1721         pKernelAllocation->iKID = iInterfaceDescriptor;
1722     }
1723 
1724     // Update kernel usage
1725     pRenderHal->pfnTouchDynamicKernel(pRenderHal, pKernelAllocation);
1726 
1727 finish:
1728     return iInterfaceDescriptor;
1729 }
1730 
1731 //!
1732 //! \brief    Get a media ID
1733 //! \details  Returns an interface descriptor for this media state
1734 //!           sets kernel allocation for the media ID
1735 //! \param    PRENDERHAL_INTERFACE pRenderHal
1736 //!           [in] Pointer to the renderhal interface
1737 //! \param    PRENDERHAL_MEDIA_STATE pMediaState
1738 //!           [in] Pointer to the media state
1739 //! \param    PRENDERHAL_KRN_ALLOCATION   pKernelAllocation
1740 //!           [in] Pointer to the kernel allocation
1741 //! \return   int32_t mediaID
1742 //!
RenderHal_DSH_GetMediaID(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_MEDIA_STATE pMediaState,PRENDERHAL_KRN_ALLOCATION pKernelAllocation)1743 int32_t RenderHal_DSH_GetMediaID(
1744     PRENDERHAL_INTERFACE        pRenderHal,
1745     PRENDERHAL_MEDIA_STATE      pMediaState,
1746     PRENDERHAL_KRN_ALLOCATION   pKernelAllocation)
1747 {
1748     PRENDERHAL_KRN_ALLOCATION    *pKrnAllocations;
1749     int32_t                       iInterfaceDescriptor = -1;
1750     MOS_STATUS                    eStatus = MOS_STATUS_UNKNOWN;
1751     PRENDERHAL_MEDIA_STATE_LEGACY pMediaStateLegacy = (PRENDERHAL_MEDIA_STATE_LEGACY)pMediaState;
1752 
1753     MHW_RENDERHAL_CHK_NULL(pMediaStateLegacy);
1754     MHW_RENDERHAL_CHK_NULL(pMediaStateLegacy->pDynamicState);
1755     MHW_RENDERHAL_CHK_NULL(pMediaStateLegacy->pDynamicState->pKrnAllocations);
1756     MHW_RENDERHAL_CHK_NULL(pKernelAllocation);
1757 
1758     iInterfaceDescriptor = pKernelAllocation->iKID;
1759     pKrnAllocations      = pMediaStateLegacy->pDynamicState->pKrnAllocations;
1760 
1761     // Try to reuse interface descriptor (for 2nd level buffer optimizations)
1762     // Check if ID already in use by another kernel - must use a different ID
1763     if (iInterfaceDescriptor >= 0 &&
1764         pKrnAllocations[iInterfaceDescriptor] != nullptr &&
1765         pKrnAllocations[iInterfaceDescriptor] != pKernelAllocation)
1766     {
1767         iInterfaceDescriptor = -1;
1768     }
1769 
1770     // Search available ID in current media state heap
1771     if (iInterfaceDescriptor < 0)
1772     {
1773         int32_t iMax = pMediaStateLegacy->pDynamicState->MediaID.iCount;
1774         for (iInterfaceDescriptor = 0;
1775              iInterfaceDescriptor < iMax;
1776              iInterfaceDescriptor++)
1777         {
1778             if (pKrnAllocations[iInterfaceDescriptor] == nullptr)
1779             {
1780                 break;
1781             }
1782         }
1783 
1784         // All IDs are in use - fail
1785         if (iInterfaceDescriptor >= iMax)
1786         {
1787             MHW_RENDERHAL_ASSERT("No Interface Descriptor available.");
1788             iInterfaceDescriptor = -1;
1789             goto finish;
1790         }
1791     }
1792 
1793     // Set kernel allocation for the current Media ID
1794     pKrnAllocations[iInterfaceDescriptor] = pKernelAllocation;
1795 
1796     // Set preferred Media ID for the current kernel
1797     // This is necessary for 2nd level BB optimization.
1798     if (pKernelAllocation->iKID < 0)
1799     {
1800         pKernelAllocation->iKID = iInterfaceDescriptor;
1801     }
1802 
1803 finish:
1804     return iInterfaceDescriptor;
1805 }
1806 
1807 //!
1808 //! \brief    Assign Dynamic Media State
1809 //! \details  Gets a pointer to the next available media state in GSH;
1810 //!           fails if not available
1811 //! \param    PRENDERHAL_INTERFACE pRenderHal
1812 //!           [in] Pointer to Hadrware Interface Structure
1813 //! \param    PRENDERHAL_INTERFACE pRenderHal
1814 //!           [in] Pointer to Hadrware Interface Structure
1815 //! \param    RENDERHAL_COMPONENT componentID
1816 //!           [in] Identifier of the requesting component
1817 //! \return   PRENDERHAL_MEDIA_STATE
1818 //!           gets a new Media State, returns pointer to Media State structure
1819 //!           nullptr - invalid, no states available + timeout
1820 //!
RenderHal_DSH_AssignDynamicState(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_DYNAMIC_MEDIA_STATE_PARAMS pParams,RENDERHAL_COMPONENT componentID)1821 PRENDERHAL_MEDIA_STATE RenderHal_DSH_AssignDynamicState(
1822     PRENDERHAL_INTERFACE                  pRenderHal,
1823     PRENDERHAL_DYNAMIC_MEDIA_STATE_PARAMS pParams,
1824     RENDERHAL_COMPONENT                   componentID)
1825 {
1826     MHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS Params;              // Block allocation parameters
1827     PRENDERHAL_MEDIA_STATE_LEGACY       pMediaState = nullptr;  // Media state structure
1828     PRENDERHAL_DYNAMIC_STATE            pDynamicState;       // Dynamic media state structure
1829     PXMHW_STATE_HEAP_INTERFACE          pMhwStateHeap;
1830     PMHW_RENDER_STATE_SIZES             pHwSizes;
1831     MOS_STATUS                          eStatus = MOS_STATUS_SUCCESS;
1832     uint32_t                            dwSizeMediaState = 0;
1833     uint32_t                            dwMediaStateAlign;
1834     uint32_t                            dwSamplerStateAlign;
1835     uint8_t                             *pCurrentPtr;
1836     uint8_t                             *performanceMemory = nullptr;
1837     uint32_t                            performanceSize;
1838     uint32_t                            currentExtendSize = 0;
1839     PRENDERHAL_INTERFACE_LEGACY         pRenderHalLegacy = (PRENDERHAL_INTERFACE_LEGACY)pRenderHal;
1840 
1841     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy);
1842     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pStateHeap);
1843     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pMhwStateHeap);
1844     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pOsInterface);
1845 
1846     // Assign new media state (get from pool)
1847     pMediaState = (PRENDERHAL_MEDIA_STATE_LEGACY)RenderHal_DSH_GetMediaStateFromPool(pRenderHalLegacy->pStateHeap);
1848     MHW_RENDERHAL_CHK_NULL(pMediaState);
1849     MHW_RENDERHAL_CHK_NULL(pMediaState->pDynamicState);
1850 
1851     // Get pointer to state heap interface
1852     pMhwStateHeap = pRenderHalLegacy->pMhwStateHeap;
1853 
1854     // Get hw structure sizes
1855     pHwSizes = pRenderHalLegacy->pHwSizes;
1856 
1857     // Point to dynamic state
1858     pDynamicState = pMediaState->pDynamicState;
1859     MOS_ZeroMemory(pDynamicState, sizeof(RENDERHAL_DYNAMIC_STATE));
1860 
1861     // Reset some states
1862     pMediaState->bBusy = false; // will be busy after submission
1863 
1864     // Setup parameters
1865     pDynamicState->Curbe.dwOffset = dwSizeMediaState;
1866     pDynamicState->Curbe.dwSize   = (uint32_t)MOS_MAX(pParams->iMaxCurbeSize, pParams->iMaxCurbeOffset);
1867 
1868     // Align media state for CURBE
1869     dwMediaStateAlign = pRenderHalLegacy->dwCurbeBlockAlign;
1870     dwSizeMediaState  = MOS_ALIGN_CEIL(pDynamicState->Curbe.dwSize, dwMediaStateAlign);
1871 
1872     // Align media states for Samplers
1873     dwSamplerStateAlign = MHW_SAMPLER_STATE_ALIGN;
1874     dwSizeMediaState    = MOS_ALIGN_CEIL(dwSizeMediaState, dwSamplerStateAlign);
1875 
1876     // Allocate Samplers
1877     if (pRenderHalLegacy->bHasCombinedAVSSamplerState == false)
1878     {
1879         uint32_t dwSamplerSize = 0;
1880 
1881         // This is needed regardless of 3D samplers
1882         /// Used to calculate offset to sampler area during interface descriptor setup
1883         pDynamicState->Sampler3D.dwOffset = dwSizeMediaState;
1884 
1885         // 3D Sampler states
1886         if (pParams->iMaxSamplerIndex3D > 0)
1887         {
1888             pDynamicState->Sampler3D.iCount   = pParams->iMaxSamplerIndex3D;
1889             pDynamicState->Sampler3D.dwSize   = MOS_ALIGN_CEIL(pParams->iMaxSamplerIndex3D * pHwSizes->dwSizeSamplerState,  MHW_SAMPLER_STATE_ALIGN);
1890             dwSamplerSize                     = pDynamicState->Sampler3D.dwSize;
1891         }
1892 
1893         // AVS sampler states (colocated with 3D => make sure the area is large enough for both)
1894         if (pParams->iMaxSamplerIndexAVS > 0)
1895         {
1896             pDynamicState->SamplerAVS.dwOffset = dwSizeMediaState;
1897             pDynamicState->SamplerAVS.iCount   = pParams->iMaxSamplerIndexAVS;
1898             pDynamicState->SamplerAVS.dwSize   = MOS_ALIGN_CEIL(pParams->iMaxSamplerIndexAVS * pHwSizes->dwSizeSamplerStateAvs,  MHW_SAMPLER_STATE_ALIGN);
1899             dwSamplerSize                      = MOS_MAX(dwSamplerSize, pDynamicState->SamplerAVS.dwSize);
1900         }
1901 
1902         // Sampler Indirect State (border color associated with each 3D sampler)
1903         if (pParams->iMaxSamplerIndex3D > 0)
1904         {
1905             pDynamicState->SamplerInd.dwOffset = MOS_ALIGN_CEIL(dwSizeMediaState + dwSamplerSize, MHW_SAMPLER_STATE_ALIGN);
1906             pDynamicState->SamplerInd.iCount   = pParams->iMaxSamplerIndex3D;
1907             pDynamicState->SamplerInd.dwSize   = MOS_ALIGN_CEIL(pParams->iMaxSamplerIndex3D * pHwSizes->dwSizeSamplerIndirectState, MHW_SAMPLER_STATE_ALIGN);
1908             dwSamplerSize                     += pDynamicState->SamplerInd.dwSize;
1909         }
1910 
1911         pDynamicState->dwSizeSamplers = dwSamplerSize = MOS_ALIGN_CEIL(dwSamplerSize, dwSamplerStateAlign);
1912         dwSamplerSize *= pParams->iMaxMediaIDs;     // Move tables to end of all sampler states
1913 
1914         // 8x8 tables
1915         if (pParams->iMax8x8Tables > 0)
1916         {
1917             pDynamicState->Table8x8.dwOffset   = MOS_ALIGN_CEIL(dwSizeMediaState + dwSamplerSize, MHW_SAMPLER_STATE_ALIGN);
1918             pDynamicState->Table8x8.iCount     = pParams->iMax8x8Tables;
1919             pDynamicState->Table8x8.dwSize     = MOS_ALIGN_CEIL(pHwSizes->dwSizeSamplerStateTable8x8,  MHW_SAMPLER_STATE_ALIGN);
1920             dwSamplerSize                     += pParams->iMax8x8Tables * pDynamicState->Table8x8.dwSize;
1921        }
1922 
1923         dwSamplerSize     = MOS_ALIGN_CEIL(dwSamplerSize, dwSamplerStateAlign);
1924         dwSizeMediaState += dwSamplerSize;
1925     }
1926     else
1927     {
1928         uint32_t dwSamplerSize = 0;
1929 
1930         // common base for all sampler types
1931         pDynamicState->Sampler3D  .dwOffset = dwSizeMediaState;
1932         pDynamicState->SamplerAVS .dwOffset = dwSizeMediaState;
1933         pDynamicState->SamplerConv.dwOffset = dwSizeMediaState;
1934         pDynamicState->SamplerMisc.dwOffset = dwSizeMediaState;
1935 
1936         // 3D sampler
1937         pDynamicState->Sampler3D.iCount = pParams->iMaxSamplerIndex3D;
1938         pDynamicState->Sampler3D.dwSize = pParams->iMaxSamplerIndex3D * pHwSizes->dwSizeSamplerState;
1939 
1940         // Misc (VA) sampler
1941         if (pParams->iMaxSamplerIndexMisc > 0)
1942         {
1943             dwSamplerStateAlign = MOS_MAX(dwMediaStateAlign, MHW_SAMPLER_STATE_VA_ALIGN);
1944             pDynamicState->SamplerMisc.iCount = pParams->iMaxSamplerIndexMisc;
1945             pDynamicState->SamplerMisc.dwSize = pParams->iMaxSamplerIndexMisc * pHwSizes->dwSizeSamplerStateVA;
1946         }
1947 
1948         // AVS sampler
1949         if (pParams->iMaxSamplerIndexAVS > 0)
1950         {
1951             uint32_t dwAlign = GFX_IS_GEN_9_OR_LATER(pRenderHalLegacy->Platform) ? MHW_SAMPLER_STATE_AVS_ALIGN_G9 : MHW_SAMPLER_STATE_AVS_ALIGN;
1952             uint32_t dwInc   = pRenderHalLegacy->pMhwRenderInterface->GetSamplerStateAVSIncUnit();
1953 
1954             dwSamplerStateAlign = MOS_MAX(dwMediaStateAlign, dwAlign);
1955             pDynamicState->SamplerAVS.iCount = pParams->iMaxSamplerIndexAVS;
1956             pDynamicState->SamplerAVS.dwSize = (pParams->iMaxSamplerIndexAVS - 1) * dwInc + pHwSizes->dwSizeSamplerStateAvs;
1957         }
1958 
1959         // Conv sampler
1960         if (pParams->iMaxSamplerIndexConv > 0)
1961         {
1962             uint32_t dwAlign = GFX_IS_GEN_9_OR_LATER(pRenderHalLegacy->Platform) ? MHW_SAMPLER_STATE_AVS_ALIGN_G9 : MHW_SAMPLER_STATE_AVS_ALIGN;
1963             uint32_t dwInc   = pRenderHalLegacy->pMhwRenderInterface->GetSamplerStateConvIncUnit();
1964 
1965             dwSamplerStateAlign = MOS_MAX(dwMediaStateAlign, dwAlign);
1966             pDynamicState->SamplerConv.iCount = pParams->iMaxSamplerIndexConv;
1967             pDynamicState->SamplerConv.dwSize = (pParams->iMaxSamplerIndexConv - 1) * dwInc + pHwSizes->dwSizeSamplerStateVAConvolve;
1968         }
1969 
1970         // Get largest of all
1971         dwSamplerSize = MOS_MAX(pDynamicState->Sampler3D.dwSize, pDynamicState->SamplerMisc.dwSize);
1972         dwSamplerSize = MOS_MAX(pDynamicState->SamplerAVS.dwSize, dwSamplerSize);
1973         dwSamplerSize = MOS_MAX(pDynamicState->SamplerConv.dwSize, dwSamplerSize);
1974 
1975         // Sampler Indirect State (border color associated with each 3D sampler)
1976         if (pParams->iMaxSamplerIndex3D > 0)
1977         {
1978             dwSamplerSize                      = MOS_ALIGN_CEIL(dwSamplerSize, MHW_SAMPLER_STATE_ALIGN);
1979             pDynamicState->SamplerInd.dwOffset = dwSizeMediaState + dwSamplerSize;
1980             pDynamicState->SamplerInd.iCount   = pParams->iMaxSamplerIndex3D;
1981             pDynamicState->SamplerInd.dwSize   = pParams->iMaxSamplerIndex3D * pHwSizes->dwSizeSamplerIndirectState;
1982             dwSamplerSize                     += pDynamicState->SamplerInd.dwSize;
1983         }
1984 
1985         dwSamplerSize = MOS_ALIGN_CEIL(dwSamplerSize, dwSamplerStateAlign);
1986 
1987         pDynamicState->dwSizeSamplers = dwSamplerSize;
1988         dwSizeMediaState += pParams->iMaxMediaIDs * pDynamicState->dwSizeSamplers;
1989     }
1990 
1991     // Interface Descriptors
1992     pDynamicState->MediaID.iCount   = pParams->iMaxMediaIDs;
1993     pDynamicState->MediaID.dwOffset = dwSizeMediaState;
1994     pDynamicState->MediaID.dwSize   = pParams->iMaxMediaIDs * pHwSizes->dwSizeInterfaceDescriptor;
1995     dwSizeMediaState               += pDynamicState->MediaID.dwSize;
1996 
1997     // Area for Performance collection
1998     pDynamicState->Performance.iCount   = 1;
1999     pDynamicState->Performance.dwOffset = dwSizeMediaState;
2000     pDynamicState->Performance.dwSize   = 64;
2001     dwSizeMediaState                   += pDynamicState->Performance.dwSize;
2002 
2003     // Kernel Spill Area
2004     if (pParams->iMaxSpillSize > 0)
2005     {
2006         // per thread scratch space must be 1K*(2^n), (2K*(2^n) for BDW A0), alignment is 1kB
2007         int iPerThreadScratchSpace = 0;
2008         if (pRenderHalLegacy->pfnPerThreadScratchSpaceStart2K(pRenderHalLegacy))
2009         {
2010             iPerThreadScratchSpace = 2048;
2011         }
2012         else if (pRenderHalLegacy->pRenderHalPltInterface
2013                  ->PerThreadScratchSpaceStart64Byte(pRenderHalLegacy))
2014         {
2015             iPerThreadScratchSpace = 64;
2016         }
2017         else
2018         {
2019             iPerThreadScratchSpace = 1024;
2020         }
2021 
2022         for (iPerThreadScratchSpace; iPerThreadScratchSpace < pParams->iMaxSpillSize; iPerThreadScratchSpace <<= 1);
2023         pDynamicState->iMaxScratchSpacePerThread = pParams->iMaxSpillSize
2024                 = iPerThreadScratchSpace;
2025 
2026         MOS_STATUS result = pRenderHalLegacy->pRenderHalPltInterface
2027             ->AllocateScratchSpaceBuffer(iPerThreadScratchSpace, pRenderHalLegacy);
2028         if (MOS_STATUS_UNIMPLEMENTED == result)  // Scratch space buffer is not supported
2029         {
2030             pDynamicState->dwScratchSpace
2031                     = pRenderHalLegacy->pfnGetScratchSpaceSize(pRenderHalLegacy,
2032                                                          iPerThreadScratchSpace);
2033             pDynamicState->scratchSpaceOffset = dwSizeMediaState;
2034 
2035             // Allocate more 1k space in state heap, which is used to make scratch space offset 1k-aligned.
2036             dwSizeMediaState += pDynamicState->dwScratchSpace + MHW_SCRATCH_SPACE_ALIGN;
2037             currentExtendSize = pRenderHalLegacy->dgsheapManager->GetExtendSize();
2038             if (currentExtendSize < pDynamicState->dwScratchSpace)
2039             {
2040                 // update extend size for scratch space
2041                 MHW_RENDERHAL_CHK_STATUS(
2042                     pRenderHalLegacy->dgsheapManager->SetExtendHeapSize(
2043                         pDynamicState->dwScratchSpace));
2044             }
2045         }
2046         else
2047         {
2048             MHW_RENDERHAL_CHK_STATUS(result);
2049         }
2050     }
2051 
2052     // Use generic heap manager to allocate memory block for dynamic general state heap
2053     MHW_RENDERHAL_CHK_STATUS(pRenderHalLegacy->pfnAssignSpaceInStateHeap(
2054         pRenderHalLegacy->currentTrackerIndex,
2055         &pRenderHalLegacy->trackerProducer,
2056         pRenderHalLegacy->dgsheapManager,
2057         &pDynamicState->memoryBlock,
2058         dwSizeMediaState));
2059 
2060     if (pParams->iMaxSpillSize > 0 && currentExtendSize > 0)
2061     {
2062         // Restore original extend heap size
2063         MHW_RENDERHAL_CHK_STATUS(
2064             pRenderHalLegacy->dgsheapManager->SetExtendHeapSize(
2065                 currentExtendSize));
2066 
2067         // Specifies the 1k-byte aligned address offset to scratch space for
2068         // use by the kernel.  This pointer is relative to the
2069         // General State Base Address (1k aligned)
2070         // Format = GeneralStateOffset[31:10]
2071         pDynamicState->scratchSpaceOffset += pDynamicState->memoryBlock.GetOffset();
2072         pDynamicState->scratchSpaceOffset = MOS_ALIGN_CEIL(pDynamicState->scratchSpaceOffset, MHW_SCRATCH_SPACE_ALIGN);
2073     }
2074 
2075     // set the sync tag for the media state
2076     FrameTrackerTokenFlat_SetProducer(&pMediaState->trackerToken, &pRenderHalLegacy->trackerProducer);
2077     FrameTrackerTokenFlat_Merge(&pMediaState->trackerToken,
2078                                 pRenderHalLegacy->currentTrackerIndex,
2079                                 pRenderHalLegacy->trackerProducer.GetNextTracker(pRenderHalLegacy->currentTrackerIndex));
2080 
2081     // Reset HW allocations
2082     pRenderHalLegacy->iChromaKeyCount = 0;
2083     for (int32_t i = 0; i < pRenderHalLegacy->iMaxPalettes; i++)
2084     {
2085         pRenderHalLegacy->Palette[i].iNumEntries = 0;
2086     }
2087 
2088     // Zero Memory start time and end time
2089     performanceSize = (sizeof(uint64_t) * 2) + sizeof(RENDERHAL_COMPONENT);
2090     performanceMemory = (uint8_t*)MOS_AllocAndZeroMemory(performanceSize);
2091     pCurrentPtr = performanceMemory;
2092     pCurrentPtr += (sizeof(uint64_t) * 2);
2093     *((RENDERHAL_COMPONENT *)pCurrentPtr) = componentID;
2094     MHW_RENDERHAL_CHK_STATUS(pDynamicState->memoryBlock.AddData(
2095         performanceMemory,
2096         pDynamicState->Performance.dwOffset,
2097         performanceSize));
2098 
2099 finish:
2100 
2101     MOS_SafeFreeMemory(performanceMemory);
2102 
2103     if (eStatus == MOS_STATUS_SUCCESS)
2104     {
2105         if (pRenderHalLegacy && pRenderHalLegacy->pStateHeap)
2106         {
2107             pRenderHalLegacy->pStateHeap->pCurMediaState = pMediaState;
2108         }
2109 
2110         if (pRenderHalLegacy)
2111         {
2112             // Refresh sync tag for all media states in submitted queue
2113             pRenderHalLegacy->pfnRefreshSync(pRenderHalLegacy);
2114         }
2115     }
2116     else
2117     {
2118         RenderHal_DSH_ReturnMediaStateToPool(pRenderHalLegacy->pStateHeap, pMediaState);
2119         pMediaState = nullptr;
2120     }
2121 
2122     return pMediaState;
2123 }
2124 
2125 //!
2126 //! \brief    Releases the dynamic state
2127 //! \details  Returns the media state to the pool
2128 //! \param    PRENDERHAL_INTERFACE pRenderHal
2129 //!           [in] Pointer to renderhal interface
2130 //! \param    PRENDERHAL_MEDIA_STATE pMediaState
2131 //!           [in] Pointer to media state
2132 //! \return   MOS_STATUS
2133 //!
RenderHal_DSH_ReleaseDynamicState(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_MEDIA_STATE pMediaState)2134 MOS_STATUS RenderHal_DSH_ReleaseDynamicState(
2135     PRENDERHAL_INTERFACE   pRenderHal,
2136     PRENDERHAL_MEDIA_STATE pMediaState)
2137 {
2138     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2139 
2140     MHW_RENDERHAL_CHK_NULL(pRenderHal);
2141     MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap);
2142     MHW_RENDERHAL_CHK_NULL(pMediaState);
2143 
2144     // Media state cannot be busy or attached to any list (free/submitted)
2145     if (pMediaState->bBusy || pMediaState->pNext || pMediaState->pPrev)
2146     {
2147         MHW_RENDERHAL_ASSERTMESSAGE("Invalid Media State object");
2148         eStatus = MOS_STATUS_INVALID_PARAMETER;
2149         goto finish;
2150     }
2151 
2152     // Return media state to pool for reuse
2153     RenderHal_DSH_ReturnMediaStateToPool(pRenderHal->pStateHeap, pMediaState);
2154 
2155 finish:
2156     return eStatus;
2157 }
2158 
2159 //!
2160 //! \brief    Submit the dynamic state
2161 //! \details  Move memory block to the submitted queue
2162 //!           Updates the sync tag for the scratch space
2163 //! \param    PRENDERHAL_INTERFACE pRenderHal
2164 //!           [in] Pointer to renderhal interface
2165 //! \param    PRENDERHAL_MEDIA_STATE pMediaState
2166 //!           [in] Pointer to media state
2167 //! \return   MOS_STATUS
2168 //!
RenderHal_DSH_SubmitDynamicState(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_MEDIA_STATE pMediaState)2169 MOS_STATUS RenderHal_DSH_SubmitDynamicState(
2170     PRENDERHAL_INTERFACE   pRenderHal,
2171     PRENDERHAL_MEDIA_STATE pMediaState)
2172 {
2173     PRENDERHAL_MEDIA_STATE_LIST pList;
2174     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2175     std::vector<MemoryBlock> blocks;
2176     PRENDERHAL_MEDIA_STATE_LEGACY pMediaStateLegacy = (PRENDERHAL_MEDIA_STATE_LEGACY)pMediaState;
2177 
2178     MHW_RENDERHAL_CHK_NULL(pRenderHal);
2179     MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap);
2180     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwStateHeap);
2181     MHW_RENDERHAL_CHK_NULL(pMediaStateLegacy);
2182     MHW_RENDERHAL_CHK_NULL(pMediaStateLegacy->pDynamicState);
2183 
2184     // Media state cannot be attached to any list (free/submitted)
2185     if (pMediaStateLegacy->pNext || pMediaStateLegacy->pPrev)
2186     {
2187         MHW_RENDERHAL_ASSERTMESSAGE("Invalid Media State object");
2188         eStatus = MOS_STATUS_INVALID_PARAMETER;
2189         goto finish;
2190     }
2191 
2192     // Flag as busy (should be already)
2193     pMediaStateLegacy->bBusy = true;
2194 
2195     blocks.push_back(pMediaStateLegacy->pDynamicState->memoryBlock);
2196     MHW_RENDERHAL_CHK_STATUS(pRenderHal->dgsheapManager->SubmitBlocks(blocks));
2197 
2198     // Attached to end of submitted queue (media state in execution queue)
2199     pList = &pRenderHal->pStateHeap->SubmittedStates;
2200 
2201     pMediaStateLegacy->pPrev = pList->pTail;
2202     pList->pTail = pMediaStateLegacy;
2203     if (pMediaStateLegacy->pPrev)
2204     {
2205         pMediaStateLegacy->pPrev->pNext = pMediaStateLegacy;
2206     }
2207     else
2208     {   // List was empty - insert first element
2209         MHW_ASSERT(pList->iCount == 0);
2210         pList->pHead = pMediaStateLegacy;
2211     }
2212     pList->iCount++;
2213 
2214 finish:
2215     return eStatus;
2216 }
2217 
2218 //!
2219 //! \brief    Load Curbe Data
2220 //! \details  Allocates and load CURBE data for Media
2221 //! \param    PRENDERHAL_INTERFACE pRenderHal
2222 //!           [in]  Pointer to RenderHal Interface structure
2223 //! \param    PRENDERHAL_MEDIA_STATE pCurMediaState
2224 //!           [out] Pointer to Current Media State structure
2225 //! \param    void  *pData
2226 //!           [in]  Pointer to Data
2227 //! \param    int32_t iSize
2228 //!           [in]  Number of bytes to allocate
2229 //! \return   int32_t
2230 //!           Offset of the CURBE block from CURBE base (in bytes)
2231 //!           -1 if no CURBE space available in GSH
2232 //!
RenderHal_DSH_LoadCurbeData(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_MEDIA_STATE pMediaState,void * pData,int32_t iSize)2233 int32_t RenderHal_DSH_LoadCurbeData(
2234     PRENDERHAL_INTERFACE    pRenderHal,
2235     PRENDERHAL_MEDIA_STATE  pMediaState,
2236     void                    *pData,
2237     int32_t                 iSize)
2238 {
2239     MOS_STATUS                    eStatus = MOS_STATUS_SUCCESS;
2240     int32_t                       iOffset;
2241     int32_t                       iCurbeSize;
2242     PRENDERHAL_DYNAMIC_STATE      pDynamicState;
2243     uint8_t*                      pRemainingCurbe;
2244     PRENDERHAL_MEDIA_STATE_LEGACY pMediaStateLegacy = (PRENDERHAL_MEDIA_STATE_LEGACY)pMediaState;
2245 
2246     iOffset         = -1;
2247     pRemainingCurbe =  nullptr;
2248 
2249     if (pRenderHal == nullptr || pMediaStateLegacy == nullptr || pData == nullptr)
2250     {
2251         MHW_RENDERHAL_ASSERTMESSAGE("Null pointer found.");
2252         eStatus = MOS_STATUS_INVALID_PARAMETER;
2253         goto finish;
2254     }
2255 
2256     if (pMediaStateLegacy && pMediaStateLegacy->pDynamicState)
2257     {
2258         // Check if dynamic state is valid
2259         pDynamicState = pMediaStateLegacy->pDynamicState;
2260         if (!pDynamicState->memoryBlock.IsValid())
2261         {
2262             goto finish;
2263         }
2264 
2265         iCurbeSize = MOS_ALIGN_CEIL(iSize, pRenderHal->dwCurbeBlockAlign);
2266         if (pDynamicState->Curbe.iCurrent + iCurbeSize <= (int)pDynamicState->Curbe.dwSize)
2267         {
2268             iOffset = pDynamicState->Curbe.iCurrent;
2269             pDynamicState->Curbe.iCurrent += iCurbeSize;
2270 
2271             if (pData)
2272             {
2273                 MHW_RENDERHAL_CHK_STATUS(pDynamicState->memoryBlock.AddData(
2274                     pData,
2275                     pDynamicState->Curbe.dwOffset + iOffset,
2276                     iSize));
2277 
2278                 // Zero remaining CURBE (for buffer alignment)
2279                 iCurbeSize -= iSize;
2280                 if (iCurbeSize > 0)
2281                 {
2282                     pRemainingCurbe = (uint8_t*)MOS_AllocAndZeroMemory(sizeof(uint8_t)*iCurbeSize);
2283                     MHW_RENDERHAL_CHK_STATUS(pDynamicState->memoryBlock.AddData(
2284                         pRemainingCurbe,
2285                         pDynamicState->Curbe.dwOffset + iOffset + iSize,
2286                         iCurbeSize));
2287                 }
2288             }
2289         }
2290     }
2291 
2292 finish:
2293     if(pRemainingCurbe)
2294     {
2295         MOS_SafeFreeMemory(pRemainingCurbe);
2296     }
2297 
2298     if (eStatus != MOS_STATUS_SUCCESS)
2299     {
2300         iOffset = -1;
2301     }
2302     return iOffset;
2303 }
2304 
2305 //!
2306 //! \brief    Send Curbe Load
2307 //! \details  Send Curbe Load command
2308 //! \param    PRENDERHAL_INTERFACE pRenderHal
2309 //!           [in] Pointer to Hardware Interface Structure
2310 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
2311 //!           [in] Pointer to Command Buffer
2312 //! \return   MOS_STATUS
2313 //!
RenderHal_DSH_SendCurbeLoad(PRENDERHAL_INTERFACE pRenderHal,PMOS_COMMAND_BUFFER pCmdBuffer)2314 MOS_STATUS RenderHal_DSH_SendCurbeLoad(
2315     PRENDERHAL_INTERFACE    pRenderHal,
2316     PMOS_COMMAND_BUFFER     pCmdBuffer)
2317 {
2318     MHW_CURBE_LOAD_PARAMS           CurbeLoadParams;
2319     PRENDERHAL_STATE_HEAP           pStateHeap;
2320     PRENDERHAL_MEDIA_STATE_LEGACY   pMediaState;
2321     PRENDERHAL_DYNAMIC_STATE        pDynamicState;
2322     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
2323     PRENDERHAL_INTERFACE_LEGACY     pRenderHalLegacy = (PRENDERHAL_INTERFACE_LEGACY)pRenderHal;
2324     //-----------------------------------------
2325     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy);
2326     MHW_RENDERHAL_CHK_NULL(pCmdBuffer);
2327     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pStateHeap);
2328     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pMhwRenderInterface);
2329     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pStateHeap->pCurMediaState);
2330     //-----------------------------------------
2331 
2332     pMediaState = (PRENDERHAL_MEDIA_STATE_LEGACY)pRenderHalLegacy->pStateHeap->pCurMediaState;
2333     MHW_RENDERHAL_CHK_NULL(pMediaState->pDynamicState);
2334 
2335     eStatus       = MOS_STATUS_SUCCESS;
2336     pStateHeap    = pRenderHalLegacy->pStateHeap;
2337     pDynamicState = pMediaState->pDynamicState;
2338 
2339     // CURBE size is in bytes
2340     if (pDynamicState->Curbe.iCurrent != 0)
2341     {
2342         CurbeLoadParams.pKernelState            = nullptr;
2343         CurbeLoadParams.bOldInterface           = false;
2344         CurbeLoadParams.dwCURBETotalDataLength  = pDynamicState->Curbe.iCurrent;
2345         CurbeLoadParams.dwCURBEDataStartAddress = pDynamicState->memoryBlock.GetOffset() +   // media state offset from GSH base
2346                                                   pDynamicState->Curbe.dwOffset;                // curbe data offset in media state
2347 
2348         MHW_RENDERHAL_CHK_STATUS(pRenderHalLegacy->pMhwRenderInterface->AddMediaCurbeLoadCmd(pCmdBuffer, &CurbeLoadParams));
2349     }
2350 
2351 finish:
2352     return eStatus;
2353 }
2354 
2355 //!
2356 //! \brief    Send state base address
2357 //! \details  Send state base address command
2358 //! \param    PRENDERHAL_INTERFACE pRenderHal
2359 //!           [in] Pointer to Hardware Interface Structure
2360 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
2361 //!           [in] Pointer to Command Buffer
2362 //! \return   MOS_STATUS
2363 //!
RenderHal_DSH_SendStateBaseAddress(PRENDERHAL_INTERFACE pRenderHal,PMOS_COMMAND_BUFFER pCmdBuffer)2364 MOS_STATUS RenderHal_DSH_SendStateBaseAddress(PRENDERHAL_INTERFACE pRenderHal, PMOS_COMMAND_BUFFER pCmdBuffer)
2365 {
2366     PRENDERHAL_STATE_HEAP       pStateHeap;
2367     PRENDERHAL_DYNAMIC_STATE    pDynamicState;
2368     PMOS_RESOURCE               pGshResource;
2369     uint32_t                    dwGshSize;
2370     PMOS_RESOURCE               pIshResource;
2371     uint32_t                    dwIshSize;
2372     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
2373     PRENDERHAL_INTERFACE_LEGACY pRenderHalLegacy = (PRENDERHAL_INTERFACE_LEGACY)pRenderHal;
2374 
2375     //----------------------------------------
2376     MHW_RENDERHAL_CHK_NULL(pCmdBuffer);
2377     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy);
2378     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pStateHeap);
2379     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pStateHeap->pCurMediaState);
2380     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pMhwStateHeap);
2381     MHW_RENDERHAL_CHK_NULL(pRenderHalLegacy->pMhwRenderInterface);
2382     //----------------------------------------
2383 
2384     pStateHeap    = pRenderHalLegacy->pStateHeap;
2385     pDynamicState = ((PRENDERHAL_MEDIA_STATE_LEGACY)pStateHeap->pCurMediaState)->pDynamicState;
2386 
2387     MHW_RENDERHAL_CHK_NULL(pDynamicState);
2388 
2389     pGshResource  = pDynamicState->memoryBlock.GetResource();
2390     dwGshSize     = pDynamicState->memoryBlock.GetHeapSize();
2391     pIshResource  = &(pRenderHalLegacy->pMhwStateHeap->GetISHPointer()->resHeap);
2392     dwIshSize     = pRenderHalLegacy->pMhwStateHeap->GetISHPointer()->dwSize;
2393 
2394     pRenderHalLegacy->StateBaseAddressParams.presGeneralState              = pGshResource;
2395     pRenderHalLegacy->StateBaseAddressParams.dwGeneralStateSize            = dwGshSize;
2396     pRenderHalLegacy->StateBaseAddressParams.presDynamicState              = pGshResource;
2397     pRenderHalLegacy->StateBaseAddressParams.dwDynamicStateSize            = dwGshSize;
2398     pRenderHalLegacy->StateBaseAddressParams.bDynamicStateRenderTarget     = false;
2399     pRenderHalLegacy->StateBaseAddressParams.presIndirectObjectBuffer      = pGshResource;
2400     pRenderHalLegacy->StateBaseAddressParams.dwIndirectObjectBufferSize    = dwGshSize;
2401     pRenderHalLegacy->StateBaseAddressParams.presInstructionBuffer         = pIshResource;
2402     pRenderHalLegacy->StateBaseAddressParams.dwInstructionBufferSize       = dwIshSize;
2403 
2404     eStatus = pRenderHalLegacy->pMhwRenderInterface->AddStateBaseAddrCmd(pCmdBuffer,
2405                                                                    &pRenderHalLegacy->StateBaseAddressParams);
2406 finish:
2407     return eStatus;
2408 }
2409 
2410 //!
2411 //! \brief    Reset RenderHal States
2412 //! \details  Reset RenderHal States in preparation for a new command buffer
2413 //! \param    PRENDERHAL_INTERFACE pRenderHal
2414 //!           [in] Pointer to RenderHal Interface Structure
2415 //! \return   MOS_STATUS
2416 //!
RenderHal_DSH_Reset(PRENDERHAL_INTERFACE pRenderHal)2417 MOS_STATUS RenderHal_DSH_Reset(
2418     PRENDERHAL_INTERFACE pRenderHal)
2419 {
2420     MOS_STATUS eStatus;
2421 
2422     //----------------------------------
2423     MHW_RENDERHAL_CHK_NULL(pRenderHal);
2424     //----------------------------------
2425 
2426     eStatus         = MOS_STATUS_SUCCESS;
2427 
2428     // Do not register GSH resource until we allocate the Media State
2429     // Media State can be in any of the current DSH instances
2430 
2431     // Do not register ISH resource until we load all kernels
2432     // ISH could be reallocated to accomodate kernels being loaded in heap
2433 
2434     //MHW_RENDERHAL_CHK_STATUS(pOsInterface->pfnRegisterResource(pOsInterface,
2435     //                                        &pStateHeap->IshOsResource,
2436     //                                        true,
2437     //                                        true));
2438 
2439     // Reset Slice Shutdown Mode
2440     pRenderHal->bRequestSingleSlice   = false;
2441     pRenderHal->PowerOption.nSlice    = 0;
2442     pRenderHal->PowerOption.nEU       = 0;
2443     pRenderHal->PowerOption.nSubSlice = 0;
2444 
2445 finish:
2446     return eStatus;
2447 }
2448 
2449 //!
2450 //! \brief    Send Sync Tag
2451 //! \details  Sends Synchronization Tags for G75
2452 //! \param    PRENDERHAL_INTERFACE pRenderHal
2453 //!           [in] Pointer to RenderHal Interface Structure
2454 //! \param    PMOS_COMMAND_BUFFER pCmdBuffer
2455 //!           [in] Pointer to Command Buffer
2456 //! \return   MOS_STATUS
2457 //!
RenderHal_DSH_SendSyncTag(PRENDERHAL_INTERFACE pRenderHal,PMOS_COMMAND_BUFFER pCmdBuffer)2458 MOS_STATUS RenderHal_DSH_SendSyncTag(
2459     PRENDERHAL_INTERFACE    pRenderHal,
2460     PMOS_COMMAND_BUFFER     pCmdBuffer)
2461 {
2462     PRENDERHAL_STATE_HEAP           pStateHeap;
2463     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
2464     PXMHW_STATE_HEAP_INTERFACE      pMhwStateHeap;
2465     PMHW_MI_INTERFACE               pMhwMiInterface;
2466     MHW_PIPE_CONTROL_PARAMS         PipeCtl;
2467 
2468     //-------------------------------------
2469     MHW_RENDERHAL_CHK_NULL(pRenderHal);
2470     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwStateHeap);
2471     MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap);
2472     //-------------------------------------
2473 
2474     pStateHeap      = pRenderHal->pStateHeap;
2475     pMhwStateHeap   = pRenderHal->pMhwStateHeap;
2476     pMhwMiInterface = pRenderHal->pMhwMiInterface;
2477 
2478     // Send PIPE_CONTROL Token
2479     // CMD_MI_FLUSH is disabled by default on GT, use PIPE_CONTROL
2480     // Requires a token and the actual pipe control command
2481     // Flush write caches
2482     PipeCtl = g_cRenderHal_InitPipeControlParams;
2483     PipeCtl.presDest          = pMhwStateHeap->GetResCmdBufIdGlobal();
2484     PipeCtl.dwPostSyncOp      = MHW_FLUSH_NOWRITE;
2485     PipeCtl.dwFlushMode       = MHW_FLUSH_WRITE_CACHE;
2486     MHW_RENDERHAL_CHK_STATUS(pMhwMiInterface->AddPipeControl(pCmdBuffer, nullptr, &PipeCtl));
2487 
2488     // Invalidate read-only caches and perform a post sync write
2489     PipeCtl = g_cRenderHal_InitPipeControlParams;
2490     PipeCtl.presDest          = pMhwStateHeap->GetResCmdBufIdGlobal();
2491     PipeCtl.dwResourceOffset  = pStateHeap->dwOffsetSync;
2492     PipeCtl.dwPostSyncOp      = MHW_FLUSH_WRITE_IMMEDIATE_DATA;
2493     PipeCtl.dwFlushMode       = MHW_FLUSH_READ_CACHE;
2494     PipeCtl.dwDataDW1         = pStateHeap->dwNextTag;
2495     MHW_RENDERHAL_CHK_STATUS(pMhwMiInterface->AddPipeControl(pCmdBuffer, nullptr, &PipeCtl));
2496 
2497 finish:
2498     return eStatus;
2499 }
2500 
2501 //!
2502 //! \brief      Sets Sampler States
2503 //! \details    Initialize and set sampler states
2504 //! \param      PRENDERHAL_INTERFACE pRenderHal
2505 //!             [in]    Pointer to HW interface
2506 //! \param      int32_t iMediaID
2507 //!             [in]    Media ID
2508 //! \param      PRENDERHAL_SAMPLER_STATE_PARAMS pSamplerParams
2509 //!             [in]    Pointer to Sampler parameters
2510 //! \param      int32_t iSamplers
2511 //!             [in]    Number of samplers
2512 //! \return     MOS_STATUS MOS_STATUS_SUCCESS if success, otherwise MOS_STATUS_UNKNOWN
2513 //!
RenderHal_DSH_SetSamplerStates(PRENDERHAL_INTERFACE pRenderHal,int32_t iMediaID,PMHW_SAMPLER_STATE_PARAM pSamplerParams,int32_t iSamplers)2514 MOS_STATUS RenderHal_DSH_SetSamplerStates(
2515     PRENDERHAL_INTERFACE        pRenderHal,
2516     int32_t                     iMediaID,
2517     PMHW_SAMPLER_STATE_PARAM    pSamplerParams,
2518     int32_t                     iSamplers)
2519 {
2520     MHW_RENDERHAL_ASSERT(true);
2521     return MOS_STATUS_UNIMPLEMENTED;
2522 }
2523 
2524 //!
2525 //! \brief      Setup Interface Descriptor
2526 //! \details    Set interface descriptor
2527 //! \param      PRENDERHAL_INTERFACE                    pRenderHal
2528 //!             [in]    Pointer to HW interface
2529 //! \param      PRENDERHAL_MEDIA_STATE                  pMediaState
2530 //!             [in]    Pointer to media state
2531 //! \param      PRENDERHAL_KRN_ALLOCATION               pKernelAllocation
2532 //!             [in]    Pointer to kernel allocation
2533 //! \param      PRENDERHAL_INTERFACE_DESCRIPTOR_PARAMS  pInterfaceDescriptorParams
2534 //!             [in]    Pointer to interface descriptor parameters
2535 //! \param      PMHW_GPGPU_WALKER_PARAMS          pGpGpuWalkerParams
2536 //!             [in]    Pointer to gpgpu walker parameters
2537 //! \return     MOS_STATUS
2538 //!
RenderHal_DSH_SetupInterfaceDescriptor(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_MEDIA_STATE pMediaState,PRENDERHAL_KRN_ALLOCATION pKernelAllocation,PRENDERHAL_INTERFACE_DESCRIPTOR_PARAMS pInterfaceDescriptorParams)2539 MOS_STATUS RenderHal_DSH_SetupInterfaceDescriptor(
2540     PRENDERHAL_INTERFACE                   pRenderHal,
2541     PRENDERHAL_MEDIA_STATE                 pMediaState,
2542     PRENDERHAL_KRN_ALLOCATION              pKernelAllocation,
2543     PRENDERHAL_INTERFACE_DESCRIPTOR_PARAMS pInterfaceDescriptorParams)
2544 {
2545     MOS_STATUS                    eStatus = MOS_STATUS_SUCCESS;
2546     MHW_ID_ENTRY_PARAMS           Params;
2547     PRENDERHAL_STATE_HEAP         pStateHeap;
2548     PRENDERHAL_DYNAMIC_STATE      pDynamicState;
2549     uint32_t                      dwMediaStateOffset;
2550     PRENDERHAL_MEDIA_STATE_LEGACY pMediaStateLegacy = (PRENDERHAL_MEDIA_STATE_LEGACY)pMediaState;
2551 
2552     //-----------------------------------------
2553     MHW_RENDERHAL_CHK_NULL(pRenderHal);
2554     MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwStateHeap);
2555     MHW_RENDERHAL_CHK_NULL(pMediaStateLegacy);
2556     MHW_RENDERHAL_CHK_NULL(pMediaStateLegacy->pDynamicState);
2557     MHW_RENDERHAL_CHK_NULL(pKernelAllocation);
2558     MHW_RENDERHAL_CHK_NULL(pKernelAllocation->pMemoryBlock);
2559     MHW_RENDERHAL_CHK_NULL(pInterfaceDescriptorParams);
2560     //-----------------------------------------
2561 
2562     // Get states, params
2563     pStateHeap = pRenderHal->pStateHeap;
2564     pDynamicState = pMediaStateLegacy->pDynamicState;
2565     dwMediaStateOffset = pDynamicState->memoryBlock.GetOffset();
2566 
2567     Params.dwMediaIdOffset = dwMediaStateOffset + pDynamicState->MediaID.dwOffset;
2568     Params.iMediaId = pInterfaceDescriptorParams->iMediaID;
2569     Params.dwKernelOffset = pKernelAllocation->dwOffset;
2570     Params.dwSamplerOffset = dwMediaStateOffset + pDynamicState->Sampler3D.dwOffset +
2571         pInterfaceDescriptorParams->iMediaID * pDynamicState->dwSizeSamplers;
2572     Params.dwSamplerCount = pKernelAllocation->Params.Sampler_Count;
2573     Params.dwBindingTableOffset = pInterfaceDescriptorParams->iBindingTableID * pStateHeap->iBindingTableSize;
2574     Params.iCurbeOffset = pInterfaceDescriptorParams->iCurbeOffset;
2575     Params.iCurbeLength = pInterfaceDescriptorParams->iCurbeLength;
2576 
2577     Params.bBarrierEnable = pInterfaceDescriptorParams->blBarrierEnable;
2578     Params.bGlobalBarrierEnable = pInterfaceDescriptorParams->blGlobalBarrierEnable;    //It's only applied for BDW+
2579     Params.dwNumberofThreadsInGPGPUGroup = pInterfaceDescriptorParams->iNumberThreadsInGroup;
2580     Params.dwSharedLocalMemorySize = pRenderHal->pfnEncodeSLMSize(pRenderHal, pInterfaceDescriptorParams->iSLMSize);
2581     Params.iCrsThdConDataRdLn = pInterfaceDescriptorParams->iCrsThrdConstDataLn;
2582     Params.memoryBlock = &pDynamicState->memoryBlock;
2583 
2584     MHW_RENDERHAL_CHK_STATUS(pRenderHal->pMhwStateHeap->AddInterfaceDescriptorData(&Params));
2585     pDynamicState->MediaID.iCurrent++;
2586 
2587 finish:
2588     return eStatus;
2589 }
2590 
2591 //!
2592 //! \brief    Set Vfe State Params
2593 //! \details  Sets VFE State parameters
2594 //!           this functions must be called to setup
2595 //!           parameters for pMhwRender->AddMediaVfeCmd()
2596 //! \param    PRENDERHAL_INTERFACE pRenderHal
2597 //!           [in] Pointer to Hardware Interface Structure
2598 //! \param    uint32_t dwDebugCounterControl
2599 //!           [in] Debug Counter Control
2600 //! \param    uint32_t dwMaximumNumberofThreads
2601 //!           [in] Maximum Number of Threads
2602 //! \param    uint32_t dwCURBEAllocationSize
2603 //!           [in] CURBE Allocation Size
2604 //! \param    uint32_t dwURBEntryAllocationSize
2605 //!           [in] URB Entry Allocation Size
2606 //! \param    PRENDERHAL_SCOREBOARD_PARAMS pScoreboardParams
2607 //!           [in] Pointer to Scoreboard Params
2608 //! \return   MOS_STATUS
2609 //!
RenderHal_DSH_SetVfeStateParams(PRENDERHAL_INTERFACE pRenderHal,uint32_t dwDebugCounterControl,uint32_t dwMaximumNumberofThreads,uint32_t dwCURBEAllocationSize,uint32_t dwURBEntryAllocationSize,PMHW_VFE_SCOREBOARD pScoreboardParams)2610 MOS_STATUS RenderHal_DSH_SetVfeStateParams(
2611     PRENDERHAL_INTERFACE    pRenderHal,
2612     uint32_t                dwDebugCounterControl,
2613     uint32_t                dwMaximumNumberofThreads,
2614     uint32_t                dwCURBEAllocationSize,
2615     uint32_t                dwURBEntryAllocationSize,
2616     PMHW_VFE_SCOREBOARD     pScoreboardParams)
2617 {
2618     PMHW_VFE_PARAMS                 pVfeParams;
2619     PRENDERHAL_STATE_HEAP           pStateHeap;
2620     PRENDERHAL_DYNAMIC_STATE        pDynamicState;
2621     PMHW_RENDER_ENGINE_CAPS         pHwCaps;
2622     PRENDERHAL_STATE_HEAP_SETTINGS  pSettings;
2623     uint32_t                        dwMaxURBSize;
2624     uint32_t                        dwMaxCURBEAllocationSize;
2625     uint32_t                        dwMaxURBEntryAllocationSize;
2626     uint32_t                        dwNumberofURBEntries;
2627     uint32_t                        dwMaxURBEntries;
2628     uint32_t                        dwMaxInterfaceDescriptorEntries;
2629     MOS_STATUS                      eStatus;
2630     uint32_t i;
2631 
2632     //---------------------------------------------
2633     MHW_RENDERHAL_CHK_NULL(pRenderHal);
2634     MHW_RENDERHAL_CHK_NULL(pRenderHal->pWaTable);
2635     MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap);
2636     MHW_RENDERHAL_CHK_NULL(pRenderHal->pHwCaps);
2637     //---------------------------------------------
2638 
2639     eStatus = MOS_STATUS_SUCCESS;
2640     pStateHeap = pRenderHal->pStateHeap;
2641     pHwCaps = pRenderHal->pHwCaps;
2642     pVfeParams = pRenderHal->pRenderHalPltInterface->GetVfeStateParameters();
2643     pSettings = &(pRenderHal->StateHeapSettings);
2644 
2645     pVfeParams->pKernelState = nullptr;
2646     pVfeParams->eVfeSliceDisable = MHW_VFE_SLICE_ALL;
2647 
2648     // Get pointer to current dynamic state
2649     MHW_RENDERHAL_CHK_NULL(pStateHeap->pCurMediaState);
2650     pDynamicState = ((PRENDERHAL_MEDIA_STATE_LEGACY)pStateHeap->pCurMediaState)->pDynamicState;
2651     MHW_RENDERHAL_CHK_NULL(pDynamicState);
2652     //-------------------------------------------------------------------------
2653     // In this calculation, URBEntryAllocationSize and CURBEAllocationSize are
2654     // in 256-bit units:
2655     // (URBEntryAllocationSize * NumberofURBEntries + CURBEAllocationSize +
2656     //  MaxInterfaceDescriptorEntries) <= 2048
2657     //-------------------------------------------------------------------------
2658 
2659     // get the Max for all the fields
2660     dwMaxURBSize = pHwCaps->dwMaxURBSize;
2661     dwMaxURBEntries = pHwCaps->dwMaxURBEntries;
2662     dwMaxURBEntryAllocationSize = pHwCaps->dwMaxURBEntryAllocationSize;
2663     dwMaxCURBEAllocationSize = pHwCaps->dwMaxCURBEAllocationSize;
2664     dwMaxInterfaceDescriptorEntries = pHwCaps->dwMaxInterfaceDescriptorEntries;
2665 
2666     dwCURBEAllocationSize = MOS_MAX(dwCURBEAllocationSize, (uint32_t)pDynamicState->Curbe.iCurrent);
2667     dwCURBEAllocationSize = MOS_ROUNDUP_SHIFT(dwCURBEAllocationSize, 5);
2668     dwURBEntryAllocationSize = MOS_ROUNDUP_SHIFT(dwURBEntryAllocationSize, 5);
2669     dwURBEntryAllocationSize = MOS_MAX(1, dwURBEntryAllocationSize);
2670     dwNumberofURBEntries = (dwMaxURBSize - dwCURBEAllocationSize - dwMaxInterfaceDescriptorEntries) / dwURBEntryAllocationSize;
2671     dwNumberofURBEntries = MOS_CLAMP_MIN_MAX(dwNumberofURBEntries, 1, 32);
2672 
2673     pVfeParams->dwDebugCounterControl = dwDebugCounterControl;
2674     pVfeParams->dwNumberofURBEntries = dwNumberofURBEntries;
2675     pVfeParams->dwMaximumNumberofThreads = (dwMaximumNumberofThreads == RENDERHAL_USE_MEDIA_THREADS_MAX) ?
2676         pHwCaps->dwMaxThreads : MOS_MIN(dwMaximumNumberofThreads, pHwCaps->dwMaxThreads);
2677     pVfeParams->dwCURBEAllocationSize = dwCURBEAllocationSize << 5;
2678     pVfeParams->dwURBEntryAllocationSize = dwURBEntryAllocationSize;
2679 
2680     MHW_RENDERHAL_ASSERT(dwNumberofURBEntries <= dwMaxURBEntries);
2681     MHW_RENDERHAL_ASSERT(dwCURBEAllocationSize <= dwMaxCURBEAllocationSize);
2682     MHW_RENDERHAL_ASSERT(dwURBEntryAllocationSize <= dwMaxURBEntryAllocationSize);
2683     MHW_RENDERHAL_ASSERT(dwNumberofURBEntries * dwURBEntryAllocationSize + dwCURBEAllocationSize + dwMaxInterfaceDescriptorEntries <= dwMaxURBSize);
2684 
2685     // Setup Scoreboard Parameters
2686     if (pScoreboardParams)
2687     {
2688         MHW_RENDERHAL_ASSERT(pScoreboardParams->ScoreboardMask < 8);
2689 
2690         pRenderHal->VfeScoreboard.ScoreboardEnable = true;
2691         pRenderHal->VfeScoreboard.ScoreboardMask = (1 << pScoreboardParams->ScoreboardMask) - 1;
2692         pRenderHal->VfeScoreboard.ScoreboardType = pScoreboardParams->ScoreboardType;
2693         for (i = 0; i < pScoreboardParams->ScoreboardMask; i++)
2694         {
2695             pRenderHal->VfeScoreboard.ScoreboardDelta[i].x = pScoreboardParams->ScoreboardDelta[i].x;
2696             pRenderHal->VfeScoreboard.ScoreboardDelta[i].y = pScoreboardParams->ScoreboardDelta[i].y;
2697         }
2698     }
2699     else
2700     {
2701         pRenderHal->VfeScoreboard.ScoreboardEnable = true;
2702         pRenderHal->VfeScoreboard.ScoreboardMask = 0x0;
2703     }
2704 
2705     // Setup VFE Scoreboard parameters
2706     pVfeParams->Scoreboard = pRenderHal->VfeScoreboard;
2707 
2708     // Setup Kernel Scratch Space
2709     if (pDynamicState->dwScratchSpace > 0)
2710     {
2711         int32_t iSize;
2712         int32_t iRemain;
2713         int32_t iPerThreadScratchSize;
2714 
2715         MHW_RENDERHAL_ASSERT(pDynamicState->iMaxScratchSpacePerThread ==
2716             MOS_ALIGN_CEIL(pDynamicState->iMaxScratchSpacePerThread, 1024));
2717 
2718         if (pRenderHal->pfnPerThreadScratchSpaceStart2K(pRenderHal))
2719             iPerThreadScratchSize = pDynamicState->iMaxScratchSpacePerThread >> 10;
2720         else
2721             iPerThreadScratchSize = pDynamicState->iMaxScratchSpacePerThread >> 9;
2722 
2723         iRemain = iPerThreadScratchSize % 2;
2724         iPerThreadScratchSize = iPerThreadScratchSize / 2;
2725         iSize = 0;
2726         while (!iRemain && (iPerThreadScratchSize / 2))
2727         {
2728             iSize++;
2729             iRemain = iPerThreadScratchSize % 2;
2730             iPerThreadScratchSize = iPerThreadScratchSize / 2;
2731         }
2732 
2733         MHW_RENDERHAL_ASSERT(!iRemain && iPerThreadScratchSize);
2734         MHW_RENDERHAL_ASSERT(iSize < 12);
2735 
2736         pVfeParams->dwPerThreadScratchSpace   = (uint32_t)iSize;
2737         pVfeParams->dwScratchSpaceBasePointer = pDynamicState->scratchSpaceOffset;
2738     }
2739     else
2740     {
2741         pVfeParams->dwPerThreadScratchSpace = 0;
2742         pVfeParams->dwScratchSpaceBasePointer = 0;
2743     }
2744 
2745 finish:
2746     return eStatus;
2747 }
2748 
2749 //!
2750 //! \brief    Get offset and/or pointer to sampler state
2751 //! \details  Get offset and/or pointer to sampler state in General State Heap
2752 //! \param    PRENDERHAL_INTERFACE pRenderHal
2753 //!           [in] Pointer to RenderHal Interface
2754 //! \param    int32_t iMediaID
2755 //!           [in] Media ID associated with sampler
2756 //! \param    int32_t iSamplerID
2757 //!           [in] Sampler ID
2758 //! \param    uint32_t *pdwSamplerOffset
2759 //!           [out] optional; offset of sampler state from GSH base
2760 //! \param    void  **ppSampler
2761 //!           [out] optional; pointer to sampler state in GSH
2762 //! \return   MOS_STATUS
2763 //!
RenderHal_DSH_GetSamplerOffsetAndPtr(PRENDERHAL_INTERFACE pRenderHal,int32_t iMediaID,int32_t iSamplerID,PMHW_SAMPLER_STATE_PARAM pSamplerParams,uint32_t * pdwSamplerOffset,void ** ppSampler)2764 MOS_STATUS RenderHal_DSH_GetSamplerOffsetAndPtr(
2765     PRENDERHAL_INTERFACE     pRenderHal,
2766     int32_t                  iMediaID,
2767     int32_t                  iSamplerID,
2768     PMHW_SAMPLER_STATE_PARAM pSamplerParams,
2769     uint32_t                 *pdwSamplerOffset,
2770     void                    **ppSampler)
2771 {
2772     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2773     MHW_RENDERHAL_CHK_NULL(pRenderHal->pRenderHalPltInterface);
2774 
2775     MHW_RENDERHAL_CHK_STATUS( pRenderHal->pRenderHalPltInterface->GetSamplerOffsetAndPtr_DSH(
2776                                                     pRenderHal,
2777                                                     iMediaID,
2778                                                     iSamplerID,
2779                                                     pSamplerParams,
2780                                                     pdwSamplerOffset,
2781                                                     ppSampler));
2782 finish:
2783     return eStatus;
2784 }
2785 
2786 //!
2787 //! \brief    Initialize
2788 //! \details  Initialize HW states
2789 //! \param    PRENDERHAL_INTERFACE pRenderHal
2790 //!           [in] Pointer to RenderHal Interface Structure
2791 //! \param    PCRENDERHAL_SETTINGS pSettings
2792 //!           [in] Pointer to Settings
2793 //! \return   MOS_STATUS
2794 //!           true  if succeeded
2795 //!           false if failed to allocate/initialize HW commands
2796 //!
RenderHal_DSH_Initialize(PRENDERHAL_INTERFACE pRenderHal,PRENDERHAL_SETTINGS pSettings)2797 MOS_STATUS RenderHal_DSH_Initialize(
2798     PRENDERHAL_INTERFACE   pRenderHal,
2799     PRENDERHAL_SETTINGS    pSettings)
2800 {
2801     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2802 
2803     PRENDERHAL_STATE_HEAP_LEGACY pStateHeap;
2804 
2805     PRENDERHAL_SETTINGS_LEGACY pSettingsLegacy = (PRENDERHAL_SETTINGS_LEGACY)pSettings;
2806     //------------------------------------------------
2807     MHW_RENDERHAL_CHK_NULL(pRenderHal);
2808     //------------------------------------------------
2809 
2810     // Allocate State Heap control structure (aligned)
2811     pStateHeap = (PRENDERHAL_STATE_HEAP_LEGACY)MOS_AlignedAllocMemory(sizeof(RENDERHAL_STATE_HEAP_LEGACY), 16);
2812     MOS_ZeroMemory(pStateHeap, sizeof(RENDERHAL_STATE_HEAP_LEGACY));
2813     pRenderHal->pStateHeap = pStateHeap;
2814     pRenderHal->dwStateHeapSize = sizeof(RENDERHAL_STATE_HEAP_LEGACY);
2815     MHW_RENDERHAL_CHK_NULL(pStateHeap);
2816 
2817     pStateHeap->kernelHashTable = CmHashTable();
2818     pStateHeap->kernelHashTable.Init();
2819 
2820     // Apply state heap settings (iMediaStates not actually used in DSH)
2821     if (pSettingsLegacy)
2822     {
2823         pRenderHal->StateHeapSettings.iMediaStateHeaps = pSettingsLegacy->iMediaStates;
2824     }
2825 
2826     // Apply Dynamic state heap settings
2827     if (pSettingsLegacy && pSettingsLegacy->pDynSettings)
2828     {
2829         PRENDERHAL_INTERFACE_LEGACY pRenderHalLegacy = (PRENDERHAL_INTERFACE_LEGACY)pRenderHal;
2830         pRenderHalLegacy->DynamicHeapSettings = *(pSettingsLegacy->pDynSettings);
2831     }
2832 
2833     // Apply SSH settings for the current platform
2834     pRenderHal->StateHeapSettings.iSurfaceStateHeaps =
2835                                 pRenderHal->StateHeapSettings.iMediaStateHeaps;
2836 
2837     // Allocate and initialize state heaps (GSH, SSH, ISH)
2838     MHW_RENDERHAL_CHK_STATUS(pRenderHal->pfnAllocateStateHeaps(pRenderHal, &pRenderHal->StateHeapSettings));
2839 
2840     // If ASM debug is enabled, allocate debug resource
2841     MHW_RENDERHAL_CHK_STATUS(RenderHal_AllocateDebugSurface(pRenderHal));
2842 
2843 finish:
2844     return eStatus;
2845 }
2846 
2847 //!
2848 //! \brief    Issue command to write timestamp
2849 //! \param    [in] pRenderHal
2850 //! \param    [in] pCmdBuffer
2851 //! \param    [in] bStartTime
2852 //! \return   MOS_STATUS
2853 //!
2854 MOS_STATUS RenderHal_DSH_SendTimingData(
2855     PRENDERHAL_INTERFACE         pRenderHal,
2856     PMOS_COMMAND_BUFFER          pCmdBuffer,
2857     bool                         bStartTime);
2858 
2859 //! Following functions are defined in RenderHal and are not used by RenderHal_DSH
2860 //! ------------------------------------------------------------------------------
RenderHal_DSH_AssignMediaState(PRENDERHAL_INTERFACE pRenderHal,RENDERHAL_COMPONENT componentID)2861 PRENDERHAL_MEDIA_STATE RenderHal_DSH_AssignMediaState(
2862     PRENDERHAL_INTERFACE     pRenderHal,
2863     RENDERHAL_COMPONENT      componentID)
2864 {
2865     MHW_RENDERHAL_ASSERT( true );
2866     return nullptr;
2867 }
2868 
RenderHal_DSH_AllocateMediaID(PRENDERHAL_INTERFACE pRenderHal,int32_t iKernelAllocationID,int32_t iBindingTableID,int32_t iCurbeOffset,int32_t iCurbeLength,int32_t iCrsThrdConstDataLn,PMHW_GPGPU_WALKER_PARAMS pGpGpuWalkerParams)2869 int32_t RenderHal_DSH_AllocateMediaID(
2870     PRENDERHAL_INTERFACE        pRenderHal,
2871     int32_t                     iKernelAllocationID,
2872     int32_t                     iBindingTableID,
2873     int32_t                     iCurbeOffset,
2874     int32_t                     iCurbeLength,
2875     int32_t                     iCrsThrdConstDataLn,
2876     PMHW_GPGPU_WALKER_PARAMS    pGpGpuWalkerParams)
2877 {
2878     MHW_RENDERHAL_ASSERT( true );
2879     return -1;
2880 }
2881 
RenderHal_DSH_LoadKernel(PRENDERHAL_INTERFACE pRenderHal,PCRENDERHAL_KERNEL_PARAM pParameters,PMHW_KERNEL_PARAM pKernel,Kdll_CacheEntry * pKernelEntry)2882 int32_t RenderHal_DSH_LoadKernel(
2883     PRENDERHAL_INTERFACE        pRenderHal,
2884     PCRENDERHAL_KERNEL_PARAM    pParameters,
2885     PMHW_KERNEL_PARAM           pKernel,
2886     Kdll_CacheEntry             *pKernelEntry)
2887 {
2888     MHW_RENDERHAL_ASSERT( true );
2889     return -1;
2890 }
2891 
RenderHal_DSH_UnloadKernel(PRENDERHAL_INTERFACE pRenderHal,int32_t iKernelAllocationID)2892 MOS_STATUS RenderHal_DSH_UnloadKernel(
2893     PRENDERHAL_INTERFACE        pRenderHal,
2894     int32_t                     iKernelAllocationID)
2895 {
2896     MHW_RENDERHAL_ASSERT( true );
2897     return MOS_STATUS_UNIMPLEMENTED;
2898 }
2899 
RenderHal_DSH_ResetKernels(PRENDERHAL_INTERFACE pRenderHal)2900 void RenderHal_DSH_ResetKernels(
2901     PRENDERHAL_INTERFACE        pRenderHal)
2902 {
2903     MHW_RENDERHAL_ASSERT( true );
2904     return;
2905 }
2906 
RenderHal_DSH_TouchKernel(PRENDERHAL_INTERFACE pRenderHal,int32_t iKernelAllocationID)2907 void RenderHal_DSH_TouchKernel(
2908     PRENDERHAL_INTERFACE        pRenderHal,
2909     int32_t                     iKernelAllocationID)
2910 {
2911     MHW_RENDERHAL_ASSERT( true );
2912     return;
2913 }
2914 
RenderHal_DSH_GetKernelOffset(PRENDERHAL_INTERFACE pRenderHal,int32_t iKernelAllocationIndex)2915 int32_t RenderHal_DSH_GetKernelOffset(
2916     PRENDERHAL_INTERFACE        pRenderHal,
2917     int32_t                     iKernelAllocationIndex)
2918 {
2919     MHW_RENDERHAL_ASSERT( true );
2920     return 0;
2921 }
2922 //! ------------------------------------------------------------------------------
2923 
2924 void RenderHal_InitInterfaceEx_Legacy(PRENDERHAL_INTERFACE_LEGACY pRenderHal);
2925 
2926 //!
2927 //! \brief    Init Interface using Dynamic State Heap
2928 //! \details  Initializes RenderHal Interface structure, responsible for HW
2929 //!           abstraction of HW Rendering Engine for CM(MDF) and VP.
2930 //! \param    PRENDERHAL_INTERFACE pRenderHal
2931 //!           [in] Pointer to RenderHal Interface Structure
2932 //! \param    MhwCpInterface** ppCpInterface
2933 //!           [in/out] Pointer of pointer to MHW CP Interface Structure, which
2934 //!           is created during renderhal initialization
2935 //! \param    PMOS_INTERFACE pOsInterface
2936 //!           [in] Pointer to OS Interface Structure
2937 //! \return   MOS_STATUS
2938 //!           MOS_STATUS_UNKNOWN : Invalid parameters
2939 //!
RenderHal_InitInterface_Dynamic(PRENDERHAL_INTERFACE_LEGACY pRenderHal,MhwCpInterface ** ppCpInterface,PMOS_INTERFACE pOsInterface)2940 MOS_STATUS RenderHal_InitInterface_Dynamic(
2941     PRENDERHAL_INTERFACE_LEGACY pRenderHal,
2942     MhwCpInterface              **ppCpInterface,
2943     PMOS_INTERFACE              pOsInterface)
2944 {
2945     MOS_STATUS eStatus;
2946 
2947     //---------------------------------------
2948     MHW_RENDERHAL_ASSERT(pRenderHal);
2949     //---------------------------------------
2950     // Init interfaces - some of which will be later replaced for DSH
2951     MHW_RENDERHAL_CHK_STATUS(RenderHal_InitInterface_Legacy(pRenderHal, ppCpInterface, pOsInterface));
2952 
2953     // Initialization/Cleanup function
2954     pRenderHal->pfnInitialize                 = RenderHal_DSH_Initialize;
2955 
2956     // Allocate/Destroy state heaps
2957     pRenderHal->pfnAllocateStateHeaps         = RenderHal_DSH_AllocateStateHeaps;
2958     pRenderHal->pfnFreeStateHeaps             = RenderHal_DSH_FreeStateHeaps;
2959 
2960     pRenderHal->pfnAssignSpaceInStateHeap     = RenderHal_DSH_AssignSpaceInStateHeap;
2961 
2962     // Media states management functions
2963     pRenderHal->pfnAssignMediaState           = RenderHal_DSH_AssignMediaState;
2964     pRenderHal->pfnAllocateMediaID            = RenderHal_DSH_AllocateMediaID;
2965     pRenderHal->pfnGetMediaID                 = RenderHal_DSH_GetMediaID;
2966     pRenderHal->pfnAssignDynamicState         = RenderHal_DSH_AssignDynamicState;
2967     pRenderHal->pfnReleaseDynamicState        = RenderHal_DSH_ReleaseDynamicState;
2968     pRenderHal->pfnSubmitDynamicState         = RenderHal_DSH_SubmitDynamicState;
2969     pRenderHal->pfnAllocateDynamicMediaID     = RenderHal_DSH_AllocateDynamicMediaID;
2970 
2971     // Kernel management functions
2972     pRenderHal->pfnRefreshSync                = RenderHal_DSH_RefreshSync;
2973     pRenderHal->pfnLoadKernel                 = RenderHal_DSH_LoadKernel;
2974     pRenderHal->pfnUnloadKernel               = RenderHal_DSH_UnloadKernel;
2975     pRenderHal->pfnResetKernels               = RenderHal_DSH_ResetKernels;
2976     pRenderHal->pfnTouchKernel                = RenderHal_DSH_TouchKernel;
2977     pRenderHal->pfnGetKernelOffset            = RenderHal_DSH_GetKernelOffset;
2978     pRenderHal->pfnUnregisterKernel           = RenderHal_DSH_UnregisterKernel;
2979 
2980     // Dynamic Kernel management functions (not implemented here)
2981     pRenderHal->pfnLoadDynamicKernel          = RenderHal_DSH_LoadDynamicKernel;
2982     pRenderHal->pfnAllocateDynamicKernel      = RenderHal_DSH_AllocateDynamicKernel;
2983     pRenderHal->pfnSearchDynamicKernel        = RenderHal_DSH_SearchDynamicKernel;
2984     pRenderHal->pfnUnloadDynamicKernel        = RenderHal_DSH_UnloadDynamicKernel;
2985     pRenderHal->pfnRefreshDynamicKernels      = RenderHal_DSH_RefreshDynamicKernels;
2986     pRenderHal->pfnResetDynamicKernels        = RenderHal_DSH_ResetDynamicKernels;
2987     pRenderHal->pfnTouchDynamicKernel         = RenderHal_DSH_TouchDynamicKernel;
2988     pRenderHal->pfnExpandKernelStateHeap      = RenderHal_DSH_ExpandKernelStateHeap;
2989 
2990     // ISA ASM Debug support functions
2991     pRenderHal->pfnLoadSipKernel              = RenderHal_DSH_LoadSipKernel;
2992     pRenderHal->pfnSendSipStateCmd            = RenderHal_DSH_SendSipStateCmd;
2993 
2994     // Command buffer programming functions
2995     pRenderHal->pfnLoadCurbeData              = RenderHal_DSH_LoadCurbeData;
2996     pRenderHal->pfnSendCurbeLoad              = RenderHal_DSH_SendCurbeLoad;
2997     pRenderHal->pfnSendStateBaseAddress       = RenderHal_DSH_SendStateBaseAddress;
2998 
2999     // Initialize OS dependent RenderHal Interfaces common to all platforms
3000     pRenderHal->pfnReset                      = RenderHal_DSH_Reset;
3001     pRenderHal->pfnSendTimingData             = RenderHal_DSH_SendTimingData;
3002     pRenderHal->pfnSendSyncTag                = RenderHal_DSH_SendSyncTag;
3003 
3004     // Sampler state, interface descriptor, VFE params
3005     pRenderHal->pfnSetSamplerStates           = RenderHal_DSH_SetSamplerStates;
3006     pRenderHal->pfnSetupInterfaceDescriptor   = RenderHal_DSH_SetupInterfaceDescriptor;
3007     pRenderHal->pfnSetVfeStateParams          = RenderHal_DSH_SetVfeStateParams;
3008 
3009     // Hardware dependent calls
3010     pRenderHal->pfnGetSamplerOffsetAndPtr     = RenderHal_DSH_GetSamplerOffsetAndPtr;
3011 
3012     // Special functions
3013     RenderHal_InitInterfaceEx_Legacy(pRenderHal);
3014 
3015     // Initialize the DSH settings
3016     pRenderHal->pRenderHalPltInterface->InitDynamicHeapSettings(pRenderHal);
3017 
3018 finish:
3019     return eStatus;
3020 }
3021