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