• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2017-2022, 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     vphal_renderer_g12_tgllp.cpp
24 //! \brief    VPHAL top level rendering component and the entry to low level renderers
25 //! \details  The top renderer is responsible for coordinating the sequence of calls to low level renderers, e.g. DNDI or Comp
26 //!
27 #include "vphal_renderer_g12_tgllp.h"
28 #include "vp_debug.h"
29 #if defined(ENABLE_KERNELS)
30 #include "igvpkrn_g12_tgllp_cmfc.h"
31 #include "igvpkrn_g12_tgllp_cmfcpatch.h"
32 #endif
33 
34 extern const Kdll_RuleEntry         g_KdllRuleTable_g12lp[];
35 extern const Kdll_RuleEntry         g_KdllRuleTable_g12lpcmfc[];
36 
InitKdllParam()37 MOS_STATUS VphalRendererG12Tgllp::InitKdllParam()
38 {
39     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
40 
41     // Override kernel binary for CMFC/SWSB
42     if (bEnableCMFC)
43     {
44 #if defined(ENABLE_KERNELS)
45         pKernelDllRules     = g_KdllRuleTable_g12lpcmfc;
46         pcKernelBin         = (const void *)IGVPKRN_G12_TGLLP_CMFC;
47         dwKernelBinSize     = IGVPKRN_G12_TGLLP_CMFC_SIZE;
48         pcFcPatchBin        = (const void *)IGVPKRN_G12_TGLLP_CMFCPATCH;
49         dwFcPatchBinSize    = IGVPKRN_G12_TGLLP_CMFCPATCH_SIZE;
50 #endif
51     }
52 
53     if ((NULL == pcFcPatchBin) || (0 == dwFcPatchBinSize))
54     {
55         bEnableCMFC = false;
56     }
57 
58     if (bEnableCMFC && (NULL != pcFcPatchBin) && (0 != dwFcPatchBinSize))
59     {
60         m_pRenderHal->bEnableP010SinglePass = true;
61     }
62     else
63     {
64         m_pRenderHal->bEnableP010SinglePass = false;
65     }
66 
67     return eStatus;
68 }
69 
70 //!
71 //! \brief    Main render function
72 //! \details  The top level renderer function, which may contain multiple
73 //!           passes of rendering
74 //! \param    [in] pcRenderParams
75 //!           Const pointer to VPHAL render parameter
76 //! \return   MOS_STATUS
77 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
78 //!
Render(PCVPHAL_RENDER_PARAMS pcRenderParams)79 MOS_STATUS VphalRendererG12Tgllp::Render(
80     PCVPHAL_RENDER_PARAMS   pcRenderParams)
81 {
82     MOS_STATUS              eStatus;
83     PMOS_INTERFACE          pOsInterface;
84     PRENDERHAL_INTERFACE    pRenderHal;
85     VPHAL_RENDER_PARAMS     RenderParams;                                       // Make a copy of render params
86     PVPHAL_SURFACE          pSrcLeft[VPHAL_MAX_SOURCES];                        // Array of sources referring to left view stereo content
87     PVPHAL_SURFACE          pSrcRight[VPHAL_MAX_SOURCES];                       // Array of sources referring to right view stereo content
88     uint32_t                uiRenderPasses;                                     // Number of rendering passes in this one call to VpHal_RndrRender()
89     uint32_t                uiCurrentRenderPass;                                // Current render pass
90     uint32_t                uiDst;
91     VPHAL_GET_SURFACE_INFO  Info;
92 
93     //--------------------------------------------
94     VPHAL_RENDER_ASSERT(pcRenderParams);
95     VPHAL_RENDER_ASSERT(m_pOsInterface);
96     VPHAL_RENDER_ASSERT(m_pRenderHal);
97     VPHAL_RENDER_ASSERT(pKernelDllState);
98     VPHAL_RENDER_ASSERT(pRender[VPHAL_RENDER_ID_COMPOSITE]);
99     //--------------------------------------------
100 
101     eStatus         = MOS_STATUS_SUCCESS;
102     pOsInterface    = m_pOsInterface;
103     pRenderHal      = m_pRenderHal;
104 
105     // Validate render target
106     if (pcRenderParams->pTarget[0] == nullptr ||
107         Mos_ResourceIsNull(&(pcRenderParams->pTarget[0]->OsResource)))
108     {
109         VPHAL_RENDER_ASSERTMESSAGE("Invalid Render Target.");
110         eStatus = MOS_STATUS_UNKNOWN;
111         goto finish;
112     }
113 
114     // Protection mechanism, Only SKL+ support P010 output.
115     if (IsFormatSupported(pcRenderParams) == false)
116     {
117         VPHAL_RENDER_ASSERTMESSAGE("Invalid Render Target Output Format.");
118         eStatus = MOS_STATUS_UNKNOWN;
119         goto finish;
120     }
121 
122     VPHAL_DBG_STATE_DUMP_SET_CURRENT_FRAME_COUNT(uiFrameCounter);
123 
124     // Validate max number sources
125     if (pcRenderParams->uSrcCount > VPHAL_MAX_SOURCES)
126     {
127         VPHAL_RENDER_ASSERTMESSAGE("Invalid number of samples.");
128         eStatus = MOS_STATUS_UNKNOWN;
129         goto finish;
130     }
131 
132     // Validate max number targets
133     if (pcRenderParams->uDstCount > VPHAL_MAX_TARGETS)
134     {
135         VPHAL_RENDER_ASSERTMESSAGE("Invalid number of targets.");
136         eStatus = MOS_STATUS_UNKNOWN;
137         goto finish;
138     }
139 
140     // Copy the Render Params structure (so we can update it)
141     RenderParams = *pcRenderParams;
142 
143     VPHAL_DBG_PARAMETERS_DUMPPER_DUMP_XML(&RenderParams);
144     VPHAL_DBG_OCA_DUMPER_SET_RENDER_PARAM(pRenderHal, &RenderParams);
145 
146     // Get resource information for render target
147     MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
148 
149     for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
150     {
151         VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
152             m_pOsInterface,
153             &Info,
154             RenderParams.pTarget[uiDst]));
155     }
156 
157     // Set the component info
158     m_pOsInterface->Component = pcRenderParams->Component;
159 
160     // Init component(DDI entry point) info for perf measurement
161     m_pOsInterface->pfnSetPerfTag(m_pOsInterface, VPHAL_NONE);
162 
163     // Increment frame ID for performance measurement
164     m_pOsInterface->pfnIncPerfFrameID(m_pOsInterface);
165 
166     // Enable Turbo mode if sku present and DDI requests it
167     if (m_pSkuTable && MEDIA_IS_SKU(m_pSkuTable, FtrMediaTurboMode))
168     {
169         m_pRenderHal->bTurboMode = RenderParams.bTurboMode;
170     }
171 
172     // Reset feature reporting
173     m_reporting->InitReportValue();
174 
175     MOS_ZeroMemory(pSrcLeft,  sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
176     MOS_ZeroMemory(pSrcRight, sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
177 
178     VPHAL_RENDER_CHK_STATUS(PrepareSources(
179             &RenderParams,
180             pSrcLeft,
181             pSrcRight,
182             &uiRenderPasses));
183 
184     //set GpuContext
185     VPHAL_RENDER_CHK_STATUS(SetRenderGpuContext(RenderParams));
186 
187     // align rectangle and source surface
188     for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
189     {
190         VPHAL_RENDER_CHK_STATUS(VpHal_RndrRectSurfaceAlignment(RenderParams.pTarget[uiDst], RenderParams.pTarget[uiDst]->Format));
191     }
192 
193     for (uiCurrentRenderPass = 0;
194          uiCurrentRenderPass < uiRenderPasses;
195          uiCurrentRenderPass++)
196     {
197         // Assign source surfaces for current rendering pass
198         MOS_SecureMemcpy(
199             RenderParams.pSrc,
200             sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES,
201             (uiCurrentRenderPass == 0) ? pSrcLeft : pSrcRight,
202             sizeof(PVPHAL_SURFACE) * VPHAL_MAX_SOURCES);
203 
204         MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
205 
206         for (uiDst = 0; uiDst < RenderParams.uDstCount; uiDst++)
207         {
208             Info.S3dChannel = RenderParams.pTarget[uiDst]->Channel;
209             Info.ArraySlice = uiCurrentRenderPass;
210 
211             VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
212                 m_pOsInterface,
213                 &Info,
214                 RenderParams.pTarget[uiDst]));
215         }
216 
217         // Update channel. 0 = mono or stereo left, 1 = stereo right
218         uiCurrentChannel = uiCurrentRenderPass;
219 
220         VPHAL_RENDER_CHK_STATUS(RenderScaling(&RenderParams));
221 
222         VPHAL_RENDER_CHK_STATUS(RenderPass(&RenderParams));
223     }
224 
225 finish:
226     uiFrameCounter++;
227     return eStatus;
228 }
229 
230 //!
231 //! \brief    set Render Gpu Context
232 //! \details  set Render Gpu Context based on lumakey and CCS status.
233 //! \param    [in] RenderParams
234 //!           VPHAL render parameter
235 //! \return   MOS_STATUS
236 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
237 //!
SetRenderGpuContext(VPHAL_RENDER_PARAMS & RenderParams)238 MOS_STATUS VphalRendererG12Tgllp::SetRenderGpuContext(VPHAL_RENDER_PARAMS& RenderParams)
239 {
240     MOS_GPU_CONTEXT currentGpuContext = m_pOsInterface->pfnGetGpuContext(m_pOsInterface);
241     bool            bLumaKeyEnabled = false;
242 
243     for (uint32_t uiSources = 0; uiSources < RenderParams.uSrcCount; uiSources++)
244     {
245         VPHAL_SURFACE* pSrc = (VPHAL_SURFACE*)RenderParams.pSrc[uiSources];
246         bLumaKeyEnabled = (pSrc && pSrc->pLumaKeyParams) ? true : false;
247         if (bLumaKeyEnabled)
248         {
249             break;
250         }
251     }
252     if (bLumaKeyEnabled)
253     {
254         currentGpuContext = MOS_GPU_CONTEXT_RENDER;
255     }
256     UpdateRenderGpuContext(currentGpuContext);
257 
258     return MOS_STATUS_SUCCESS;
259 }
260 
261 //!
262 //! \brief    Scaling function
263 //! \details  The scaling function is only for scaling without other VP features.
264 //!           Down scaling needs 2 pass if scaling ratio is >2 for better quality.
265 //!           Pass#1 DS to 1/2 target resolution; Pass #2: DS from 1/2 target resolution to target resolution
266 //! \param    [in,out] pRenderParams
267 //!           Pointer to VPHAL render parameter
268 //! \return   MOS_STATUS
269 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
270 //!
RenderScaling(PVPHAL_RENDER_PARAMS pRenderParams)271 MOS_STATUS VphalRendererG12Tgllp::RenderScaling(
272     PVPHAL_RENDER_PARAMS    pRenderParams)
273 {
274     MOS_STATUS                  eStatus                 = MOS_STATUS_SUCCESS;
275     PVPHAL_SURFACE              pSource                 = nullptr;              // Pointer to the primary and original source surface
276     PVPHAL_SURFACE              pTarget                 = nullptr;              // Pointer to the target surface
277     float                       fScaleX                 = 0.0;                  // The original scaling ratio in X axis
278     float                       fScaleY                 = 0.0;                  // the original scaling ratio in Y axis
279     PLATFORM                    Platform                = {};
280     bool                        bScalingFirst           = false;                // Need to scaling first or not?
281     bool                        b2PassScaling           = false;                // 2 Pass scaling
282     uint32_t                    dwAllocatedWidth        = 1280;                 // The width of intermediate surfaces
283     uint32_t                    dwAllocatedHeight       = 720;                  // The height of intermediate surfaces
284     RECT                        rectScalingRegion       = {0, 0, 1280, 720};    // Scaling region of down scaling
285     VPHAL_RENDER_PARAMS         renderParams            = {};
286     VPHAL_SURFACE               inputSurface            = {};
287     PVPHAL_3DLUT_PARAMS         p3DLutParams            = nullptr;
288     PVPHAL_SURFACE              pDSSurface              = nullptr;              // Always point to the down scaled surface
289     uint32_t                    dwHalfInWidth           = 1280;                 // Half of the processed input width
290     uint32_t                    dwHalfInHeight          = 720;                  // Half of the processed input height
291     RECT                        rectHalfInRegion        = {0, 0, 1280, 720};    // Half of the processed input region
292 
293     VPHAL_RENDER_CHK_NULL(pRenderParams);
294     VPHAL_RENDER_CHK_NULL(pRenderParams->pSrc);
295     VPHAL_RENDER_CHK_NULL(pRenderParams->pTarget);
296     VPHAL_RENDER_CHK_NULL(m_pSkuTable);
297     VPHAL_RENDER_CHK_NULL(m_pOsInterface);
298 
299     // Limited to 1 input and 1 output. If not 1->1, fall back to the typical video processing path.
300     if ((pRenderParams->uSrcCount != 1) || (pRenderParams->uDstCount != 1))
301     {
302         VPHAL_RENDER_NORMALMESSAGE(" Source Count %d, Destination Count %d", pRenderParams->uSrcCount, pRenderParams->uDstCount);
303         eStatus = MOS_STATUS_SUCCESS;
304         goto finish;
305     }
306 
307     pSource     = pRenderParams->pSrc[0];
308     pTarget     = pRenderParams->pTarget[0];
309     VPHAL_RENDER_CHK_NULL(pSource);
310     VPHAL_RENDER_CHK_NULL(pTarget);
311 
312     // Calculating the scaling ratio
313     fScaleX = (float)(pSource->rcDst.right - pSource->rcDst.left) /
314               (float)(pSource->rcSrc.right - pSource->rcSrc.left);
315     fScaleY = (float)(pSource->rcDst.bottom - pSource->rcDst.top) /
316               (float)(pSource->rcSrc.bottom - pSource->rcSrc.top);
317     b2PassScaling = (fScaleX < 0.5f) && (fScaleY < 0.5f);
318 
319     // Scaling first, then other VP features. It is only enabled on DG1 with 3DLUT enabled if down scaling as of now.
320     m_pOsInterface->pfnGetPlatform(m_pOsInterface, &Platform);
321     bScalingFirst = MEDIA_IS_SKU(m_pSkuTable, FtrScalingFirst) &&
322                     ((Platform.usDeviceID == 0x4905)           ||
323                      (Platform.usDeviceID == 0x4906)           ||
324                      (Platform.usDeviceID == 0x4907)           ||
325                      (Platform.usDeviceID == 0x4908))          &&
326                      (pSource->p3DLutParams != nullptr)        &&
327                      (fScaleX < 1.0f && fScaleY < 1.0f);
328 
329     // If no need to scaling firstly, fall back to the typical video processing path.
330     if (!bScalingFirst)
331     {
332         eStatus = MOS_STATUS_SUCCESS;
333         goto finish;
334     }
335 
336     // Do the down scaling firstly, then 3DLUT VEBOX features.
337     // Allocate down scaling surfaces
338     for (uint32_t nIndex = 0; nIndex < VPHAL_MAX_NUM_DS_SURFACES; nIndex++)
339     {
340          if (m_pDSSurface[nIndex] == nullptr)
341          {
342              m_pDSSurface[nIndex] = (PVPHAL_SURFACE)MOS_AllocAndZeroMemory(sizeof(VPHAL_SURFACE));
343              VPHAL_RENDER_CHK_NULL(m_pDSSurface[nIndex]);
344          }
345     }
346 
347     // Calculate the size of processing region for 2 pass downscaling
348     dwHalfInWidth                   = (uint32_t)((0.5) * (float)(pSource->rcSrc.right - pSource->rcSrc.left));
349     dwHalfInHeight                  = (uint32_t)((0.5) * (float)(pSource->rcSrc.bottom- pSource->rcSrc.top));
350     dwHalfInWidth                   = MOS_ALIGN_CEIL(dwHalfInWidth, 4);
351     dwHalfInHeight                  = MOS_ALIGN_CEIL(dwHalfInHeight, 4);
352     rectHalfInRegion.top            = 0;
353     rectHalfInRegion.left           = 0;
354     rectHalfInRegion.right          = dwHalfInWidth;
355     rectHalfInRegion.bottom         = dwHalfInHeight;
356 
357     // Allocate intermediate surface for the first pass
358     dwAllocatedWidth                = MOS_MAX(dwHalfInWidth, pTarget->dwWidth);
359     dwAllocatedHeight               = MOS_MAX(dwHalfInHeight, pTarget->dwHeight);
360     VPHAL_RENDER_CHK_STATUS(AllocateSurface(pRenderParams, pSource, m_pDSSurface[0], dwAllocatedWidth, dwAllocatedHeight, pSource->Format));
361     // First pass scaling
362     {
363         // Use inputSurface instead of the pointer of the original input to keep it unchanged.
364         rectScalingRegion               = (b2PassScaling) ? rectHalfInRegion : pSource->rcDst;
365         p3DLutParams                    = pSource->p3DLutParams;
366         renderParams                    = *pRenderParams;
367         inputSurface                    = *pSource;
368         inputSurface.p3DLutParams       = nullptr;
369         inputSurface.rcDst              = rectScalingRegion;
370         m_pDSSurface[0]->rcSrc          = rectScalingRegion;
371         m_pDSSurface[0]->rcDst          = rectScalingRegion;
372         m_pDSSurface[0]->rcMaxSrc       = rectScalingRegion;
373         renderParams.pSrc[0]            = &inputSurface;
374         renderParams.pTarget[0]         = m_pDSSurface[0];
375         VPHAL_RENDER_CHK_STATUS(RenderPass(&renderParams));
376         m_pDSSurface[0]->rcSrc          = m_pDSSurface[0]->rcDst;
377         m_pDSSurface[0]->rcMaxSrc       = m_pDSSurface[0]->rcDst;
378         m_pDSSurface[0]->rcDst          = pSource->rcDst;
379         pDSSurface                      = m_pDSSurface[0];
380     }
381 
382     // Second pass scaling
383     if (b2PassScaling)
384     {
385         dwAllocatedWidth                = pTarget->dwWidth;
386         dwAllocatedHeight               = pTarget->dwHeight;
387         VPHAL_RENDER_CHK_STATUS(AllocateSurface(pRenderParams, pSource, m_pDSSurface[1], dwAllocatedWidth, dwAllocatedHeight, pSource->Format));
388         rectScalingRegion               = pSource->rcDst;
389         m_pDSSurface[0]->rcDst          = rectScalingRegion;
390         m_pDSSurface[1]->rcDst          = rectScalingRegion;
391 
392         inputSurface                    = *m_pDSSurface[0];
393         inputSurface.p3DLutParams       = nullptr;
394         renderParams.pSrc[0]            = &inputSurface;
395         renderParams.pTarget[0]         = m_pDSSurface[1];
396         VPHAL_RENDER_CHK_STATUS(RenderPass(&renderParams));
397         m_pDSSurface[1]->rcSrc           = m_pDSSurface[1]->rcDst;
398         m_pDSSurface[1]->rcMaxSrc        = m_pDSSurface[1]->rcDst;
399         m_pDSSurface[1]->rcDst           = pSource->rcDst;
400         pDSSurface                       = m_pDSSurface[1];
401     }
402 
403     // Attach 3DLUT parameters to the down scaled surface.
404     if (pSource->p3DLutParams)
405     {
406         if (pDSSurface->p3DLutParams == nullptr)
407         {
408             pDSSurface->p3DLutParams = (PVPHAL_3DLUT_PARAMS)MOS_AllocAndZeroMemory(sizeof(VPHAL_3DLUT_PARAMS));
409             VPHAL_RENDER_CHK_NULL(pDSSurface->p3DLutParams);
410         }
411         MOS_SecureMemcpy(pDSSurface->p3DLutParams, sizeof(VPHAL_3DLUT_PARAMS), pSource->p3DLutParams, sizeof(VPHAL_3DLUT_PARAMS));
412     }
413     else
414     {
415         MOS_FreeMemory(pDSSurface->p3DLutParams);
416         pDSSurface->p3DLutParams = nullptr;
417     }
418 
419     pRenderParams->pSrc[0]  = pDSSurface;
420 
421 finish:
422     return eStatus;
423 }
424