xref: /aosp_15_r20/external/intel-media-driver/media_softlet/linux/common/os/mos_auxtable_mgr.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2018-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    mos_auxtable_mgr.cpp
24 //! \brief   Container class for GMM aux table manager wrapper
25 //!
26 
27 #include "mos_auxtable_mgr.h"
28 #include "mos_utilities.h"
29 
30 //!
31 //! \brief  Implementation of device callback for GMM PageTableMgr to allocate page table BO
32 //!
33 //! \param  [in] bufMgr
34 //!         MOS_BUFMGR pass to GMM PageTableMgr by media driver
35 //! \param  [in] size
36 //!         Size to be allocated
37 //! \param  [in] alignment
38 //!         Alignment requirement for the VA address of the allocated buffer
39 //! \param  [out] bo
40 //!         Poiner to the bo object allocated
41 //! \param  [out] cpuAddr
42 //!         CPU VA of the bo object allocated
43 //! \param  [out] gpuAddr
44 //!         CPU VA of the bo object allocated
45 //!
46 //! \return int
47 //!         Error status code. 0 if success, else errno.
48 //!
AllocateCb(void * bufMgr,size_t size,size_t alignment,void ** bo,void ** cpuAddr,uint64_t * gpuAddr)49 static int AllocateCb(void *bufMgr, size_t size, size_t alignment, void **bo, void **cpuAddr, uint64_t *gpuAddr)
50 {
51     int             ret = 0;
52     MOS_BUFMGR      *bm;
53     void            *userptr;
54     mos_linux_bo    *lbo;
55 
56     if (bufMgr == nullptr)
57         return -EINVAL;
58 
59     bm = (MOS_BUFMGR *)bufMgr;
60     userptr = MOS_AlignedAllocMemory(size, alignment);
61     if (userptr == nullptr)
62         return -ENOMEM;
63 
64     struct mos_drm_bo_alloc_userptr alloc_uptr;
65     alloc_uptr.name = "GmmAuxPageTable";
66     alloc_uptr.addr = userptr;
67     alloc_uptr.tiling_mode = TILING_NONE;
68     alloc_uptr.stride = size;
69     alloc_uptr.size = size;
70 
71     lbo = mos_bo_alloc_userptr(bm, &alloc_uptr);
72     if (lbo == nullptr)
73     {
74         MOS_FreeMemory(userptr);
75         return -EAGAIN;
76     }
77 
78     mos_bo_set_softpin(lbo);
79 
80     *bo = lbo;
81     *cpuAddr = userptr;
82     *gpuAddr = (uint64_t)lbo->offset64;
83 
84     return 0;
85 }
86 
87 //!
88 //! \brief  Implementation of device callback for GMM PageTableMgr to free allocated BO
89 //!
90 //! \param  [in] bo
91 //!         Poiner to the bo object to be freed
92 //!
93 //! \return none
94 //!
DeallocateCb(void * bo)95 static void DeallocateCb(void *bo)
96 {
97     mos_linux_bo  *lbo = (mos_linux_bo *)bo;
98     if (lbo != nullptr)
99     {
100         void* virt = lbo->virt;
101 
102         mos_bo_wait_rendering(lbo);
103         mos_bo_unreference(lbo);
104         if (virt)
105         {
106             MOS_FreeMemory(virt);
107         }
108     }
109 }
110 
111 //!
112 //! \brief  Implementation of device callback for GMM PageTableMgr to wait BO idle
113 //!
114 //! \param  [in] bo
115 //!         Poiner to the bo object to be waited
116 //!
117 //! \return none
118 //!
WaitFromCpuCb(void * bo)119 static void WaitFromCpuCb(void *bo)
120 {
121     mos_linux_bo  *lbo = (mos_linux_bo *)bo;
122     if (lbo != nullptr)
123     {
124         mos_bo_wait_rendering((mos_linux_bo *)bo);
125     }
126 }
127 
AuxTableMgr(MOS_BUFMGR * bufMgr,GMM_CLIENT_CONTEXT * gmmClientContext)128 AuxTableMgr::AuxTableMgr(MOS_BUFMGR *bufMgr, GMM_CLIENT_CONTEXT *gmmClientContext)
129 {
130     if (bufMgr)
131     {
132         GMM_DEVICE_CALLBACKS_INT deviceCb = {0};
133 
134         m_gmmClientContext = gmmClientContext;
135         if (m_gmmClientContext == nullptr)
136         {
137             MOS_OS_ASSERTMESSAGE(" nullptr returned by GmmCreateClientContext");
138         }
139         else
140         {
141             deviceCb.pBufMgr = bufMgr;
142             deviceCb.DevCbPtrs_.pfnAllocate = AllocateCb;
143             deviceCb.DevCbPtrs_.pfnDeallocate = DeallocateCb;
144             deviceCb.DevCbPtrs_.pfnWaitFromCpu = WaitFromCpuCb;
145 
146             m_gmmPageTableMgr = m_gmmClientContext->CreatePageTblMgrObject(&deviceCb, AUXTT);
147             if (m_gmmPageTableMgr == nullptr)
148             {
149                 MOS_OS_ASSERTMESSAGE(" nullptr returned by new GMM_PAGETABLE_MGR");
150             }
151         }
152     }
153 }
154 
~AuxTableMgr()155 AuxTableMgr::~AuxTableMgr()
156 {
157     if (m_gmmPageTableMgr != nullptr)
158     {
159         m_gmmClientContext->DestroyPageTblMgrObject((GMM_PAGETABLE_MGR *)m_gmmPageTableMgr);
160         m_gmmPageTableMgr = nullptr;
161     }
162     if (m_gmmClientContext != nullptr)
163     {
164         m_gmmClientContext = nullptr;
165     }
166 }
167 
CreateAuxTableMgr(MOS_BUFMGR * bufMgr,MEDIA_FEATURE_TABLE * sku,GMM_CLIENT_CONTEXT * gmmClientContext)168 AuxTableMgr * AuxTableMgr::CreateAuxTableMgr(MOS_BUFMGR *bufMgr, MEDIA_FEATURE_TABLE *sku, GMM_CLIENT_CONTEXT *gmmClientContext)
169 {
170     if (MEDIA_IS_SKU(sku, FtrE2ECompression) && !MEDIA_IS_SKU(sku, FtrFlatPhysCCS))
171     {
172         AuxTableMgr *auxTableMgr = MOS_New(AuxTableMgr, bufMgr, gmmClientContext);
173         if (auxTableMgr == nullptr)
174         {
175             MOS_OS_ASSERTMESSAGE(" nullptr returned by creating AuxTableMgr");
176         }
177         return auxTableMgr;
178     }
179     return nullptr;
180 }
181 
MapResource(GMM_RESOURCE_INFO * gmmResInfo,MOS_LINUX_BO * bo)182 MOS_STATUS  AuxTableMgr::MapResource(GMM_RESOURCE_INFO *gmmResInfo, MOS_LINUX_BO *bo)
183 {
184     if (gmmResInfo == nullptr || bo == nullptr)
185     {
186         return MOS_STATUS_NULL_POINTER;
187     }
188 
189     GMM_RESOURCE_FLAG flags = gmmResInfo->GetResFlags();
190     if ((flags.Info.MediaCompressed || flags.Info.RenderCompressed) &&
191         (flags.Gpu.MMC && flags.Gpu.CCS)                            &&
192         (bo->aux_mapped == false))
193     {
194         int ret = 0;
195 
196         ret = mos_bo_set_softpin(bo);
197         if (ret != 0)
198         {
199             MOS_OS_ASSERTMESSAGE("Aux mapping failed: softpin failed");
200             return MOS_STATUS_UNKNOWN;
201         }
202 
203         GMM_DDI_UPDATEAUXTABLE  updateReq = {};
204 
205         updateReq.BaseResInfo = gmmResInfo;
206         updateReq.BaseGpuVA = bo->offset64;
207         updateReq.Map = 1;
208         if (GMM_SUCCESS != ((GMM_PAGETABLE_MGR *)m_gmmPageTableMgr)->UpdateAuxTable(&updateReq))
209         {
210             MOS_OS_ASSERTMESSAGE("update AuxTable failed");
211             return MOS_STATUS_UNKNOWN;
212         }
213         bo->aux_mapped = true;
214     }
215     return MOS_STATUS_SUCCESS;
216 }
217 
UnmapResource(GMM_RESOURCE_INFO * gmmResInfo,MOS_LINUX_BO * bo)218 MOS_STATUS  AuxTableMgr::UnmapResource(GMM_RESOURCE_INFO *gmmResInfo, MOS_LINUX_BO *bo)
219 {
220     if (gmmResInfo && bo && bo->aux_mapped)
221     {
222         GMM_DDI_UPDATEAUXTABLE  updateReq = {};
223 
224         MOS_OS_ASSERT(gmmResInfo->GetResFlags().Info.MediaCompressed ||
225                 gmmResInfo->GetResFlags().Info.RenderCompressed);
226 
227         updateReq.BaseResInfo   = gmmResInfo;
228         updateReq.BaseGpuVA     = bo->offset64;
229         updateReq.Map           = 0;
230         ((GMM_PAGETABLE_MGR*)m_gmmPageTableMgr)->UpdateAuxTable(&updateReq);
231         bo->aux_mapped = false;
232     }
233     return MOS_STATUS_SUCCESS;
234 }
235 
EmitAuxTableBOList(MOS_LINUX_BO * cmd_bo)236 MOS_STATUS  AuxTableMgr::EmitAuxTableBOList(MOS_LINUX_BO *cmd_bo)
237 {
238     // Retrieve aux table bo list from GMM and emit it to exec buffer bo list
239     int boCnt = ((GMM_PAGETABLE_MGR*)m_gmmPageTableMgr)->GetNumOfPageTableBOs(AUXTT);
240     if (boCnt <= 0) {
241         return MOS_STATUS_SUCCESS;
242     }
243 
244     mos_linux_bo **boList = (MOS_LINUX_BO **)MOS_AllocAndZeroMemory(boCnt * sizeof(mos_linux_bo*));
245     if (boList == nullptr)
246         return MOS_STATUS_NO_SPACE;
247 
248     ((GMM_PAGETABLE_MGR*)m_gmmPageTableMgr)->GetPageTableBOList(AUXTT, boList);
249     for (int i=0; i<boCnt; i++)
250     {
251         int ret = mos_bo_add_softpin_target(cmd_bo, boList[i], false);
252         if (ret != 0)
253         {
254             MOS_OS_ASSERTMESSAGE("Error patching alloc_bo = 0x%x, cmd_bo = 0x%x.",
255                 (uintptr_t)boList[i],
256                 (uintptr_t)cmd_bo);
257             return MOS_STATUS_UNKNOWN;
258         }
259     }
260     MOS_FreeMemory(boList);
261 
262     return MOS_STATUS_SUCCESS;
263 }
264 
GetAuxTableBase()265 uint64_t  AuxTableMgr::GetAuxTableBase()
266 {
267     return m_gmmPageTableMgr ? ((GMM_PAGETABLE_MGR*)m_gmmPageTableMgr)->GetAuxL3TableAddr() : 0;
268 }
269