1 /*
2 * Copyright (c) 2018, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file      cm_ssh.cpp
24 //! \brief     Contains Class CmSSH  definitions
25 //!
26 
27 #include "cm_ssh.h"
28 #include "renderhal_platform_interface.h"
29 #include "cm_kernel_ex.h"
30 #include "cm_scratch_space.h"
31 #include "mos_solo_generic.h"
32 
33 #include <string>
34 #include <iostream>
35 #include <sstream>
36 #include <fstream>
37 
CmSSH(CM_HAL_STATE * cmhal,PMOS_COMMAND_BUFFER cmdBuf)38 CmSSH::CmSSH(CM_HAL_STATE *cmhal, PMOS_COMMAND_BUFFER cmdBuf):
39     m_stateBase(nullptr),
40     m_stateOffset(0),
41     m_length(0),
42     m_btStart(0),
43     m_ssStart(0),
44     m_bteNum(0),
45     m_maxSsNum(0),
46     m_btEntrySize(0),
47     m_ssCmdSize(0),
48     m_cmdBuf(cmdBuf),
49     m_curBTIndex(0),
50     m_normalBteStart(0),
51     m_curSsIndex(0),
52     m_cmhal(cmhal),
53     m_renderhal(nullptr),
54     m_resCount(0),
55     m_occupiedBteIndexes(nullptr)
56 {
57 }
58 
Initialize(CmKernelEx ** kernels,uint32_t count)59 MOS_STATUS CmSSH::Initialize(CmKernelEx **kernels, uint32_t count)
60 {
61     CM_CHK_NULL_RETURN_MOSERROR(m_cmhal);
62 
63     m_renderhal = m_cmhal->renderHal;
64     if (!m_renderhal)
65     {
66         return MOS_STATUS_NULL_POINTER;
67     }
68 
69     PMOS_INTERFACE osInterface = m_cmhal->osInterface;
70     if (m_cmdBuf && osInterface)
71     {
72         osInterface->pfnGetIndirectState(osInterface, &m_stateOffset, &m_length);
73         m_stateBase = (uint8_t *)m_cmdBuf->pCmdBase + m_stateOffset;
74     }
75 
76     if (!m_stateBase)
77     {
78         return MOS_STATUS_NULL_POINTER;
79     }
80 
81     PRENDERHAL_STATE_HEAP_SETTINGS pSettings = &m_renderhal->StateHeapSettings;
82     m_btStart = 0;
83 
84     m_btEntrySize = m_renderhal->pHwSizes->dwSizeBindingTableState;
85     m_ssCmdSize = m_renderhal->pRenderHalPltInterface->GetSurfaceStateCmdSize();
86 
87     // Get the total binding table entry number for one ssh
88     m_bteNum = pSettings->iBindingTables * pSettings->iSurfacesPerBT;
89 
90     CM_SURFACE_BTI_INFO surfBTIInfo;
91     m_cmhal->cmHalInterface->GetHwSurfaceBTIInfo(&surfBTIInfo);
92     m_normalBteStart = surfBTIInfo.normalSurfaceStart;
93 
94     m_ssStart = m_btStart + m_bteNum * m_btEntrySize;
95     m_maxSsNum = pSettings->iSurfaceStates;
96 
97     uint32_t requiredSize = m_ssStart + m_maxSsNum * m_ssCmdSize;
98 
99     // set binding table and surface states to 0
100     MOS_ZeroMemory(m_stateBase + m_btStart, requiredSize);
101 
102     if (requiredSize > m_length)
103     {
104         return MOS_STATUS_NO_SPACE;
105     }
106 
107     MOS_ZeroMemory(m_btStartPerKernel, sizeof(m_btStartPerKernel));
108     MOS_ZeroMemory(m_curBteIndexes, sizeof(m_curBteIndexes));
109     MOS_ZeroMemory(m_surfStatesInSsh, sizeof(m_surfStatesInSsh));
110     MOS_ZeroMemory(m_resourcesAdded, sizeof(m_resourcesAdded));
111     m_occupiedBteIndexes = MOS_NewArray(_BteFlag, count);
112 
113     return MOS_STATUS_SUCCESS;
114 }
115 
~CmSSH()116 CmSSH::~CmSSH()
117 {
118     if (m_occupiedBteIndexes)
119     {
120         MOS_DeleteArray(m_occupiedBteIndexes);
121     }
122 }
123 
124 
AssignBindingTable()125 int CmSSH::AssignBindingTable()
126 {
127     int index = m_curBTIndex;
128     m_curBTIndex ++;
129     m_curBteIndexes[index] = m_normalBteStart;
130     if (index > 0) // align the last BT size
131     {
132         uint32_t size = (m_btStartPerKernel[index] - m_btStartPerKernel[index -1]) * m_btEntrySize;
133         uint32_t alignedSize = MOS_ALIGN_CEIL(size, m_renderhal->StateHeapSettings.iBTAlignment);
134         m_btStartPerKernel[index] = m_btStartPerKernel[index -1] + alignedSize/m_btEntrySize;
135     }
136 
137     return index;
138 }
139 
GetFreeBindingTableEntries(int surfNum,int btIndex)140 int CmSSH::GetFreeBindingTableEntries(int surfNum, int btIndex)
141 {
142     int index = (btIndex == -1)?(m_curBTIndex - 1):btIndex;
143     if (index < 0 || index >= CM_MAX_KERNELS_PER_TASK)
144     {
145         MHW_RENDERHAL_ASSERTMESSAGE("Binding Table not assigned yet");
146         return -1;
147     }
148     uint32_t bteIndex = m_curBteIndexes[index];
149     for (; bteIndex < m_bteNum - m_btStartPerKernel[index]; bteIndex ++)
150     {
151         if (!m_occupiedBteIndexes[index].IsSet(bteIndex, surfNum))
152         {
153             break;
154         }
155     }
156 
157     m_curBteIndexes[index] = bteIndex + surfNum;
158     if (m_curBteIndexes[index] > m_bteNum - m_btStartPerKernel[index] + 1)
159     {
160         MHW_RENDERHAL_ASSERTMESSAGE("No available binding table entries in current binding table");
161         return -1;
162     }
163     return bteIndex;
164 }
165 
GetFreeSurfStateIndex(int surfNum)166 int CmSSH::GetFreeSurfStateIndex(int surfNum)
167 {
168     if (m_curSsIndex + surfNum > m_maxSsNum)
169     {
170         MHW_RENDERHAL_ASSERTMESSAGE("Unable to allocate Surface State. Exceeds Maximum.");
171         return -1;
172     }
173 
174     int ssIdx = m_curSsIndex;
175     m_curSsIndex += surfNum;
176     return ssIdx;
177 }
178 
AddSurfaceState(CmSurfaceState * surfState,int bteIndex,int btIndex)179 int CmSSH::AddSurfaceState(CmSurfaceState *surfState, int bteIndex, int btIndex)
180 {
181     int btIdx = (btIndex == -1)?(m_curBTIndex - 1):btIndex;
182 
183     bool bteRecorded = false;
184     bool ssRecorded = false;
185 
186     CmSSH *rSsh;
187     int rBtIdx;
188     int rBteIdx;
189     int rSsIdx;
190     surfState->GetRecordedInfo(&rSsh, &rBtIdx, &rBteIdx, &rSsIdx);
191 
192     if (rSsh == this && rSsIdx >= 0)
193     {
194         bool valid = true;
195         for (uint32_t idx = 0; idx < surfState->GetNumPlane(); idx ++)
196         {
197             if (m_surfStatesInSsh[rSsIdx+idx] != surfState)
198             {
199                 valid = false;
200                 break;
201             }
202         }
203         if (valid)
204         {
205             ssRecorded = true;
206             if (rBtIdx == btIdx)
207             {
208                 bteRecorded = true;
209             }
210         }
211     }
212 
213     if (bteRecorded && (bteIndex == -1 || rBteIdx == bteIndex))
214     {
215         return rBteIdx;
216     }
217     // if bteRecorded by user required a different bteIndex, still add a new entry
218     bteRecorded = false;
219 
220     MOS_RESOURCE *resource = surfState->GetResource();
221 
222     int bteIdx = (bteIndex == -1)?(GetFreeBindingTableEntries(surfState->GetNumBte(), btIdx)):bteIndex;
223     if (btIdx == -1 || bteIdx == -1)
224     {
225         return -1;
226     }
227 
228     int ssIdx;
229     if (ssRecorded)
230     {
231         ssIdx = rSsIdx;
232     }
233     else
234     {
235         ssIdx = GetFreeSurfStateIndex(surfState->GetNumPlane());
236     }
237 
238     m_occupiedBteIndexes[btIdx].Set(bteIdx, surfState->GetNumBte());
239 
240     if (btIdx == m_curBTIndex - 1) // current binding table, allow next bt start to change
241     {
242         if ((btIdx + 1) >= (CM_MAX_KERNELS_PER_TASK + 1))
243         {
244             MHW_RENDERHAL_ASSERTMESSAGE("Binding table index exceeds the maximun.");
245             return -1;
246         }
247         m_btStartPerKernel[btIdx + 1] = MOS_MAX(m_btStartPerKernel[btIdx + 1], m_btStartPerKernel[btIdx] + bteIdx + surfState->GetNumBte());
248         if (m_btStartPerKernel[btIdx + 1] > m_bteNum)
249         {
250             MHW_RENDERHAL_ASSERTMESSAGE("Binding table entry index exceeds the maximun.");
251             return -1;
252         }
253     }
254     else if ((uint32_t)btIdx > m_curBTIndex - 1)
255     {
256         MHW_RENDERHAL_ASSERTMESSAGE("Can't set to a binding table not assigned.");
257         return -1;
258     }
259     else if((btIdx + 1) >= (CM_MAX_KERNELS_PER_TASK + 1) ||
260             (m_btStartPerKernel[btIdx] + bteIdx + surfState->GetNumBte() > m_btStartPerKernel[btIdx + 1]))
261     {
262         MHW_RENDERHAL_ASSERTMESSAGE("Binding table entry index exceeds the maximun.");
263         return -1;
264     }
265 
266     int stateIdx = 0;
267     for (uint32_t surfIdx = 0; surfIdx < surfState->GetNumBte(); surfIdx ++)
268     {
269         uint8_t *pSS = surfState->GetSurfaceState(surfIdx);
270         if (pSS == nullptr)
271         {
272             continue;
273         }
274         // Get the pointer to the binding table entry
275         uint8_t *pBte = m_stateBase + m_btStart + m_btStartPerKernel[btIdx] * m_btEntrySize + (bteIdx+surfIdx) * m_btEntrySize;
276         // Get the offset to the surface state
277         uint32_t surfStateOffset = m_ssStart + (ssIdx + stateIdx) * m_ssCmdSize;
278 
279         MHW_BINDING_TABLE_PARAMS params;
280         params.pBindingTableEntry   = pBte;
281         params.dwSurfaceStateOffset = surfStateOffset;
282         params.bSurfaceStateAvs     = surfState->isAVS(surfIdx)? true : false;
283         params.iBindingTableEntry   = bteIdx + surfIdx;
284 
285         m_renderhal->pMhwStateHeap->SetBindingTableEntry(&params);
286 
287         if (!ssRecorded)
288         {
289             int patchDWOffset = 0;
290 
291             MOS_RESOURCE *resourcePerPlane = surfState->GetResource(surfIdx);
292             if (resourcePerPlane)
293             {
294                 if (m_cmhal->syncOnResource && (!Mos_Solo_IsInUse(m_cmhal->osInterface)))
295                 {
296                     if (m_cmhal->osInterface->CurrentGpuContextOrdinal != MOS_GPU_CONTEXT_RENDER4)
297                     {
298                         m_cmhal->osInterface->pfnSyncOnResource(
299                             m_cmhal->osInterface,
300                             resourcePerPlane,
301                             m_cmhal->osInterface->CurrentGpuContextOrdinal, //state->GpuContext,
302                             true);
303                     }
304                 }
305                 m_renderhal->pOsInterface->pfnRegisterResource(m_renderhal->pOsInterface, resourcePerPlane, true, true);
306                 m_resourcesAdded[m_resCount ++] = resourcePerPlane;
307             }
308             else
309             {
310                 continue;
311             }
312 
313             if (surfState->isAVS(surfIdx))
314             {
315                 MOS_SecureMemcpy(m_stateBase + surfStateOffset, m_renderhal->pHwSizes->dwSizeSurfaceState,
316                     pSS, m_renderhal->pHwSizes->dwSizeSurfaceState);
317                 patchDWOffset = 6;
318             }
319             else
320             {
321                 MOS_SecureMemcpy(m_stateBase + surfStateOffset, m_renderhal->pHwSizes->dwSizeSurfaceState,
322                     pSS, m_renderhal->pHwSizes->dwSizeSurfaceState);
323                 patchDWOffset = 8;
324             }
325 
326             uint64_t ui64GfxAddress = 0;
327             if (m_renderhal->pOsInterface->bUsesGfxAddress)
328             {
329                 uint32_t *pAddr = (uint32_t *)(m_stateBase + surfStateOffset) + patchDWOffset;
330 
331                 if ( resourcePerPlane->user_provided_va != 0 )
332                 {
333                     ui64GfxAddress = resourcePerPlane->user_provided_va;
334                 }
335                 else
336                 {
337                     ui64GfxAddress = m_renderhal->pOsInterface->pfnGetResourceGfxAddress( m_renderhal->pOsInterface, resourcePerPlane)
338                                         + surfState->GetSurfaceOffset(surfIdx);
339                 }
340                 *pAddr = ( uint32_t )( ui64GfxAddress & 0x00000000FFFFFFFF );
341                 *(pAddr + 1) = ( uint32_t )( ( ui64GfxAddress & 0x0000FFFF00000000 ) >> 32 );
342             }
343 
344             MOS_PATCH_ENTRY_PARAMS PatchEntryParams;
345 
346             uint8_t *pbPtrCmdBuf = (uint8_t *)m_cmdBuf->pCmdBase;
347 
348             MOS_ZeroMemory(&PatchEntryParams, sizeof(PatchEntryParams));
349             PatchEntryParams.uiAllocationIndex  = m_renderhal->pOsInterface->pfnGetResourceAllocationIndex(m_renderhal->pOsInterface, resourcePerPlane);
350             PatchEntryParams.uiResourceOffset = surfState->GetSurfaceOffset(surfIdx);
351             PatchEntryParams.uiPatchOffset    = m_stateOffset + surfStateOffset + patchDWOffset*4;
352             PatchEntryParams.bWrite           = surfState->IsRenderTarget();
353             PatchEntryParams.HwCommandType    = surfState->isAVS(surfIdx)? MOS_SURFACE_STATE_ADV : MOS_SURFACE_STATE;
354             PatchEntryParams.forceDwordOffset = 0;
355             PatchEntryParams.cmdBufBase       = pbPtrCmdBuf;
356             PatchEntryParams.presResource     = resourcePerPlane;
357 
358             // Set patch for surface state address
359             m_renderhal->pOsInterface->pfnSetPatchEntry(
360                 m_renderhal->pOsInterface,
361                 &PatchEntryParams);
362 
363             if (surfState->GetMmcState(surfIdx) == MOS_MEMCOMP_RC && (!surfState->isAVS(surfIdx))
364                 && (!m_cmhal->cmHalInterface->SupportCompressedOutput()))
365             {
366                 if (m_renderhal->pOsInterface->bUsesGfxAddress)
367                 {
368                     uint32_t *pSurfStateAddr = (uint32_t *)(m_stateBase + surfStateOffset);
369                     uint64_t auxAddress = ui64GfxAddress + (uint32_t)resourcePerPlane->pGmmResInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_CCS);
370                     *(pSurfStateAddr + 10) = ( uint32_t )( auxAddress & 0x00000000FFFFFFFF );
371                     *(pSurfStateAddr + 11) = ( uint32_t )( ( auxAddress & 0x0000FFFF00000000 ) >> 32 );
372                     uint64_t clearAddress = ui64GfxAddress + (uint32_t)resourcePerPlane->pGmmResInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_CC);
373                     *(pSurfStateAddr + 12) = ( uint32_t )( clearAddress & 0x00000000FFFFFFFF );
374                     *(pSurfStateAddr + 13) = ( uint32_t )( ( clearAddress & 0x0000FFFF00000000 ) >> 32 );
375                 }
376                 else
377                 {
378                     // Set patch for AuxiliarySurfaceBaseAddress
379                     MOS_ZeroMemory(&PatchEntryParams, sizeof(PatchEntryParams));
380                     PatchEntryParams.uiAllocationIndex  = m_renderhal->pOsInterface->pfnGetResourceAllocationIndex(m_renderhal->pOsInterface, resourcePerPlane);
381                     PatchEntryParams.uiResourceOffset = surfState->GetSurfaceOffset(surfIdx) + (uint32_t)resourcePerPlane->pGmmResInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_CCS);
382                     PatchEntryParams.uiPatchOffset    = m_stateOffset + surfStateOffset + 10 * sizeof(uint32_t);
383                     PatchEntryParams.bWrite           = surfState->IsRenderTarget();
384                     PatchEntryParams.HwCommandType    = surfState->isAVS(surfIdx)? MOS_SURFACE_STATE_ADV : MOS_SURFACE_STATE;
385                     PatchEntryParams.forceDwordOffset = 0;
386                     PatchEntryParams.cmdBufBase       = pbPtrCmdBuf;
387                     PatchEntryParams.presResource     = resourcePerPlane;
388                     m_renderhal->pOsInterface->pfnSetPatchEntry(
389                         m_renderhal->pOsInterface,
390                         &PatchEntryParams);
391 
392                     // Set patch for ClearAddress
393                     MOS_ZeroMemory(&PatchEntryParams, sizeof(PatchEntryParams));
394                     PatchEntryParams.uiAllocationIndex  = m_renderhal->pOsInterface->pfnGetResourceAllocationIndex(m_renderhal->pOsInterface, resourcePerPlane);
395                     PatchEntryParams.uiResourceOffset = surfState->GetSurfaceOffset(surfIdx) + (uint32_t)resourcePerPlane->pGmmResInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_CC);
396                     PatchEntryParams.uiPatchOffset    = m_stateOffset + surfStateOffset + 12 * sizeof(uint32_t);
397                     PatchEntryParams.bWrite           = surfState->IsRenderTarget();
398                     PatchEntryParams.HwCommandType    = surfState->isAVS(surfIdx)? MOS_SURFACE_STATE_ADV : MOS_SURFACE_STATE;
399                     PatchEntryParams.forceDwordOffset = 0;
400                     PatchEntryParams.cmdBufBase       = pbPtrCmdBuf;
401                     PatchEntryParams.presResource     = resourcePerPlane;
402                     m_renderhal->pOsInterface->pfnSetPatchEntry(
403                         m_renderhal->pOsInterface,
404                         &PatchEntryParams);
405                 }
406             }
407 
408             // Record the surface state added
409             m_surfStatesInSsh[ssIdx + stateIdx] = surfState;
410             stateIdx ++;
411         }
412     }
413 
414     surfState->Recorded(this, btIdx, bteIdx, ssIdx);
415 
416     return bteIdx;
417 }
418 
AddScratchSpace(CmScratchSpace * scratch)419 int CmSSH::AddScratchSpace(CmScratchSpace *scratch)
420 {
421     int ssIdx = GetFreeSurfStateIndex(1); // one surface state for scratch
422     if (ssIdx < 0)
423     {
424         return ssIdx;
425     }
426     MOS_RESOURCE *resource =  scratch->GetResource();
427     m_renderhal->pOsInterface->pfnRegisterResource(m_renderhal->pOsInterface,
428                                                    resource,
429                                                    true, true);
430     m_resourcesAdded[m_resCount ++] = resource;
431 
432     uint32_t surfStateOffset = m_ssStart + ssIdx * m_ssCmdSize;
433 
434     // create a surface state for scratch buffer
435     CmSurfaceStateBuffer surfState(m_cmhal);
436     surfState.Initialize(scratch->GetResource(), scratch->GetSize());
437     surfState.GenerateSurfaceState();
438 
439     uint8_t *pSS = surfState.GetSurfaceState(0);
440 
441     MOS_SecureMemcpy(m_stateBase + surfStateOffset, m_renderhal->pHwSizes->dwSizeSurfaceState,
442         pSS, m_renderhal->pHwSizes->dwSizeSurfaceState);
443     int patchDWOffset = 8;
444 
445     uint64_t ui64GfxAddress = 0;
446     if (m_renderhal->pOsInterface->bUsesGfxAddress)
447     {
448         uint32_t *pAddr = (uint32_t *)(m_stateBase + surfStateOffset) + patchDWOffset;
449 
450         if ( resource->user_provided_va != 0 )
451         {
452             ui64GfxAddress = resource->user_provided_va;
453         }
454         else
455         {
456             ui64GfxAddress = m_renderhal->pOsInterface->pfnGetResourceGfxAddress( m_renderhal->pOsInterface, resource)
457                                 + surfState.GetSurfaceOffset(0);
458         }
459         *pAddr = ( uint32_t )( ui64GfxAddress & 0x00000000FFFFFFFF );
460         *(pAddr + 1) = ( uint32_t )( ( ui64GfxAddress & 0x0000FFFF00000000 ) >> 32 );
461     }
462 
463     MOS_PATCH_ENTRY_PARAMS PatchEntryParams;
464     uint8_t *pbPtrCmdBuf = (uint8_t *)m_cmdBuf->pCmdBase;
465 
466     MOS_ZeroMemory(&PatchEntryParams, sizeof(PatchEntryParams));
467     PatchEntryParams.uiAllocationIndex  = m_renderhal->pOsInterface->pfnGetResourceAllocationIndex(m_renderhal->pOsInterface, resource);
468     PatchEntryParams.uiResourceOffset = surfState.GetSurfaceOffset(0);
469     PatchEntryParams.uiPatchOffset    = m_stateOffset + surfStateOffset + patchDWOffset*4;
470     PatchEntryParams.bWrite           = surfState.IsRenderTarget();
471     PatchEntryParams.HwCommandType    = surfState.isAVS(0)? MOS_SURFACE_STATE_ADV : MOS_SURFACE_STATE;
472     PatchEntryParams.forceDwordOffset = 0;
473     PatchEntryParams.cmdBufBase       = pbPtrCmdBuf;
474     PatchEntryParams.presResource     = resource;
475 
476     // Set patch for surface state address
477     m_renderhal->pOsInterface->pfnSetPatchEntry(m_renderhal->pOsInterface,
478                                                 &PatchEntryParams);
479 
480     return surfStateOffset;
481 }
482 
GetBindingTableOffset(int btIndex)483 int CmSSH::GetBindingTableOffset(int btIndex)
484 {
485     if (btIndex == -1)
486     {
487         btIndex = m_curBTIndex - 1;
488     }
489     if (btIndex == -1) // not assigned a bt
490     {
491         MHW_RENDERHAL_ASSERTMESSAGE("Binding Table not Allocated.");
492     }
493     return m_btStart + m_btStartPerKernel[btIndex]*m_btEntrySize;
494 }
495 
EstimateBTSize(int maxBteNum,std::map<int,CmSurfaceState * > & reservedBteIndex)496 int CmSSH::EstimateBTSize(int maxBteNum, std::map<int, CmSurfaceState *> &reservedBteIndex)
497 {
498     int estimatedSize = maxBteNum + m_normalBteStart;
499     if (reservedBteIndex.empty())
500     {
501         return estimatedSize;
502     }
503 
504     for (auto it = reservedBteIndex.begin(); it != reservedBteIndex.end(); it++)
505     {
506         if (it->first < (int)m_normalBteStart)
507         {
508             continue;
509         }
510         else if (it->first > estimatedSize - 1)
511         {
512             estimatedSize = it->first + it->second->GetNumBte();
513         }
514         else
515         {
516             estimatedSize += it->second->GetNumBte() + 2; // reserved 2 extra entries for each inserted bte
517         }
518     }
519 
520     return estimatedSize;
521 }
522 
PrepareResourcesForCp()523 MOS_STATUS CmSSH::PrepareResourcesForCp()
524 {
525     if (m_resCount > 0 && m_renderhal->pOsInterface->osCpInterface)
526     {
527         return m_renderhal->pOsInterface->osCpInterface->PrepareResources((void **)m_resourcesAdded, m_resCount, nullptr, 0);
528     }
529     return MOS_STATUS_SUCCESS;
530 }
531 
532 using namespace std;
533 
534 #if defined(ANDROID) || defined(LINUX)
535 #define PLATFORM_DIR_SEPERATOR   "/"
536 #else
537 #define PLATFORM_DIR_SEPERATOR   "\\"
538 #endif
539 
DumpSSH()540 void CmSSH::DumpSSH()
541 {
542 #if MDF_SURFACE_STATE_DUMP
543     if (m_cmhal->dumpSurfaceState)
544     {
545         char fileNamePrefix[MAX_PATH];
546         static int fileCount = 0;
547         stringstream filename;
548         filename << "HALCM_Surface_State_Dumps" << PLATFORM_DIR_SEPERATOR << "ssh_" << fileCount++ << ".fast.log";
549         GetLogFileLocation(filename.str().c_str(), fileNamePrefix);
550 
551         fstream sshFile;
552         sshFile.open(fileNamePrefix, ios_base::out);
553 
554         sshFile << "==============================" << endl;
555         sshFile << "Binding Table:" << endl;
556 
557         for (uint32_t idx = 0; idx < CM_MAX_KERNELS_PER_TASK; idx ++)
558         {
559             sshFile << "BT " << dec << idx << ":" << endl;
560             for (int i = 0; i < (int)(m_btStartPerKernel[idx + 1] - m_btStartPerKernel[idx]); i++)
561             {
562                 sshFile << "    " << dec << i << ": ";
563                 uint32_t *pData = (uint32_t *)(m_stateBase + m_btStart + (m_btStartPerKernel[idx] + i)*m_btEntrySize);
564                 for (uint32_t j = 0; j < m_btEntrySize/4; j ++)
565                 {
566                     sshFile << "0x" << hex << *(pData + j) <<", ";
567                 }
568                 sshFile << endl;
569             }
570         }
571 
572         sshFile << endl << endl << endl;
573         sshFile << "================================" << endl;
574         sshFile << "Surface States:" << endl;
575         for (uint32_t idx = 0; idx < m_maxSsNum; idx ++)
576         {
577             int offset = m_ssStart + idx * m_ssCmdSize;
578             sshFile << dec << idx << ": offset 0x" << hex << offset << ":  ";
579             uint32_t *pData = (uint32_t *)(m_stateBase + offset);
580             for (uint32_t i = 0; i < m_ssCmdSize/4; i++)
581             {
582                 sshFile << "0x" << hex << *(pData + i) << ", ";
583             }
584             sshFile << endl;
585         }
586 
587         sshFile.close();
588     }
589 #endif
590 }
591 
DumpSSH(CM_HAL_STATE * cmhal,PMOS_COMMAND_BUFFER cmdBuf)592 void CmSSH::DumpSSH(CM_HAL_STATE *cmhal, PMOS_COMMAND_BUFFER cmdBuf)
593 {
594     uint8_t *stateBase = nullptr;
595     uint32_t stateOffset;
596     uint32_t length;
597     uint32_t btStart; // start of binding tables
598     uint32_t ssStart; // start of surface states
599     uint32_t maxBtNum;
600     uint32_t btSize; // size of each binding table
601     uint32_t maxSsNum;
602     uint32_t btEntrySize; // size of each binding table entry
603     uint32_t ssCmdSize; // size of each Surface state cmd
604     RENDERHAL_INTERFACE *renderhal = nullptr;
605     if (cmhal)
606     {
607         renderhal = cmhal->renderHal;
608     }
609     if (!renderhal)
610     {
611         return;
612     }
613 
614     PMOS_INTERFACE osInterface = cmhal->osInterface;
615     if (cmdBuf && osInterface)
616     {
617         osInterface->pfnGetIndirectState(osInterface, &stateOffset, &length);
618         stateBase = (uint8_t *)cmdBuf->pCmdBase + stateOffset;
619     }
620 
621     if (!stateBase)
622     {
623         return;
624     }
625 
626     PRENDERHAL_STATE_HEAP_SETTINGS pSettings = &renderhal->StateHeapSettings;
627     btStart = 0;
628     maxBtNum = pSettings->iBindingTables;
629     btSize = MOS_ALIGN_CEIL(pSettings->iSurfacesPerBT * renderhal->pHwSizes->dwSizeBindingTableState,
630                               pSettings->iBTAlignment);
631     ssStart = btStart + maxBtNum * btSize;
632     maxSsNum = pSettings->iSurfaceStates;
633     btEntrySize = renderhal->pHwSizes->dwSizeBindingTableState;
634     ssCmdSize = renderhal->pRenderHalPltInterface->GetSurfaceStateCmdSize();
635 
636     // Dump
637     static int fileCount = 0;
638     stringstream filename;
639     filename << "ssh_" << fileCount++ << ".orig.log";
640 
641     fstream sshFile;
642     sshFile.open(filename.str(), ios_base::out);
643 
644     sshFile << "==============================" << endl;
645     sshFile << "Binding Table:" << endl;
646 
647     for (uint32_t idx = 0; idx < maxBtNum; idx ++)
648     {
649         sshFile << "BT " << dec << idx << ":" << endl;
650         for (uint32_t i = 0; i < btSize/btEntrySize; i++)
651         {
652             sshFile << "    " << dec << i << ": ";
653             uint32_t *pData = (uint32_t *)(stateBase + btStart + idx*btSize + i*btEntrySize);
654             for (uint32_t j = 0; j < btEntrySize/4; j ++)
655             {
656                 sshFile << "0x" << hex << *(pData + j) <<", ";
657             }
658             sshFile << endl;
659         }
660     }
661 
662     sshFile << endl << endl << endl;
663     sshFile << "================================" << endl;
664     sshFile << "Surface States:" << endl;
665     for (uint32_t idx = 0; idx < maxSsNum; idx ++)
666     {
667         int offset = ssStart + idx * ssCmdSize;
668         sshFile << dec << idx << ": offset 0x" << hex << offset << ":  ";
669         uint32_t *pData = (uint32_t *)(stateBase + offset);
670         for (uint32_t i = 0; i < ssCmdSize/4; i++)
671         {
672             sshFile << "0x" << hex << *(pData + i) << ", ";
673         }
674         sshFile << endl;
675     }
676     sshFile.close();
677 }
678 
679