1 /* Copyright (c) 2020-2022, Intel Corporation
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 * OTHER DEALINGS IN THE SOFTWARE.
20 */
21 //!
22 //! \file     vp_render_kernelset.cpp
23 //! \brief    The header file of the base class of kernel set
24 //! \details  The kernel set will include kernel generation from binary.
25 //!           It's responsible for setting up HW states and generating the SFC
26 //!           commands.
27 //!
28 #include "vp_kernelset.h"
29 #include "vp_render_fc_kernel.h"
30 #include "vp_render_l0_fc_kernel.h"
31 #include "vp_render_vebox_hdr_3dlut_kernel.h"
32 #include "vp_render_vebox_hvs_kernel.h"
33 #include "vp_render_hdr_kernel.h"
34 #include "vp_render_vebox_hdr_3dlut_l0_kernel.h"
35 
36 using namespace vp;
37 
VpKernelSet(PVP_MHWINTERFACE hwInterface,PVpAllocator allocator)38 VpKernelSet::VpKernelSet(PVP_MHWINTERFACE hwInterface, PVpAllocator allocator) :
39     m_hwInterface(hwInterface),
40     m_allocator(allocator)
41 {
42     m_pKernelPool = &hwInterface->m_vpPlatformInterface->GetKernelPool();
43 }
44 
GetKernelInfo(std::string kernelName,uint32_t kuid,uint32_t & size,void * & kernel)45 MOS_STATUS VpKernelSet::GetKernelInfo(std::string kernelName, uint32_t kuid, uint32_t& size, void*& kernel)
46 {
47     VP_FUNC_CALL();
48 
49     auto it = m_pKernelPool->find(kernelName);
50 
51     if (m_pKernelPool->end() == it)
52     {
53         VP_RENDER_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
54     }
55 
56     Kdll_State* kernelState = it->second.GetKdllState();
57 
58     if (kernelState)
59     {
60         // For FC case, the kernel binary and size are gotten during GetKernelEntry.
61         if (IDR_VP_EOT == kuid)
62         {
63             size = 0;
64             kernel = nullptr;
65         }
66         else
67         {
68             size   = kernelState->ComponentKernelCache.pCacheEntries[kuid].iSize;
69             kernel = kernelState->ComponentKernelCache.pCacheEntries[kuid].pBinary;
70         }
71         return MOS_STATUS_SUCCESS;
72     }
73     else if (kernelName == VpRenderKernel::s_kernelNameNonAdvKernels)
74     {
75         VP_PUBLIC_ASSERTMESSAGE("Kernel State not inplenmented, return error");
76         return MOS_STATUS_UNINITIALIZED;
77     }
78     else
79     {
80         size = it->second.GetKernelSize();
81         kernel = (void*)it->second.GetKernelBinPointer();
82         return MOS_STATUS_SUCCESS;
83     }
84 }
85 
86 // For Adv kernel
FindAndInitKernelObj(VpRenderKernelObj * kernelObj)87 MOS_STATUS VpKernelSet::FindAndInitKernelObj(VpRenderKernelObj* kernelObj)
88 {
89     VP_FUNC_CALL();
90 
91     VP_RENDER_CHK_NULL_RETURN(kernelObj);
92     VP_RENDER_CHK_NULL_RETURN(m_pKernelPool);
93 
94     bool bFind = false;
95     VP_RENDER_CHK_STATUS_RETURN(m_hwInterface->m_vpPlatformInterface->InitializeDelayedKernels(kernelObj->GetKernelType()));
96 
97     if (m_pKernelPool)
98     {
99         auto it = m_pKernelPool->find(kernelObj->GetKernelName());
100         if (m_pKernelPool->end() != it)
101         {
102             auto &kernel = it->second;
103             VP_RENDER_CHK_STATUS_RETURN(kernelObj->Init(kernel));
104             bFind = true;
105         }
106     }
107 
108     if (!bFind)
109     {
110         VP_RENDER_ASSERTMESSAGE("The kernel is not found!");
111         return MOS_STATUS_INVALID_PARAMETER;
112     }
113 
114     return MOS_STATUS_SUCCESS;
115 }
116 
CreateSingleKernelObject(VpRenderKernelObj * & kernel,VpKernelID kernelId,KernelIndex kernelIndex)117 MOS_STATUS VpKernelSet::CreateSingleKernelObject(
118     VpRenderKernelObj *&kernel,
119     VpKernelID kernelId,
120     KernelIndex kernelIndex)
121 {
122     VP_FUNC_CALL();
123     kernel = nullptr;
124     switch ((uint32_t)kernelId)
125     {
126     case kernelCombinedFc:
127         kernel = (VpRenderKernelObj*)MOS_New(VpRenderFcKernel, m_hwInterface, m_allocator);
128         VP_RENDER_CHK_NULL_RETURN(kernel);
129         break;
130     case kernelL0FcCommon:
131     case kernelL0FcFP:
132     case kernelL0Fc444PL3Input:
133         kernel = (VpRenderKernelObj *)MOS_New(VpRenderL0FcKernel, m_hwInterface, kernelId, kernelIndex, m_allocator);
134         VP_RENDER_CHK_NULL_RETURN(kernel);
135         break;
136     case kernelHdr3DLutCalc:
137         if (m_pKernelPool->find(VP_HDR_KERNEL_NAME_L0) != m_pKernelPool->end())
138         {
139             VP_RENDER_NORMALMESSAGE("HDR 3dlut kernel use l0 hdr_3dlut_l0 kernel");
140             kernel = (VpRenderKernelObj *)MOS_New(VpRenderHdr3DLutKernel, m_hwInterface, m_allocator);
141         }
142         else
143         {
144             VP_RENDER_NORMALMESSAGE("HDR 3dlut kernel use isa hdr_3dlut kernel");
145             kernel = (VpRenderKernelObj *)MOS_New(VpRenderHdr3DLutKernelCM, m_hwInterface, kernelId, kernelIndex, m_allocator);
146         }
147         VP_RENDER_CHK_NULL_RETURN(kernel);
148         break;
149     case kernelHdr3DLutCalcL0:
150         VP_RENDER_NORMALMESSAGE("HDR 3dlut kernel use l0 fillLutTable_3dlut kernel");
151         kernel = (VpRenderKernelObj *)MOS_New(VpRenderHdr3DLutL0Kernel, m_hwInterface, m_allocator);
152         VP_RENDER_CHK_NULL_RETURN(kernel);
153         break;
154     case kernelHVSCalc:
155         kernel = (VpRenderKernelObj *)MOS_New(VpRenderHVSKernel, m_hwInterface, kernelId, kernelIndex, m_allocator);
156         VP_RENDER_CHK_NULL_RETURN(kernel);
157         break;
158     case kernelHdrMandatory:
159         kernel = (VpRenderKernelObj *)MOS_New(VpRenderHdrKernel, m_hwInterface, m_allocator);
160         VP_RENDER_CHK_NULL_RETURN(kernel);
161         break;
162     default:
163         VP_RENDER_ASSERTMESSAGE("No supported kernel, return");
164         return MOS_STATUS_UNIMPLEMENTED;
165     }
166 
167     return MOS_STATUS_SUCCESS;
168 }
169 
CreateKernelObjects(KERNEL_PARAMS_LIST & kernelParams,VP_SURFACE_GROUP & surfacesGroup,KERNEL_SAMPLER_STATE_GROUP & samplerStateGroup,KERNEL_CONFIGS & kernelConfigs,KERNEL_OBJECTS & kernelObjs,VP_RENDER_CACHE_CNTL & surfMemCacheCtl,VP_PACKET_SHARED_CONTEXT * sharedContext)170 MOS_STATUS VpKernelSet::CreateKernelObjects(
171     KERNEL_PARAMS_LIST& kernelParams,
172     VP_SURFACE_GROUP& surfacesGroup,
173     KERNEL_SAMPLER_STATE_GROUP& samplerStateGroup,
174     KERNEL_CONFIGS& kernelConfigs,
175     KERNEL_OBJECTS& kernelObjs,
176     VP_RENDER_CACHE_CNTL& surfMemCacheCtl,
177     VP_PACKET_SHARED_CONTEXT *sharedContext)
178 {
179     VP_FUNC_CALL();
180 
181     VpRenderKernelObj* kernel = nullptr;
182 
183     auto VpStatusHandler = [&] (MOS_STATUS status)
184     {
185         if (MOS_FAILED(status))
186         {
187             if (kernel)
188             {
189                 auto it = m_cachedKernels.find(kernel->GetKernelId());
190                 if (it != m_cachedKernels.end() && it->second == kernel)
191                 {
192                     m_cachedKernels.erase(it);
193                 }
194                 MOS_Delete(kernel);
195             }
196         }
197         return status;
198     };
199 
200     kernelObjs.clear();
201 
202     for (uint32_t kernelIndex = 0; kernelIndex < kernelParams.size(); ++kernelIndex)
203     {
204         auto it = m_cachedKernels.find(kernelParams[kernelIndex].kernelId);
205         if (m_cachedKernels.end() == it)
206         {
207             VP_RENDER_CHK_STATUS_RETURN(CreateSingleKernelObject(
208                 kernel,
209                 kernelParams[kernelIndex].kernelId,
210                 kernelIndex));
211             if (kernel->IsKernelCached())
212             {
213                 m_cachedKernels.insert(std::make_pair(kernelParams[kernelIndex].kernelId, kernel));
214             }
215         }
216         else
217         {
218             kernel = it->second;
219         }
220 
221         VP_RENDER_CHK_NULL_RETURN(kernel);
222 
223         if (!kernel->IsAdvKernel())
224         {
225             void* binary = nullptr;
226             uint32_t kernelSize = 0;
227 
228             VP_RENDER_CHK_NULL_RETURN(kernel);
229 
230             VP_RENDER_CHK_STATUS_RETURN(VpStatusHandler(GetKernelInfo(kernel->GetKernelName(), kernel->GetKernelBinaryID(), kernelSize, binary)));
231 
232             VP_RENDER_CHK_STATUS_RETURN(VpStatusHandler(kernel->InitKernel(binary, kernelSize, kernelConfigs, surfacesGroup, surfMemCacheCtl)));
233 
234             kernelObjs.insert(std::make_pair(kernelIndex, kernel));
235         }
236         else
237         {
238             VP_RENDER_CHK_STATUS_RETURN(VpStatusHandler(FindAndInitKernelObj(kernel)));
239 
240             VP_RENDER_CHK_STATUS_RETURN(VpStatusHandler(kernel->SetKernelConfigs(kernelParams[kernelIndex], surfacesGroup, samplerStateGroup, kernelConfigs, sharedContext)));
241 
242             kernelObjs.insert(std::make_pair(kernelIndex, kernel));
243         }
244     }
245 
246     kernelParams.clear();
247 
248     if (kernelObjs.empty())
249     {
250         VP_RENDER_ASSERTMESSAGE("Kernel Object Fail, return Error");
251         return MOS_STATUS_NULL_POINTER;
252     }
253 
254     return MOS_STATUS_SUCCESS;
255 }