xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/vp/hal/vphal_render_hdr_base.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2010-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      vphal_render_hdr_base.cpp
24 //! \brief     Unified VP HAL HDR Implementation
25 //!
26 //!
27 //! \file     vphal_render_hdr_base.cpp
28 //! \brief    Common interface and structure used in HDR
29 //! \details  Common interface and structure used in HDR which are platform independent
30 //!
31 
32 #include "vphal.h"
33 #include "vphal_renderer.h"
34 #include "vphal_render_hdr_base.h"
35 #include "renderhal_platform_interface.h"
36 #include "vphal_render_hdr_g9_base.h"
37 
38 
39 #if (_DEBUG || _RELEASE_INTERNAL)
40 static bool sEnableKernelDump = false;
41 #endif
42 
43 //!
44 //! \brief    Initialize HDR state
45 //! \details  Initialize HDR state
46 //! \param    PVPHAL_HDR_STATE pHdrState
47 //!           [in,out] HDR State pointer
48 //! \param    const VphalSettings* pSettings
49 //!           [in] Pointer to VPHAL Setting
50 //! \param    Kdll_KernelCache * pKernelCache
51 //!           [in] Pointer to kernel cache
52 //! \return   void
53 //!
VpHal_HdrInitialize(PVPHAL_HDR_STATE pHdrState,const VphalSettings * pSettings,Kdll_State * pKernelDllState)54 MOS_STATUS VpHal_HdrInitialize(
55     PVPHAL_HDR_STATE         pHdrState,
56     const VphalSettings      *pSettings,
57     Kdll_State               *pKernelDllState)
58 {
59     int32_t    i;
60     uint32_t   dwSize = 0;
61     bool       bAllocated = false;
62     MOS_NULL_RENDERING_FLAGS    NullRenderingFlags;
63     MOS_STATUS                  eStatus;
64     PRENDERHAL_INTERFACE        pRenderHal;
65     MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
66 
67     eStatus = MOS_STATUS_SUCCESS;
68 
69     VPHAL_PUBLIC_CHK_NULL(pHdrState);
70     VPHAL_PUBLIC_CHK_NULL(pHdrState->pOsInterface);
71     VPHAL_PUBLIC_CHK_NULL(pHdrState->pSkuTable);
72     VPHAL_PUBLIC_CHK_NULL(pKernelDllState);
73 
74     NullRenderingFlags          =
75                     pHdrState->pOsInterface->pfnGetNullHWRenderFlags(pHdrState->pOsInterface);
76     pHdrState->bNullHwRenderHdr = false;
77     pRenderHal                  = pHdrState->pRenderHal;
78 
79     VPHAL_PUBLIC_CHK_NULL(pRenderHal);
80 
81     // Setup disable render flag controlled by a user feature key for validation purpose
82     pHdrState->bDisableRender = (pSettings->disableHdr) ? true : false;
83 
84     // Setup interface to KDLL
85     pHdrState->pKernelCache   = &pKernelDllState->ComponentKernelCache;
86 
87     eStatus = MOS_STATUS_SUCCESS;
88 
89     pHdrState->uiSplitFramePortions = 1;
90 
91     // If user set the user feature key, then the uiSplitFramePortions specified will always be used,
92     // no matter HW support preemption or not.
93     // If it is not set, and HW doesn't support preemption, then the split portions
94     // will be calculted based on resolution.
95     if (!pHdrState->bForceSplitFrame)
96     {
97         if (MEDIA_IS_SKU(pHdrState->pSkuTable, FtrMediaMidBatchPreempt) ||
98             MEDIA_IS_SKU(pHdrState->pSkuTable, FtrMediaThreadGroupLevelPreempt) ||
99             MEDIA_IS_SKU(pHdrState->pSkuTable, FtrMediaMidThreadLevelPreempt))
100         {
101             pHdrState->uiSplitFramePortions = 1;
102             pHdrState->bForceSplitFrame     = true;
103         }
104     }
105 
106     pHdrState->bFtrComputeWalker = false;
107     pHdrState->uiSplitFramePortions = 1;
108 
109     pHdrState->bVeboxpreprocessed = false;
110 
111     VpHal_HdrInitInterface_g9(pHdrState);            // Total number of slices
112 
113 finish:
114     return eStatus;
115 }
116 
117 //!
118 //! \brief    Destroy HDR state
119 //! \details  Release local resources.
120 //! \param    PVPHAL_HDR_STATE pHdrState
121 //!           [in] Pointer to HDR state
122 //! \return   MOS_STATUS
123 //!           MOS_STATUS_SUCCESS if successful, otherwise failed
124 //!
VpHal_HdrDestroy(PVPHAL_HDR_STATE pHdrState)125 MOS_STATUS VpHal_HdrDestroy(
126     PVPHAL_HDR_STATE    pHdrState)
127 {
128     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
129     VPHAL_PUBLIC_CHK_NULL(pHdrState);
130 
131     VpHal_HdrDestroyInterface_g9(pHdrState);
132 
133     // Free allocations
134     if (pHdrState->pfnFreeResources)
135     {
136         pHdrState->pfnFreeResources(pHdrState);
137     }
138 
139 finish:
140     return eStatus;
141 }
142 
143 //!
144 //! \brief    Assemble the HDR kernel per layer stages
145 //! \details  Contruct a case id from the input information, and look up the configuration entry in the table.
146 //! \param    PVPHAL_HDR_STATE pHdrState
147 //!           [in] Pointer to HDR state
148 //! \param    PVPHAL_SURFACE pSource
149 //!           [in] Pointer to source surface
150 //! \param    PVPHAL_SURFACE pTarget
151 //!           [in] Pointer to target surface
152 //! \param    HDRStageConfigEntry *pConfigEntry
153 //!           [out] Pointer to configuration entry
154 //! \return   bool
155 //!           True if find proper configuration entry, otherwise false
156 //!
Vphal_HdrToneMappingStagesAssemble(PVPHAL_HDR_STATE pHdrState,PVPHAL_SURFACE pSource,PVPHAL_SURFACE pTarget,HDRStageConfigEntry * pConfigEntry)157 static bool Vphal_HdrToneMappingStagesAssemble(
158     PVPHAL_HDR_STATE       pHdrState,
159     PVPHAL_SURFACE         pSource,
160     PVPHAL_SURFACE         pTarget,
161     HDRStageConfigEntry   *pConfigEntry)
162 {
163     HDRCaseID id = { 0 };
164 
165     VPHAL_RENDER_ASSERT(pHdrState);
166     VPHAL_RENDER_ASSERT(pSource);
167     VPHAL_RENDER_ASSERT(pTarget);
168     VPHAL_RENDER_ASSERT(pConfigEntry);
169 
170     if (!pHdrState || !pSource || !pTarget || !pConfigEntry)
171         return false;
172 
173     // Because FP16 format can represent both SDR or HDR, we need do judgement here.
174     // We need this information because we dont have unified tone mapping algorithm for various scenarios(H2S/H2H).
175     // To do this, we make two assumptions:
176     // 1. This colorspace will be set to BT709/Gamma1.0 from APP, so such information can NOT be used to check HDR.
177     // 2. If APP pass any HDR metadata, it indicates this is HDR.
178     id.InputXDR     = (pSource->pHDRParams &&
179                       ((pSource->pHDRParams->EOTF == VPHAL_HDR_EOTF_SMPTE_ST2084) || IS_RGB64_FLOAT_FORMAT(pSource->Format))) ? 1 : 0;
180     id.InputGamut   = IS_COLOR_SPACE_BT2020(pSource->ColorSpace);
181     id.OutputXDR    = (pTarget->pHDRParams &&
182                       ((pTarget->pHDRParams->EOTF == VPHAL_HDR_EOTF_SMPTE_ST2084) || IS_RGB64_FLOAT_FORMAT(pTarget->Format))) ? 1 : 0;
183     id.OutputGamut  = IS_COLOR_SPACE_BT2020(pTarget->ColorSpace);
184     id.OutputLinear = IS_RGB64_FLOAT_FORMAT(pTarget->Format) ? 1 : 0;
185 
186     if (pHdrState->pHDRStageConfigTable)
187     {
188         pConfigEntry->value = pHdrState->pHDRStageConfigTable[id.index];
189     }
190     else
191     {
192         pConfigEntry->Invalid = 1;
193     }
194 
195     if (pConfigEntry->Invalid == 1)
196     {
197         VPHAL_RENDER_ASSERTMESSAGE("Tone mapping stages assembling failed, please reexamine the usage case(case id %d)! "
198             "If it is definitely a correct usage, please add an entry in HDRStageEnableTable.", id.index);
199     }
200 
201     return (pConfigEntry->Invalid != 1);
202 }
203 
204 //!
205 //! \brief    Update per layer pipeline states and return update mask for each layer
206 //! \details  Update per layer pipeline states and return update mask for each layer
207 //! \param    PVPHAL_HDR_STATE pHdrStatee
208 //!           [in] Pointer to HDR state
209 //! \param    uint32_t* pdwUpdateMask
210 //!           [out] Pointer to update mask
211 //! \return   MOS_STATUS
212 //!
VpHal_HdrUpdatePerLayerPipelineStates(PVPHAL_HDR_STATE pHdrState,uint32_t * pdwUpdateMask)213 MOS_STATUS VpHal_HdrUpdatePerLayerPipelineStates(
214     PVPHAL_HDR_STATE    pHdrState,
215     uint32_t*           pdwUpdateMask)
216 {
217     MOS_STATUS           eStatus              = MOS_STATUS_UNKNOWN;
218     uint32_t             i                    = 0;
219     PVPHAL_SURFACE       pSrc                 = nullptr;
220     PVPHAL_SURFACE       pTarget              = nullptr;
221     VPHAL_HDR_LUT_MODE   CurrentLUTMode       = VPHAL_HDR_LUT_MODE_NONE;
222     VPHAL_GAMMA_TYPE     CurrentEOTF          = VPHAL_GAMMA_NONE;            //!< EOTF
223     VPHAL_GAMMA_TYPE     CurrentOETF          = VPHAL_GAMMA_NONE;            //!< OETF
224     VPHAL_HDR_MODE       CurrentHdrMode       = VPHAL_HDR_MODE_NONE;      //!< Hdr Mode
225     VPHAL_HDR_CCM_TYPE   CurrentCCM           = VPHAL_HDR_CCM_NONE;           //!< CCM Mode
226     VPHAL_HDR_CCM_TYPE   CurrentCCMExt1       = VPHAL_HDR_CCM_NONE;       //!< CCM Ext1 Mode
227     VPHAL_HDR_CCM_TYPE   CurrentCCMExt2       = VPHAL_HDR_CCM_NONE;       //!< CCM Ext2 Mode
228     VPHAL_HDR_CSC_TYPE   CurrentPriorCSC      = VPHAL_HDR_CSC_NONE;      //!< Prior CSC Mode
229     VPHAL_HDR_CSC_TYPE   CurrentPostCSC       = VPHAL_HDR_CSC_NONE;       //!< Post CSC Mode
230     HDRStageConfigEntry  ConfigEntry          = { 0 };
231     HDRStageEnables      StageEnables         = { 0 };
232 
233     VPHAL_RENDER_CHK_NULL(pHdrState);
234     VPHAL_RENDER_CHK_NULL(pdwUpdateMask);
235     VPHAL_PUBLIC_CHK_NULL(pHdrState->pTargetSurf[0]);
236 
237     *pdwUpdateMask = 0;
238 
239     pTarget = (PVPHAL_SURFACE)pHdrState->pTargetSurf[0];
240 
241     for (i = 0; i < VPHAL_MAX_HDR_INPUT_LAYER; i++)
242     {
243         if (pHdrState->pSrcSurf[i] == nullptr)
244         {
245             pHdrState->LUTMode[i]   = VPHAL_HDR_LUT_MODE_NONE;
246             pHdrState->EOTFGamma[i] = VPHAL_GAMMA_NONE;
247             pHdrState->OETFGamma[i] = VPHAL_GAMMA_NONE;
248             pHdrState->CCM[i]       = VPHAL_HDR_CCM_NONE;
249             pHdrState->CCMExt1[i]   = VPHAL_HDR_CCM_NONE;
250             pHdrState->CCMExt2[i]   = VPHAL_HDR_CCM_NONE;
251             pHdrState->HdrMode[i]   = VPHAL_HDR_MODE_NONE;
252             pHdrState->PriorCSC[i]  = VPHAL_HDR_CSC_NONE;
253             pHdrState->PostCSC[i]   = VPHAL_HDR_CSC_NONE;
254 
255             pHdrState->StageEnableFlags[i].value = 0;
256             MOS_ZeroMemory(&pHdrState->HDRLastFrameSourceParams[i], sizeof(VPHAL_HDR_PARAMS));
257 
258             continue;
259         }
260 
261         pSrc = (PVPHAL_SURFACE)pHdrState->pSrcSurf[i];
262 
263         CurrentLUTMode  = VPHAL_HDR_LUT_MODE_NONE;
264         CurrentEOTF     = VPHAL_GAMMA_NONE;
265         CurrentOETF     = VPHAL_GAMMA_NONE;
266         CurrentHdrMode  = VPHAL_HDR_MODE_NONE;
267         CurrentCCM      = VPHAL_HDR_CCM_NONE;
268         CurrentCCMExt1  = VPHAL_HDR_CCM_NONE;
269         CurrentCCMExt2  = VPHAL_HDR_CCM_NONE;
270         CurrentPriorCSC = VPHAL_HDR_CSC_NONE;
271         CurrentPostCSC  = VPHAL_HDR_CSC_NONE;
272 
273         if (!Vphal_HdrToneMappingStagesAssemble(pHdrState, pSrc, pTarget, &ConfigEntry))
274         {
275             eStatus = MOS_STATUS_INVALID_PARAMETER;
276             goto finish;
277         }
278 
279         CurrentHdrMode = (VPHAL_HDR_MODE)ConfigEntry.PWLF;
280         CurrentCCM     = (VPHAL_HDR_CCM_TYPE)ConfigEntry.CCM;
281         CurrentCCMExt1 = (VPHAL_HDR_CCM_TYPE)ConfigEntry.CCMExt1;
282         CurrentCCMExt2 = (VPHAL_HDR_CCM_TYPE)ConfigEntry.CCMExt2;
283 
284         // So far only enable auto mode in H2S cases.
285         if (CurrentHdrMode == VPHAL_HDR_MODE_TONE_MAPPING &&
286             pSrc->pHDRParams                              &&
287             pSrc->pHDRParams->bAutoMode                   &&
288             pSrc->SurfType == SURF_IN_PRIMARY)
289         {
290             CurrentHdrMode = VPHAL_HDR_MODE_TONE_MAPPING_AUTO_MODE;
291         }
292 
293         StageEnables.value             = 0;
294         StageEnables.CCMEnable         = (CurrentCCM     != VPHAL_HDR_CCM_NONE ) ? 1 : 0;
295         StageEnables.PWLFEnable        = (CurrentHdrMode != VPHAL_HDR_MODE_NONE) ? 1 : 0;
296         StageEnables.CCMExt1Enable     = (CurrentCCMExt1 != VPHAL_HDR_CCM_NONE ) ? 1 : 0;
297         StageEnables.CCMExt2Enable     = (CurrentCCMExt2 != VPHAL_HDR_CCM_NONE ) ? 1 : 0;
298         StageEnables.GamutClamp1Enable = ConfigEntry.GamutClamp1;
299         StageEnables.GamutClamp2Enable = ConfigEntry.GamutClamp2;
300 
301         if (IS_YUV_FORMAT(pSrc->Format) || IS_ALPHA_YUV_FORMAT(pSrc->Format))
302         {
303             StageEnables.PriorCSCEnable = 1;
304         }
305 
306         if (!IS_RGB64_FLOAT_FORMAT(pSrc->Format) &&
307             (StageEnables.CCMEnable || StageEnables.PWLFEnable || StageEnables.CCMExt1Enable || StageEnables.CCMExt2Enable))
308         {
309             StageEnables.EOTFEnable = 1;
310         }
311 
312         if (!IS_RGB64_FLOAT_FORMAT(pTarget->Format) && (StageEnables.EOTFEnable || IS_RGB64_FLOAT_FORMAT(pSrc->Format)))
313         {
314             StageEnables.OETFEnable = 1;
315         }
316 
317         if (IS_YUV_FORMAT(pTarget->Format))
318         {
319             StageEnables.PostCSCEnable = 1;
320         }
321 
322         if (pSrc->SurfType == SURF_IN_PRIMARY && pHdrState->GlobalLutMode != VPHAL_HDR_LUT_MODE_3D)
323         {
324             CurrentLUTMode = VPHAL_HDR_LUT_MODE_2D;
325         }
326         else
327         {
328             CurrentLUTMode = VPHAL_HDR_LUT_MODE_3D;
329         }
330 
331         // Neither 1D nor 3D LUT is needed in linear output case.
332         if (IS_RGB64_FLOAT_FORMAT(pHdrState->pTargetSurf[0]->Format))
333         {
334             CurrentLUTMode = VPHAL_HDR_LUT_MODE_NONE;
335         }
336 
337         // EOTF/CCM/Tone Mapping/OETF require RGB input
338         // So if prior CSC is needed, it will always be YUV to RGB conversion
339         if (StageEnables.PriorCSCEnable)
340         {
341             if (pSrc->ColorSpace == CSpace_BT601)
342             {
343                 CurrentPriorCSC = VPHAL_HDR_CSC_YUV_TO_RGB_BT601;
344             }
345             else if (pSrc->ColorSpace == CSpace_BT709)
346             {
347                 CurrentPriorCSC = VPHAL_HDR_CSC_YUV_TO_RGB_BT709;
348             }
349             else if (pSrc->ColorSpace == CSpace_BT2020)
350             {
351                 CurrentPriorCSC = VPHAL_HDR_CSC_YUV_TO_RGB_BT2020;
352             }
353             else if (pSrc->ColorSpace == CSpace_BT2020_FullRange)
354             {
355                 CurrentPriorCSC = VPHAL_HDR_CSC_YUV_TO_RGB_BT2020;
356             }
357             else
358             {
359                 VPHAL_RENDER_ASSERTMESSAGE("Color Space %d Not found.", pSrc->ColorSpace);
360                 eStatus = MOS_STATUS_INVALID_PARAMETER;
361                 goto finish;
362             }
363         }
364 
365         if (StageEnables.EOTFEnable)
366         {
367             if ((!pSrc->pHDRParams) ||
368                 (pSrc->pHDRParams &&
369                  (pSrc->pHDRParams->EOTF == VPHAL_HDR_EOTF_TRADITIONAL_GAMMA_SDR ||
370                   pSrc->pHDRParams->EOTF == VPHAL_HDR_EOTF_TRADITIONAL_GAMMA_HDR)))
371             {
372                 // Mark tranditional HDR/SDR gamma as the same type
373                 CurrentEOTF = VPHAL_GAMMA_TRADITIONAL_GAMMA;
374             }
375             else if (pSrc->pHDRParams &&
376                      pSrc->pHDRParams->EOTF == VPHAL_HDR_EOTF_SMPTE_ST2084)
377             {
378                 CurrentEOTF = VPHAL_GAMMA_SMPTE_ST2084;
379             }
380             else if (pSrc->pHDRParams &&
381                      pSrc->pHDRParams->EOTF == VPHAL_HDR_EOTF_BT1886)
382             {
383                 CurrentEOTF = VPHAL_GAMMA_BT1886;
384             }
385             else
386             {
387                 VPHAL_RENDER_ASSERTMESSAGE("Invalid EOTF setting for tone mapping");
388                 eStatus = MOS_STATUS_INVALID_PARAMETER;
389                 goto finish;
390             }
391         }
392 
393         if (StageEnables.OETFEnable)
394         {
395             if ((!pTarget->pHDRParams) ||
396                 (pTarget->pHDRParams &&
397                  (pTarget->pHDRParams->EOTF == VPHAL_HDR_EOTF_TRADITIONAL_GAMMA_SDR ||
398                   pTarget->pHDRParams->EOTF == VPHAL_HDR_EOTF_TRADITIONAL_GAMMA_HDR)))
399             {
400                 CurrentOETF = VPHAL_GAMMA_SRGB;
401             }
402             else if (pTarget->pHDRParams &&
403                      pTarget->pHDRParams->EOTF == VPHAL_HDR_EOTF_SMPTE_ST2084)
404             {
405                 CurrentOETF = VPHAL_GAMMA_SMPTE_ST2084;
406             }
407             else
408             {
409                 VPHAL_RENDER_ASSERTMESSAGE("Invalid EOTF setting for tone mapping");
410                 eStatus = MOS_STATUS_INVALID_PARAMETER;
411                 goto finish;
412             }
413         }
414 
415         // OETF will output RGB surface
416         // So if post CSC is needed, it will always be RGB to YUV conversion
417         if (StageEnables.PostCSCEnable)
418         {
419             if (pTarget->ColorSpace == CSpace_BT601)
420             {
421                 CurrentPostCSC = VPHAL_HDR_CSC_RGB_TO_YUV_BT601;
422             }
423             else if (pTarget->ColorSpace == CSpace_BT709)
424             {
425                 CurrentPostCSC = VPHAL_HDR_CSC_RGB_TO_YUV_BT709;
426             }
427             else if (pTarget->ColorSpace == CSpace_BT709_FullRange)
428             {
429                 // CSC for target BT709_FULLRANGE is only exposed to Vebox Preprocessed HDR cases.
430                 CurrentPostCSC = VPHAL_HDR_CSC_RGB_TO_YUV_BT709_FULLRANGE;
431             }
432             else if (pTarget->ColorSpace == CSpace_BT2020 ||
433                      pTarget->ColorSpace == CSpace_BT2020_FullRange)
434             {
435                 CurrentPostCSC = VPHAL_HDR_CSC_RGB_TO_YUV_BT2020;
436             }
437             else
438             {
439                 VPHAL_RENDER_ASSERTMESSAGE("Color Space %d Not found.", pTarget->ColorSpace);
440                 eStatus = MOS_STATUS_INVALID_PARAMETER;
441                 goto finish;
442             }
443         }
444 
445         if (pHdrState->LUTMode[i]   != CurrentLUTMode  ||
446             pHdrState->EOTFGamma[i] != CurrentEOTF     ||
447             pHdrState->OETFGamma[i] != CurrentOETF     ||
448             pHdrState->CCM[i]       != CurrentCCM      ||
449             pHdrState->CCMExt1[i]   != CurrentCCMExt1  ||
450             pHdrState->CCMExt2[i]   != CurrentCCMExt2  ||
451             pHdrState->HdrMode[i]   != CurrentHdrMode  ||
452             pHdrState->PriorCSC[i]  != CurrentPriorCSC ||
453             pHdrState->PostCSC[i]   != CurrentPostCSC)
454         {
455             *pdwUpdateMask |= (1 << i);
456         }
457 
458         if (pSrc->pHDRParams)
459         {
460             if (memcmp(pSrc->pHDRParams, &pHdrState->HDRLastFrameSourceParams[i], sizeof(VPHAL_HDR_PARAMS)))
461             {
462                 *pdwUpdateMask |= (1 << i);
463                 pHdrState->HDRLastFrameSourceParams[i] = *pSrc->pHDRParams;
464             }
465         }
466         else
467         {
468             MOS_ZeroMemory(&pHdrState->HDRLastFrameSourceParams[i], sizeof(VPHAL_HDR_PARAMS));
469         }
470 
471         pHdrState->LUTMode[i]          = CurrentLUTMode;
472         pHdrState->EOTFGamma[i]        = CurrentEOTF;
473         pHdrState->OETFGamma[i]        = CurrentOETF;
474         pHdrState->CCM[i]              = CurrentCCM;
475         pHdrState->CCMExt1[i]          = CurrentCCMExt1;
476         pHdrState->CCMExt2[i]          = CurrentCCMExt2;
477         pHdrState->HdrMode[i]          = CurrentHdrMode;
478         pHdrState->PriorCSC[i]         = CurrentPriorCSC;
479         pHdrState->PostCSC[i]          = CurrentPostCSC;
480         pHdrState->StageEnableFlags[i] = StageEnables;
481     }
482 
483     if (pTarget->pHDRParams)
484     {
485         if (memcmp(pTarget->pHDRParams, &pHdrState->HDRLastFrameTargetParams, sizeof(VPHAL_HDR_PARAMS)))
486         {
487             *pdwUpdateMask |= (1 << VPHAL_MAX_HDR_INPUT_LAYER);
488             pHdrState->HDRLastFrameTargetParams = *pTarget->pHDRParams;
489         }
490     }
491     else
492     {
493         MOS_ZeroMemory(&pHdrState->HDRLastFrameTargetParams, sizeof(VPHAL_HDR_PARAMS));
494     }
495     pHdrState->dwUpdateMask = *pdwUpdateMask;
496     eStatus = MOS_STATUS_SUCCESS;
497 
498 finish:
499     return eStatus;
500 }
501 
502 //!
503 //! \brief    Checks to see if HDR is needed and supported
504 //! \details  Checks to see if HDR is needed and supported
505 //! \param    pRenderer
506 //            [in] Pointer to VphalRenderer
507 //! \param    pBeNeeded
508 //!           [out] 1 Needed 0 not Needed
509 //! \return   MOS_STATUS
510 //!           MOS_STATUS_SUCCESS if successful, otherwise failed
511 //!
VpHal_HdrIsNeeded(VphalRenderer * pRenderer,bool * pBeNeeded)512 MOS_STATUS VpHal_HdrIsNeeded(
513     VphalRenderer         *pRenderer,
514     bool*                  pBeNeeded)
515 {
516     MOS_STATUS                  eStatus;
517     eStatus = MOS_STATUS_SUCCESS;
518 
519     VPHAL_PUBLIC_CHK_NULL(pRenderer);
520     VPHAL_PUBLIC_CHK_NULL(pBeNeeded);
521 
522     // Check whether Hdr is supported by platform
523     if (!MEDIA_IS_SKU(pRenderer->GetSkuTable(), FtrHDR) ||
524          pRenderer->pHdrState->bDisableRender)
525     {
526         *pBeNeeded = false;
527         VPHAL_RENDER_ASSERTMESSAGE("Hdr not enabled or disabled for this platform.");
528         goto finish;
529     }
530 
531     *pBeNeeded = true;
532 
533 finish:
534     return eStatus;
535 }
536 
537 //!
538 //! \brief    Set up HDR Render Data
539 //! \details  Set up HDR render data, including kernel information, input surface's block size
540 //! \param    PVPHAL_HDR_STATE pHdrState
541 //!           [in] Pointer to HDR state
542 //! \param    PVPHAL_HDR_RENDER_DATA pRenderData
543 //!           [out] Pointer to HDR render data
544 //! \param    int32_t iKUID
545 //!           [in] Kernel unique ID
546 //! \param    int32_t iKDTIndex
547 //            [in] KDT index.
548 //! \return   MOS_STATUS
549 //!           MOS_STATUS_SUCCESS if successful, otherwise failed
550 //!
VpHal_HdrSetupRenderData(PVPHAL_HDR_STATE pHdrState,PVPHAL_HDR_RENDER_DATA pRenderData,int32_t iKUID,int32_t iKDTIndex)551 MOS_STATUS VpHal_HdrSetupRenderData(
552     PVPHAL_HDR_STATE        pHdrState,
553     PVPHAL_HDR_RENDER_DATA  pRenderData,
554     int32_t                 iKUID,
555     int32_t                 iKDTIndex)
556 {
557     int32_t                         iBlockWd;                                       // Block width
558     int32_t                         iBlockHt;                                       // Block Height
559     MOS_STATUS                      eStatus;                                        // Return code
560     PRENDERHAL_INTERFACE            pRenderHal;
561     Kdll_CacheEntry                 *pCacheEntryTable;                              // Kernel Cache Entry table
562     PVPHAL_SURFACE                  pSrcSurface;
563     uint32_t                        dwSrcWidth;
564     uint32_t                        dwSrcHeight;
565     uint32_t                        i;
566 
567     VPHAL_RENDER_CHK_NULL(pHdrState);
568     VPHAL_RENDER_CHK_NULL(pRenderData);
569     VPHAL_RENDER_CHK_NULL(pHdrState->pRenderHal);
570 
571     MOS_ZeroMemory(pRenderData, sizeof(VPHAL_HDR_RENDER_DATA));
572 
573     // Initialize Variables
574     eStatus = MOS_STATUS_SUCCESS;
575 
576     if (iKDTIndex == KERNEL_HDR_MANDATORY_G9)
577     {
578         for (i = 0; i < pHdrState->uSourceCount; i++)
579         {
580             if (pHdrState->pSrcSurf[i])
581             {
582                 if (pHdrState->pSrcSurf[i]->SurfType == SURF_IN_PRIMARY)
583                 {
584                     if (pHdrState->pSrcSurf[i]->pIEFParams)
585                     {
586                         pRenderData->pIEFParams = pHdrState->pSrcSurf[i]->pIEFParams;
587                     }
588 
589 
590                     if (pHdrState->pSrcSurf[i]->Rotation == VPHAL_ROTATION_IDENTITY ||
591                         pHdrState->pSrcSurf[i]->Rotation == VPHAL_ROTATION_180 ||
592                         pHdrState->pSrcSurf[i]->Rotation == VPHAL_MIRROR_HORIZONTAL ||
593                         pHdrState->pSrcSurf[i]->Rotation == VPHAL_MIRROR_VERTICAL)
594                     {
595                         pRenderData->fPrimaryLayerScaleX = (float)(pHdrState->pSrcSurf[i]->rcDst.right - pHdrState->pSrcSurf[i]->rcDst.left) /
596                                                            (float)(pHdrState->pSrcSurf[i]->rcSrc.right - pHdrState->pSrcSurf[i]->rcSrc.left);
597                         pRenderData->fPrimaryLayerScaleY = (float)(pHdrState->pSrcSurf[i]->rcDst.bottom - pHdrState->pSrcSurf[i]->rcDst.top) /
598                                                            (float)(pHdrState->pSrcSurf[i]->rcSrc.bottom - pHdrState->pSrcSurf[i]->rcSrc.top);
599                     }
600                     else
601                     {
602                         // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 ||
603                         // VPHAL_ROTATE_90_MIRROR_HORIZONTAL || VPHAL_ROTATE_90_MIRROR_VERTICAL
604                         pRenderData->fPrimaryLayerScaleX = (float)(pHdrState->pSrcSurf[i]->rcDst.right - pHdrState->pSrcSurf[i]->rcDst.left) /
605                                                            (float)(pHdrState->pSrcSurf[i]->rcSrc.bottom - pHdrState->pSrcSurf[i]->rcSrc.top);
606                         pRenderData->fPrimaryLayerScaleY = (float)(pHdrState->pSrcSurf[i]->rcDst.bottom - pHdrState->pSrcSurf[i]->rcDst.top) /
607                                                            (float)(pHdrState->pSrcSurf[i]->rcSrc.right - pHdrState->pSrcSurf[i]->rcSrc.left);
608                     }
609 
610                     pRenderData->PrimaryLayerFormat = pHdrState->pSrcSurf[i]->Format;
611                 }
612             }
613         }
614 
615         // Store pointer to Kernel Parameter
616         pRenderData->pKernelParam[iKDTIndex] = &pHdrState->pKernelParamTable[iKDTIndex];
617         pCacheEntryTable                     = pHdrState->pKernelCache->pCacheEntries;
618 
619         VPHAL_RENDER_CHK_NULL(pCacheEntryTable);
620 
621         // Set Parameters for Kernel Entry
622         MOS_ZeroMemory(&pRenderData->KernelEntry[iKDTIndex], sizeof(Kdll_CacheEntry));
623 
624         // Set the curbe length
625         pRenderData->iCurbeLength = (pRenderData->pKernelParam[iKDTIndex]->CURBE_Length) * GRF_SIZE;
626 
627         // Set Parameters for Kernel Entry
628         pRenderData->KernelEntry[iKDTIndex].iKUID   = iKUID;
629         pRenderData->KernelEntry[iKDTIndex].iKCID   = -1;
630         pRenderData->KernelEntry[iKDTIndex].iSize   = pCacheEntryTable[iKUID].iSize;
631         pRenderData->KernelEntry[iKDTIndex].pBinary = pCacheEntryTable[iKUID].pBinary;
632         pRenderData->KernelEntry[iKDTIndex].szName  = pCacheEntryTable[iKUID].szName;
633 
634         pRenderData->PerfTag  = (VPHAL_PERFTAG)(VPHAL_HDR_GENERIC + pHdrState->uSourceCount);
635 
636         // Get per block resulution
637         iBlockWd = pRenderData->pKernelParam[iKDTIndex]->block_width;
638         iBlockHt = pRenderData->pKernelParam[iKDTIndex]->block_height;
639 
640         // Calcualte block numbers to process
641         dwSrcWidth            = pHdrState->pTargetSurf[0]->rcDst.right - pHdrState->pTargetSurf[0]->rcDst.left;
642         dwSrcHeight           = pHdrState->pTargetSurf[0]->rcDst.bottom - pHdrState->pTargetSurf[0]->rcDst.top;
643         pRenderData->iBlocksX = (dwSrcWidth + iBlockWd - 1) / iBlockWd;
644         pRenderData->iBlocksY = (dwSrcHeight + iBlockHt -1) / iBlockHt;
645 
646         // Set up Scoreboard parameters
647         pRenderData->ScoreboardParams.ScoreboardMask = 0;
648         pRenderData->ScoreboardParams.ScoreboardType = 1;
649 
650         // Set up AVS parameters
651         pRenderData->pAVSParameters[0] = &pHdrState->AVSParameters[0];
652         pRenderData->pAVSParameters[1] = &pHdrState->AVSParameters[1];
653     }
654     else if (iKDTIndex == KERNEL_HDR_PREPROCESS)
655     {
656         // Store pointer to Kernel Parameter
657         pRenderData->pKernelParam[iKDTIndex] = &pHdrState->pKernelParamTable[iKDTIndex];
658         pCacheEntryTable = pHdrState->pKernelCache->pCacheEntries;
659 
660         VPHAL_RENDER_CHK_NULL(pCacheEntryTable);
661 
662         // Set Parameters for Kernel Entry
663         MOS_ZeroMemory(&pRenderData->KernelEntry[iKDTIndex], sizeof(Kdll_CacheEntry));
664 
665         // Set the curbe length
666         pRenderData->iCurbeLength = (pRenderData->pKernelParam[iKDTIndex]->CURBE_Length) * GRF_SIZE;
667 
668         // Set Parameters for Kernel Entry
669         pRenderData->KernelEntry[iKDTIndex].iKUID = iKUID;
670         pRenderData->KernelEntry[iKDTIndex].iKCID = -1;
671         pRenderData->KernelEntry[iKDTIndex].iSize = pCacheEntryTable[iKUID].iSize;
672         pRenderData->KernelEntry[iKDTIndex].pBinary = pCacheEntryTable[iKUID].pBinary;
673         pRenderData->KernelEntry[iKDTIndex].szName = pCacheEntryTable[iKUID].szName;
674 
675         // Set up Scoreboard parameters
676         pRenderData->ScoreboardParams.ScoreboardMask = 0;
677         pRenderData->ScoreboardParams.ScoreboardType = 1;
678     }
679     else
680     {
681         VPHAL_RENDER_ASSERTMESSAGE("Unknown HDR kernel");
682         eStatus = MOS_STATUS_UNKNOWN;
683         goto finish;
684     }
685 
686 finish:
687     return eStatus;
688 }
689 
690 //!
691 //! \brief    HDR HW States Setup
692 //! \details  Setup HW states for HDR
693 //! \param    PVPHAL_HDR_STATE pHdrState
694 //!           [in] Pointer to the HDR State
695 //! \param    PVPHAL_HDR_RENDER_DATA pRenderData
696 //!           [in,out] Pointer to HDR render data
697 //! \param    PVPHAL_HDR_RENDER_DATA pRenderData
698 //!           [in,out] Pointer to HDR render data
699 //! \param    uint32_t HDRKernelID
700 //!           [in] HDR Kernel ID
701 //! \return   MOS_STATUS
702 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
703 //!
VpHal_HdrSetupHwStates(PVPHAL_HDR_STATE pHdrState,PVPHAL_HDR_RENDER_DATA pRenderData,uint32_t HDRKernelID)704 MOS_STATUS VpHal_HdrSetupHwStates(
705     PVPHAL_HDR_STATE            pHdrState,
706     PVPHAL_HDR_RENDER_DATA      pRenderData,
707     uint32_t                    HDRKernelID)
708 {
709     PRENDERHAL_INTERFACE        pRenderHal           = nullptr;
710     int32_t                     iKrnAllocation       = 0;
711     int32_t                     iCurbeOffset         = 0;
712     MOS_STATUS                  eStatus              = MOS_STATUS_SUCCESS;
713     MHW_KERNEL_PARAM            MhwKernelParam       = {};
714     PMOS_INTERFACE              pOsInterface         = nullptr;
715 
716     VPHAL_RENDER_CHK_NULL(pHdrState);
717     VPHAL_RENDER_CHK_NULL(pRenderData);
718     VPHAL_RENDER_CHK_NULL(pHdrState->pOsInterface);
719 
720     pRenderHal   = pHdrState->pRenderHal;
721     pOsInterface = pHdrState->pOsInterface;
722     VPHAL_RENDER_CHK_NULL(pRenderHal);
723 
724     //----------------------------------
725     // Allocate and reset media state
726     //----------------------------------
727     pRenderData->pMediaState = pRenderHal->pfnAssignMediaState(pRenderHal, (RENDERHAL_COMPONENT)RENDERHAL_COMPONENT_HDR);
728     MOS_OS_CHK_NULL(pRenderData->pMediaState);
729 
730     //----------------------------------
731     // Allocate and reset SSH instance
732     //----------------------------------
733     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnAssignSshInstance(pRenderHal));
734 
735     //----------------------------------
736     // Assign and Reset Binding Table
737     //----------------------------------
738     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnAssignBindingTable(
739         pRenderHal,
740         &pRenderData->iBindingTable));
741 
742     //----------------------------------
743     // Setup Surface states
744     //----------------------------------
745     VPHAL_RENDER_CHK_STATUS(pHdrState->pfnSetupSurfaceStates(
746         pHdrState,
747         pRenderData));
748 
749     //----------------------------------
750     // Load Static data
751     //----------------------------------
752     VPHAL_RENDER_CHK_STATUS(pHdrState->pfnLoadStaticData(
753         pHdrState,
754         pRenderData,
755         &iCurbeOffset));
756 
757     //----------------------------------
758     // Setup VFE State params. Each Renderer MUST call pfnSetVfeStateParams().
759     // See comment in VpHal_HwSetVfeStateParams() for details.
760     //----------------------------------
761     pRenderHal->pfnSetVfeStateParams(
762         pRenderHal,
763         MEDIASTATE_DEBUG_COUNTER_FREE_RUNNING,
764         pRenderData->pKernelParam[HDRKernelID]->Thread_Count,
765         pRenderData->iCurbeLength,
766         0,
767         nullptr);
768 
769     //----------------------------------
770     // Load kernel to GSH
771     //----------------------------------
772     INIT_MHW_KERNEL_PARAM(MhwKernelParam, &pRenderData->KernelEntry[HDRKernelID]);
773 
774     iKrnAllocation = pRenderHal->pfnLoadKernel(
775         pRenderHal,
776         pRenderData->pKernelParam[HDRKernelID],
777         &MhwKernelParam,
778         nullptr);
779 
780     if (iKrnAllocation < 0)
781     {
782         VPHAL_RENDER_ASSERTMESSAGE("HDR Load kernel to GSH failed");
783         eStatus = MOS_STATUS_UNKNOWN;
784         goto finish;
785     }
786 
787     //----------------------------------
788     // Allocate Media ID, link to kernel
789     //----------------------------------
790     pRenderData->iMediaID = pRenderHal->pfnAllocateMediaID(
791         pRenderHal,
792         iKrnAllocation,
793         pRenderData->iBindingTable,
794         iCurbeOffset,
795         pRenderData->iCurbeLength,
796         0,
797         nullptr);
798 
799     if (pRenderData->iMediaID < 0)
800     {
801         VPHAL_RENDER_ASSERTMESSAGE("HDR Allocate Media ID failed");
802         eStatus = MOS_STATUS_UNKNOWN;
803         goto finish;
804     }
805 
806     //----------------------------------
807     // Setup Sampler states
808     //----------------------------------
809     if (HDRKernelID != KERNEL_HDR_PREPROCESS)
810     {
811         VPHAL_RENDER_CHK_STATUS(pHdrState->pfnSetSamplerStates(
812             pHdrState,
813             pRenderData));
814     }
815 
816 finish:
817     VPHAL_RENDER_ASSERT(eStatus == MOS_STATUS_SUCCESS);
818     return eStatus;
819 }
820 
821 //!
822 //! \brief    Setup media walker command for HDR
823 //! \details  Setup media walker command for HDR
824 //! \param    PVPHAL_HDR_STATE pHdrState
825 //!           [in] Pointer to HDR state
826 //! \param    PVPHAL_HDR_RENDER_DATA pRenderData
827 //!           [in] Pointer to render data
828 //! \param    PMHW_WALKER_PARAMS pWalkerParams
829 //!           [out] Pointer to media walker parameters
830 //! \param    int32_t iKDTIndex
831 //            [in] KDT index.
832 //! \param    uint32_t uiPortionIndex
833 //            [in] Frame split portion index.
834 //! \return   MOS_STATUS
835 //!
VpHal_PreprocessHdrSetupWalkerObject(PVPHAL_HDR_STATE pHdrState,PVPHAL_HDR_RENDER_DATA pRenderData,PMHW_WALKER_PARAMS pWalkerParams,int32_t iKDTIndex,uint32_t uiPortionIndex)836 MOS_STATUS VpHal_PreprocessHdrSetupWalkerObject(
837     PVPHAL_HDR_STATE            pHdrState,
838     PVPHAL_HDR_RENDER_DATA      pRenderData,
839     PMHW_WALKER_PARAMS          pWalkerParams,
840     int32_t                     iKDTIndex,
841     uint32_t                    uiPortionIndex)
842 {
843     MOS_STATUS  eStatus       = MOS_STATUS_SUCCESS;
844     uint32_t threadswidth     = 1;
845     uint32_t threadsheight    = VPHAL_MAX_HDR_INPUT_LAYER;
846 
847     VPHAL_RENDER_CHK_NULL(pHdrState);
848     VPHAL_RENDER_CHK_NULL(pRenderData);
849     VPHAL_RENDER_CHK_NULL(pWalkerParams);
850 
851     // Setup Media Walker cmd. Raster scan with no dependency
852     MOS_ZeroMemory(pWalkerParams, sizeof(MHW_WALKER_PARAMS));
853     pWalkerParams->InterfaceDescriptorOffset = pRenderData->iMediaID;
854     pWalkerParams->dwGlobalLoopExecCount = 1;
855     pWalkerParams->dwLocalLoopExecCount  = 1;
856     pWalkerParams->BlockResolution.x  = threadswidth;
857     pWalkerParams->BlockResolution.y  = threadsheight;
858     pWalkerParams->GlobalResolution.x = threadswidth;
859     pWalkerParams->GlobalResolution.y = threadsheight;
860 
861 
862     pWalkerParams->GlobalStart.x = 0;
863     pWalkerParams->GlobalStart.y = 0;
864     pWalkerParams->GlobalOutlerLoopStride.x = threadswidth;
865     pWalkerParams->GlobalOutlerLoopStride.y = 0;
866     pWalkerParams->GlobalInnerLoopUnit.x = 0;
867     pWalkerParams->GlobalInnerLoopUnit.y = threadsheight;
868     pWalkerParams->LocalStart.x = 0;
869     pWalkerParams->LocalStart.y = 0;
870     pWalkerParams->LocalOutLoopStride.x = 1;
871     pWalkerParams->LocalOutLoopStride.y = 0;
872     pWalkerParams->LocalInnerLoopUnit.x = 0;
873     pWalkerParams->LocalInnerLoopUnit.y = 1;
874     pWalkerParams->LocalEnd.x = 0;
875     pWalkerParams->LocalEnd.y = threadsheight - 1;
876 
877     eStatus = MOS_STATUS_SUCCESS;
878 
879 finish:
880     return eStatus;
881 }
882 
883 //!
884 //! \brief    Render GpGpu Walker Buffer
885 //! \details  Render GpGpu Walker Buffer, fill Walker static data fields and set walker
886 //!           cmd params
887 //! \param    [in] pHdrState
888 //!           Pointer to HdrState
889 //! \param    [in] pRenderingData
890 //!           Pointer to Rendering Data
891 //! \param    [in] pWalkerParams
892 //!           Pointer to Walker parameters
893 //! \return   MOS_STATUS
894 //!           Return MOS_STATUS_SUCCESS if successful, otherwise false
895 //!
Vphal_HdrSetupComputeWalker(PVPHAL_HDR_STATE pHdrState,PVPHAL_HDR_RENDER_DATA pRenderData,PMHW_GPGPU_WALKER_PARAMS pWalkerParams)896 MOS_STATUS Vphal_HdrSetupComputeWalker(
897     PVPHAL_HDR_STATE                pHdrState,
898     PVPHAL_HDR_RENDER_DATA          pRenderData,
899     PMHW_GPGPU_WALKER_PARAMS        pWalkerParams)
900 {
901     MOS_STATUS                          eStatus                 = MOS_STATUS_UNINITIALIZED;
902     PRENDERHAL_INTERFACE                pRenderHal              = nullptr;
903     PVPHAL_BB_COMP_ARGS                 pBbArgs                 = nullptr;
904     bool                                bResult                 = false;
905     int32_t                             iLayers                 = 0;
906     uint32_t                            uiMediaWalkerBlockSize  = 0;
907     uint32_t*                           pdwDestXYTopLeft        = nullptr;
908     uint32_t*                           pdwDestXYBottomRight    = nullptr;
909     RECT                                AlignedRect             = {};
910     bool                                bVerticalPattern        = false;
911 
912     VPHAL_RENDER_CHK_NULL(pHdrState);
913     VPHAL_RENDER_CHK_NULL(pHdrState->pTargetSurf[0]);
914     VPHAL_RENDER_CHK_NULL(pHdrState->pSrcSurf[0]);
915     VPHAL_RENDER_CHK_NULL(pRenderData);
916     VPHAL_RENDER_CHK_NULL(pWalkerParams);
917 
918     pRenderHal              = pHdrState->pRenderHal;
919     VPHAL_RENDER_CHK_NULL(pRenderHal);
920 
921     bVerticalPattern        = false;
922     AlignedRect             = pHdrState->pTargetSurf[0]->rcDst;
923 
924     // Get media walker kernel block size
925     uiMediaWalkerBlockSize  = pRenderHal->pHwSizes->dwSizeMediaWalkerBlock;
926 
927     // Calculate aligned output area in order to determine the total # blocks
928     // to process in case of non-16x16 aligned target.
929     AlignedRect.right       += uiMediaWalkerBlockSize - 1;
930     AlignedRect.bottom      += uiMediaWalkerBlockSize - 1;
931     AlignedRect.left        -= AlignedRect.left   % uiMediaWalkerBlockSize;
932     AlignedRect.top         -= AlignedRect.top    % uiMediaWalkerBlockSize;
933     AlignedRect.right       -= AlignedRect.right  % uiMediaWalkerBlockSize;
934     AlignedRect.bottom      -= AlignedRect.bottom % uiMediaWalkerBlockSize;
935 
936     // Set walker cmd params - Rasterscan
937     pWalkerParams->InterfaceDescriptorOffset = pRenderData->iMediaID;
938 
939     if (pHdrState->uSourceCount == 1 &&
940         pHdrState->pSrcSurf[0]->TileType == MOS_TILE_LINEAR &&
941         (pHdrState->pSrcSurf[0]->Rotation == VPHAL_ROTATION_90 || pHdrState->pSrcSurf[0]->Rotation == VPHAL_ROTATION_270))
942     {
943         pWalkerParams->GroupStartingX       = (AlignedRect.top / uiMediaWalkerBlockSize);
944         pWalkerParams->GroupStartingY       = (AlignedRect.left / uiMediaWalkerBlockSize);
945         pWalkerParams->GroupWidth           = pRenderData->iBlocksY;
946         pWalkerParams->GroupHeight          = pRenderData->iBlocksX;
947     }
948     else
949     {
950         pWalkerParams->GroupStartingX       = (AlignedRect.left / uiMediaWalkerBlockSize);
951         pWalkerParams->GroupStartingY       = (AlignedRect.top / uiMediaWalkerBlockSize);
952         pWalkerParams->GroupWidth           = pRenderData->iBlocksX;
953         pWalkerParams->GroupHeight          = pRenderData->iBlocksY;
954     }
955 
956     pWalkerParams->ThreadWidth              = 1;
957     pWalkerParams->ThreadHeight             = 1;
958     pWalkerParams->ThreadDepth              = 1;
959     pWalkerParams->IndirectDataStartAddress = pRenderData->iCurbeOffset;
960     // Indirect Data Length is a multiple of 64 bytes (size of L3 cacheline). Bits [5:0] are zero.
961     pWalkerParams->IndirectDataLength       = MOS_ALIGN_CEIL(pRenderData->iCurbeLength, 1 << MHW_COMPUTE_INDIRECT_SHIFT);
962     pWalkerParams->BindingTableID           = pRenderData->iBindingTable;
963 
964     eStatus = MOS_STATUS_SUCCESS;
965 
966 finish:
967     return eStatus;
968 }
969 
970 //!
971 //! \brief    HDR render
972 //! \details  Launch HDR kernel to render output picture
973 //! \param    PVPHAL_HDR_STATE pHdrState
974 //!           [in] Poniter to HDR state
975 //! \param    PVPHAL_RENDER_PARAMS pRenderParams
976 //!           [in,out] Pointer to Render parameters
977 //! \return   MOS_STATUS
978 //!           MOS_STATUS_SUCCESS if successful, otherwise failed
979 //!
VpHal_HdrRender(PVPHAL_HDR_STATE pHdrState,PVPHAL_RENDER_PARAMS pRenderParams)980 MOS_STATUS VpHal_HdrRender(
981     PVPHAL_HDR_STATE             pHdrState,
982     PVPHAL_RENDER_PARAMS         pRenderParams)
983 {
984     PRENDERHAL_INTERFACE            pRenderHal              = nullptr;
985     PMOS_INTERFACE                  pOsInterface            = nullptr;
986     MHW_WALKER_PARAMS               WalkerParams            = {};
987     PMHW_WALKER_PARAMS              pWalkerParams           = nullptr;
988     MHW_GPGPU_WALKER_PARAMS         ComputeWalkerParams     = {};
989     PMHW_GPGPU_WALKER_PARAMS        pComputeWalkerParams    = nullptr;
990     int32_t                         iKUID                   = 0;
991     int32_t                         iKDTIndex               = 0;
992     uint32_t                        i                       = 0;
993     bool                            bSupported              = true;
994     MOS_STATUS                      eStatus                 = MOS_STATUS_UNKNOWN;
995     uint32_t                        HdrKernel               = 0;
996     VPHAL_HDR_RENDER_DATA           RenderData              = {};
997     MOS_GPU_CONTEXT                 RenderGpuContext        = MOS_GPU_CONTEXT_RENDER;
998     bool                            bLastSummit             = true;
999 
1000     VPHAL_RENDER_FUNCTION_ENTER;
1001 
1002     VPHAL_RENDER_CHK_NULL(pHdrState);
1003     VPHAL_RENDER_CHK_NULL(pRenderParams);
1004     VPHAL_RENDER_CHK_NULL(pHdrState->pRenderHal);
1005     VPHAL_RENDER_CHK_NULL(pHdrState->pOsInterface);
1006 
1007     // Initialize Variables
1008     pRenderHal                = pHdrState->pRenderHal;
1009     pOsInterface              = pHdrState->pOsInterface;
1010     pWalkerParams             = &WalkerParams;
1011     pHdrState->uSourceCount   = 0;
1012     pHdrState->uTargetCount   = 0;
1013     pRenderParams             = (VPHAL_RENDER_PARAMS*)pRenderParams;
1014 
1015     RenderGpuContext          = pOsInterface ? (pOsInterface->CurrentGpuContextOrdinal) : MOS_GPU_CONTEXT_RENDER;
1016     pComputeWalkerParams      = nullptr;
1017     MOS_ZeroMemory(&ComputeWalkerParams, sizeof(ComputeWalkerParams));
1018 
1019     if (pRenderParams->uSrcCount > VPHAL_MAX_HDR_INPUT_LAYER)
1020     {
1021         eStatus = MOS_STATUS_INVALID_PARAMETER;
1022         goto finish;
1023     }
1024     if (pRenderParams->uDstCount > VPHAL_MAX_HDR_OUTPUT_LAYER)
1025     {
1026         eStatus = MOS_STATUS_INVALID_PARAMETER;
1027         goto finish;
1028     }
1029 
1030     HdrKernel = KERNEL_HDR_MANDATORY;
1031 
1032     for (i = 0; i < pRenderParams->uSrcCount; i++)
1033     {
1034         if (pRenderParams->pSrc[i] == nullptr)
1035         {
1036             continue;
1037         }
1038 
1039         VPHAL_RENDER_CHK_STATUS(pHdrState->pfnIsInputFormatSupported(pRenderParams->pSrc[i], &bSupported));
1040 
1041         if (!bSupported)
1042         {
1043             eStatus = MOS_STATUS_INVALID_PARAMETER;
1044             goto finish;
1045         }
1046 
1047         pHdrState->pSrcSurf[i] = pRenderParams->pSrc[i];
1048         pHdrState->uSourceCount++;
1049 
1050         // Ensure the input is ready to be read
1051         pOsInterface->pfnSyncOnResource(
1052             pOsInterface,
1053             &pHdrState->pSrcSurf[i]->OsResource,
1054             RenderGpuContext,
1055             false);
1056     }
1057 
1058     for (i = 0; i < pRenderParams->uDstCount; i++)
1059     {
1060         if (pRenderParams->pTarget[i] == nullptr)
1061         {
1062             continue;
1063         }
1064 
1065         VPHAL_RENDER_CHK_STATUS(pHdrState->pfnIsOutputFormatSupported(pRenderParams->pTarget[i], &bSupported));
1066 
1067         if (!bSupported)
1068         {
1069             eStatus = MOS_STATUS_INVALID_PARAMETER;
1070             goto finish;
1071         }
1072 
1073 
1074         pHdrState->pTargetSurf[i] = pRenderParams->pTarget[i];
1075         pHdrState->uTargetCount++;
1076 
1077         // Ensure the output is ready to be written
1078         pOsInterface->pfnSyncOnResource(
1079             pOsInterface,
1080             &pHdrState->pTargetSurf[i]->OsResource,
1081             RenderGpuContext,
1082             true);
1083 
1084         // Sync Render Target with Overlay Context
1085         if (pHdrState->pTargetSurf[i]->bOverlay)
1086         {
1087             pOsInterface->pfnSyncOnOverlayResource(
1088                 pOsInterface,
1089                 &pHdrState->pTargetSurf[i]->OsResource,
1090                 RenderGpuContext);
1091         }
1092     }
1093 
1094     pHdrState->pColorFillParams = pRenderParams->pColorFillParams;
1095     // Allocate resources needed by Hdr
1096     VPHAL_RENDER_CHK_STATUS(pHdrState->pfnAllocateResources(pHdrState));
1097     VPHAL_RENDER_CHK_STATUS(VpHal_HdrPreprocess(pHdrState, pRenderParams));
1098 
1099     for (i = 0; i < pHdrState->uiSplitFramePortions; i++)
1100     {
1101         // Reset states before rendering
1102         // (clear allocations, get GSH allocation index + any additional housekeeping)
1103         pOsInterface->pfnResetOsStates(pOsInterface);
1104         VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnReset(pRenderHal));
1105 
1106         // Get the Kernel Parameter (Platform Specific)
1107         VPHAL_RENDER_CHK_STATUS(pHdrState->pfnGetKernelParam(
1108             HdrKernel,
1109             &iKUID,
1110             &iKDTIndex));
1111 
1112         // Setup Hdr render data
1113         VPHAL_RENDER_CHK_STATUS(VpHal_HdrSetupRenderData(
1114             pHdrState,
1115             &RenderData,
1116             iKUID,
1117             iKDTIndex));
1118 
1119         // Set up HW States and Commands
1120         VPHAL_RENDER_CHK_STATUS(VpHal_HdrSetupHwStates(pHdrState, &RenderData, iKDTIndex));
1121 
1122         // Set Perf Tag
1123         pOsInterface->pfnResetPerfBufferID(pOsInterface);
1124         pOsInterface->pfnSetPerfTag(pOsInterface, RenderData.PerfTag);
1125 
1126         if (pHdrState->bFtrComputeWalker)
1127         {
1128             // Setup Compute Walker
1129             pWalkerParams = nullptr;
1130             pComputeWalkerParams = &ComputeWalkerParams;
1131 
1132             VPHAL_RENDER_CHK_STATUS(Vphal_HdrSetupComputeWalker(
1133                 pHdrState,
1134                 &RenderData,
1135                 &ComputeWalkerParams));
1136         }
1137         else
1138         {
1139             // Setup Media Walker Object
1140             VpHal_HdrSetupWalkerObject(
1141                 pHdrState,
1142                 &RenderData,
1143                 &WalkerParams,
1144                 iKDTIndex,
1145                 i);
1146         }
1147 
1148         bLastSummit = (i == (pHdrState->uiSplitFramePortions - 1) ? true : false);
1149         // Submit all media states to HW
1150         VPHAL_RENDER_CHK_STATUS(VpHal_RndrSubmitCommands(
1151             pRenderHal,
1152             nullptr,
1153             pHdrState->bNullHwRenderHdr,
1154             pWalkerParams,
1155             pComputeWalkerParams,
1156             &pHdrState->StatusTableUpdateParams,
1157             (VpKernelID)kernelHdrMandatory,
1158             0,
1159             nullptr,
1160             bLastSummit));
1161     }
1162 
1163     eStatus = MOS_STATUS_SUCCESS;
1164 
1165 finish:
1166     VPHAL_RENDER_EXITMESSAGE("eStatus %d", eStatus);
1167     return eStatus;
1168 }
1169 
1170 //!
1171 //! \brief    Hdr init renderer interface
1172 //! \details  Initializes the Hdr interface
1173 //! \param    PVPHAL_HDR_STATE pHdrState
1174 //!           [in] Pointer to Hdr state
1175 //! \param    PRENDERHAL_INTERFACE pRenderHal
1176 //!           [in] Pointer to RENDERHAL interface
1177 //! \return   void
1178 //!
VpHal_HdrInitInterface(PVPHAL_HDR_STATE pHdrState,PRENDERHAL_INTERFACE pRenderHal)1179 MOS_STATUS VpHal_HdrInitInterface(
1180     PVPHAL_HDR_STATE          pHdrState,
1181     PRENDERHAL_INTERFACE      pRenderHal)
1182 {
1183     MOS_STATUS                  eStatus         = MOS_STATUS_SUCCESS;
1184     PMOS_INTERFACE              pOsInterface    = nullptr;
1185 
1186     VPHAL_PUBLIC_CHK_NULL(pHdrState);
1187     VPHAL_PUBLIC_CHK_NULL(pRenderHal);
1188 
1189     MOS_ZeroMemory(pHdrState, sizeof(VPHAL_HDR_STATE));
1190 
1191     pOsInterface = pRenderHal->pOsInterface;
1192 
1193     VPHAL_PUBLIC_CHK_NULL(pOsInterface);
1194 
1195     // Set interface to OS and HW interfaces
1196     pHdrState->pRenderHal                 = pRenderHal;
1197     pHdrState->pOsInterface               = pOsInterface;
1198     pHdrState->pSkuTable                  = pOsInterface->pfnGetSkuTable(pOsInterface);
1199 
1200     // Setup Function Pointers
1201     pHdrState->pfnInitialize              = VpHal_HdrInitialize;
1202     pHdrState->pfnDestroy                 = VpHal_HdrDestroy;
1203     pHdrState->pfnRender                  = VpHal_HdrRender;
1204     pHdrState->pfnIsNeeded                = VpHal_HdrIsNeeded;
1205 
1206     eStatus = MOS_STATUS_SUCCESS;
1207 
1208 finish:
1209     return eStatus;
1210 }
1211 
1212 //! \brief    Perform Rendering HDR step
1213 //! \details  Check whether HDR is needed. When it's needed, perform HDR
1214 //!           operation
1215 //! \param    [in,out] pRenderer
1216 //!           VPHAL renderer pointer
1217 //! \param    [in,out] pRenderParams
1218 //!           Pointer to VPHAL render parameter
1219 //! \param    [in,out] pRenderPassData
1220 //!           Pointer to the VPHAL render pass data
1221 //! \return   MOS_STATUS
1222 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1223 //!
VpHal_RndrRenderHDR(VphalRenderer * pRenderer,PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)1224 MOS_STATUS VpHal_RndrRenderHDR(
1225     VphalRenderer           *pRenderer,
1226     PVPHAL_RENDER_PARAMS    pRenderParams,
1227     RenderpassData          *pRenderPassData)
1228 {
1229     PRENDERHAL_INTERFACE    *pRenderHal = nullptr;
1230     MOS_STATUS              eStatus     = MOS_STATUS_SUCCESS;
1231     bool                    bEnabled    = false;
1232 
1233     VPHAL_RENDER_FUNCTION_ENTER;
1234 
1235     VPHAL_RENDER_CHK_NULL(pRenderer);
1236     VPHAL_RENDER_CHK_NULL(pRenderParams);
1237     VPHAL_RENDER_CHK_NULL(pRenderPassData);
1238     VPHAL_RENDER_CHK_NULL(pRenderer->pHdrState);
1239 
1240     pRenderHal = &pRenderer->pHdrState->pRenderHal;
1241     VPHAL_RENDER_CHK_NULL(pRenderHal);
1242 
1243     // Disable bEnableP010SinglePass for HDR path, to avoid AVS sampler and 1 planes 3D sampler path in kernel.
1244     // Kernel solution only support 2 planes rendering of 3D sampler.
1245     if ((*pRenderHal)->bEnableP010SinglePass)
1246     {
1247         bEnabled = true;
1248         (*pRenderHal)->bEnableP010SinglePass = false;
1249     }
1250     eStatus = pRenderer->pHdrState->pfnRender(pRenderer->pHdrState, pRenderParams);
1251 
1252     if (bEnabled)
1253        (*pRenderHal)->bEnableP010SinglePass = true;
1254 
1255 finish:
1256     VPHAL_RENDER_EXITMESSAGE("eStatus %d", eStatus);
1257     return eStatus;
1258 }
1259 
1260 //!
1261 //! \brief    Check if HDR path is needed
1262 //! \details  Check if HDR path is needed
1263 //! \param    [in] pRenderer
1264 //!           VPHAL renderer pointer
1265 //! \param    [in] pRenderParams
1266 //!           Pointer to VPHAL render parameter
1267 //! \param    [in] pRenderPassData
1268 //!           Pointer to VPHAL render pass data
1269 //! \return   bool
1270 //!
VpHal_RndrIsHdrPathNeeded(VphalRenderer * pRenderer,PVPHAL_RENDER_PARAMS pRenderParams,RenderpassData * pRenderPassData)1271 bool VpHal_RndrIsHdrPathNeeded(
1272     VphalRenderer           *pRenderer,
1273     PVPHAL_RENDER_PARAMS    pRenderParams,
1274     RenderpassData          *pRenderPassData)
1275 {
1276     if (!pRenderer || !pRenderParams || !pRenderPassData)
1277     {
1278         return false;
1279     }
1280 
1281     if (pRenderPassData->bHdrNeeded && pRenderer->pHdrState)
1282     {
1283         // Hdr kernel render will be disabled for 1 layer H2H bypass case for PnP optimization
1284         if (!pRenderer->pHdrState->bBypassHdrKernelPath)
1285         {
1286             return true;
1287         }
1288     }
1289 
1290     return false;
1291 }
1292 
1293 //!
1294 //! \brief    Setup media walker command for HDR
1295 //! \details  Setup media walker command for HDR
1296 //! \param    PVPHAL_HDR_STATE pHdrState
1297 //!           [in] Pointer to HDR state
1298 //! \param    PVPHAL_HDR_RENDER_DATA pRenderData
1299 //!           [in] Pointer to render data
1300 //! \param    PMHW_WALKER_PARAMS pWalkerParams
1301 //!           [out] Pointer to media walker parameters
1302 //! \param    int32_t iKDTIndex
1303 //            [in] KDT index.
1304 //! \param    uint32_t uiPortionIndex
1305 //            [in] Frame split portion index.
1306 //! \return   MOS_STATUS
1307 //!
VpHal_HdrSetupWalkerObject(PVPHAL_HDR_STATE pHdrState,PVPHAL_HDR_RENDER_DATA pRenderData,PMHW_WALKER_PARAMS pWalkerParams,int32_t iKDTIndex,uint32_t uiPortionIndex)1308 MOS_STATUS VpHal_HdrSetupWalkerObject(
1309     PVPHAL_HDR_STATE            pHdrState,
1310     PVPHAL_HDR_RENDER_DATA      pRenderData,
1311     PMHW_WALKER_PARAMS          pWalkerParams,
1312     int32_t                     iKDTIndex,
1313     uint32_t                    uiPortionIndex)
1314 {
1315     MOS_STATUS                  eStatus        =  MOS_STATUS_SUCCESS;
1316     RECT                        AlignedRect    = {};
1317     int32_t                     iBlockWd       = 0;                                       // Block Width
1318     int32_t                     iBlockHt       = 0;                                       // Block Height
1319 
1320     VPHAL_RENDER_CHK_NULL(pHdrState);
1321     VPHAL_RENDER_CHK_NULL(pHdrState->pTargetSurf[0]);
1322     VPHAL_RENDER_CHK_NULL(pRenderData);
1323     VPHAL_RENDER_CHK_NULL(pWalkerParams);
1324 
1325     AlignedRect = pHdrState->pTargetSurf[0]->rcDst;
1326     iBlockWd = pRenderData->pKernelParam[iKDTIndex]->block_width;
1327     iBlockHt = pRenderData->pKernelParam[iKDTIndex]->block_height;
1328 
1329     AlignedRect.right += iBlockWd - 1;
1330     AlignedRect.bottom += iBlockHt - 1;
1331     AlignedRect.left -= AlignedRect.left   % iBlockWd;
1332     AlignedRect.top -= AlignedRect.top    % iBlockHt;
1333     AlignedRect.right -= AlignedRect.right  % iBlockWd;
1334     AlignedRect.bottom -= AlignedRect.bottom % iBlockHt;
1335 
1336     // Setup Media Walker cmd. Raster scan with no dependency
1337     MOS_ZeroMemory(pWalkerParams, sizeof(MHW_WALKER_PARAMS));
1338     pWalkerParams->InterfaceDescriptorOffset = pRenderData->iMediaID;
1339     pWalkerParams->dwGlobalLoopExecCount = 1;
1340     pWalkerParams->dwLocalLoopExecCount = pRenderData->iBlocksX - 1;
1341     pWalkerParams->BlockResolution.x = pRenderData->iBlocksX;
1342     pWalkerParams->BlockResolution.y = pRenderData->iBlocksY;
1343 
1344     if (AlignedRect.left != 0 || AlignedRect.top != 0)
1345     {
1346         // if the rect starts from any other macro block other than the first
1347         // then the global resolution should be the whole frame and the global
1348         // start should be the rect start.
1349         pWalkerParams->GlobalResolution.x =
1350             (AlignedRect.right / iBlockWd);
1351         pWalkerParams->GlobalResolution.y =
1352             (AlignedRect.bottom / iBlockHt);
1353     }
1354     else
1355     {
1356         pWalkerParams->GlobalResolution.x = pRenderData->iBlocksX;
1357         pWalkerParams->GlobalResolution.y = pRenderData->iBlocksY;
1358     }
1359 
1360     pWalkerParams->GlobalStart.x = (AlignedRect.left / iBlockWd);
1361     pWalkerParams->GlobalStart.y = (AlignedRect.top / iBlockHt);
1362     pWalkerParams->GlobalOutlerLoopStride.x = pRenderData->iBlocksX;
1363     pWalkerParams->GlobalOutlerLoopStride.y = 0;
1364     pWalkerParams->GlobalInnerLoopUnit.x = 0;
1365     pWalkerParams->GlobalInnerLoopUnit.y = pRenderData->iBlocksY;
1366     pWalkerParams->LocalStart.x = 0;
1367     pWalkerParams->LocalStart.y = 0;
1368     pWalkerParams->LocalOutLoopStride.x = 1;
1369     pWalkerParams->LocalOutLoopStride.y = 0;
1370     pWalkerParams->LocalInnerLoopUnit.x = 0;
1371     pWalkerParams->LocalInnerLoopUnit.y = 1;
1372     pWalkerParams->LocalEnd.x = 0;
1373     pWalkerParams->LocalEnd.y = pRenderData->iBlocksY - 1;
1374 
1375     if (pHdrState->uiSplitFramePortions > 1)
1376     {
1377         pWalkerParams->GlobalStart.x = MOS_MAX(MOS_ROUNDUP_DIVIDE(pWalkerParams->GlobalResolution.x, pHdrState->uiSplitFramePortions) * (uiPortionIndex),
1378             pWalkerParams->GlobalStart.x);
1379         pWalkerParams->GlobalResolution.x = MOS_MIN(MOS_ROUNDUP_DIVIDE(pWalkerParams->GlobalResolution.x, pHdrState->uiSplitFramePortions) * (uiPortionIndex + 1),
1380             pWalkerParams->GlobalResolution.x);
1381     }
1382 
1383     eStatus = MOS_STATUS_SUCCESS;
1384 
1385 finish:
1386     return eStatus;
1387 }
1388 
1389 //!
1390 //! \brief    HDR preprocess
1391 //! \details  Launch HDR pre process kernel to render hdr coefficients surface
1392 //! \param    PVPHAL_HDR_STATE pHdrState
1393 //!           [in] Poniter to HDR state
1394 //! \param    PVPHAL_RENDER_PARAMS pRenderParams
1395 //!           [in,out] Pointer to Render parameters
1396 //! \return   MOS_STATUS
1397 //!           MOS_STATUS_SUCCESS if successful, otherwise failed
1398 //!
VpHal_HdrPreprocess(PVPHAL_HDR_STATE pHdrState,PVPHAL_RENDER_PARAMS pRenderParams)1399 MOS_STATUS VpHal_HdrPreprocess(
1400     PVPHAL_HDR_STATE        pHdrState,
1401     PVPHAL_RENDER_PARAMS    pRenderParams)
1402 {
1403     MOS_STATUS                    eStatus               = MOS_STATUS_UNKNOWN;
1404     PRENDERHAL_INTERFACE          pRenderHal            = nullptr;
1405     PMOS_INTERFACE                pOsInterface          = nullptr;
1406     uint32_t                      HdrKernel             = KERNEL_HDR_PREPROCESS;
1407     MOS_GPU_CONTEXT               RenderGpuContext      = MOS_GPU_CONTEXT_RENDER;
1408     int32_t                       iKUID                 = 0;
1409     int32_t                       iKDTIndex             = 0;
1410     VPHAL_HDR_RENDER_DATA         RenderData            = {};
1411     bool                          bLastSummit           = true;
1412     MHW_WALKER_PARAMS             WalkerParams          = {};
1413     PMHW_WALKER_PARAMS            pWalkerParams         = nullptr;
1414     MHW_GPGPU_WALKER_PARAMS       ComputeWalkerParams   = {};
1415     PMHW_GPGPU_WALKER_PARAMS      pComputeWalkerParams  = nullptr;
1416     uint32_t                      i                     = 0;
1417     int32_t                       iCurbeOffset          = 0;
1418     const uint32_t                HDRKernelID           = KERNEL_HDR_PREPROCESS;
1419     MHW_KERNEL_PARAM              MhwKernelParam        = {};
1420     int32_t                       iKrnAllocation        = 0;
1421 
1422     VPHAL_RENDER_FUNCTION_ENTER;
1423 
1424     VPHAL_RENDER_CHK_NULL(pHdrState);
1425     VPHAL_RENDER_CHK_NULL(pRenderParams);
1426     VPHAL_RENDER_CHK_NULL(pHdrState->pRenderHal);
1427     VPHAL_RENDER_CHK_NULL(pHdrState->pOsInterface);
1428 
1429     // HDR PreProcess Kernel is needed only if HDR metada is changed.
1430     if (!pHdrState->dwUpdateMask)
1431     {
1432         VPHAL_RENDER_EXITMESSAGE("pHdrState->dwUpdateMask is false, no need to update coefficients, exit with MOS_STATUS_SUCCESS!");
1433         return MOS_STATUS_SUCCESS;
1434     }
1435 
1436     // Initialize Variables
1437     pRenderHal          = pHdrState->pRenderHal;
1438     pOsInterface        = pHdrState->pOsInterface;
1439     RenderGpuContext    = pOsInterface->CurrentGpuContextOrdinal;
1440 
1441     // Reset states before rendering
1442     // (clear allocations, get GSH allocation index + any additional housekeeping)
1443     pOsInterface->pfnResetOsStates(pOsInterface);
1444     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnReset(pRenderHal));
1445 
1446     // Get the Kernel Parameter (Platform Specific)
1447     VPHAL_RENDER_CHK_STATUS(pHdrState->pfnGetKernelParam(
1448         HdrKernel,
1449         &iKUID,
1450         &iKDTIndex));
1451 
1452     // Setup Hdr render data
1453     VPHAL_RENDER_CHK_STATUS(VpHal_HdrSetupRenderData(
1454         pHdrState,
1455         &RenderData,
1456         iKUID,
1457         iKDTIndex));
1458 
1459     //----------------------------------
1460     // Allocate and reset media state
1461     //----------------------------------
1462     RenderData.pMediaState = pRenderHal->pfnAssignMediaState(pRenderHal, (RENDERHAL_COMPONENT)RENDERHAL_COMPONENT_HDR);
1463     MOS_OS_CHK_NULL(RenderData.pMediaState);
1464 
1465     //----------------------------------
1466     // Allocate and reset SSH instance
1467     //----------------------------------
1468     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnAssignSshInstance(pRenderHal));
1469 
1470     //----------------------------------
1471     // Assign and Reset Binding Table
1472     //----------------------------------
1473     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnAssignBindingTable(
1474         pRenderHal,
1475         &RenderData.iBindingTable));
1476 
1477     //----------------------------------
1478    // Setup Surface states
1479    //----------------------------------
1480     VPHAL_RENDER_CHK_STATUS(pHdrState->pfnSetupPreSurfaceStates(
1481         pHdrState,
1482         &RenderData));
1483 
1484     //----------------------------------
1485     // Load Static data
1486     //----------------------------------
1487     VPHAL_RENDER_CHK_STATUS(pHdrState->pfnLoadPreStaticData(
1488         pHdrState,
1489         &RenderData,
1490         &iCurbeOffset));
1491 
1492     //----------------------------------
1493     // Setup VFE State params. Each Renderer MUST call pfnSetVfeStateParams().
1494     // See comment in VpHal_HwSetVfeStateParams() for details.
1495     //----------------------------------
1496     pRenderHal->pfnSetVfeStateParams(
1497         pRenderHal,
1498         MEDIASTATE_DEBUG_COUNTER_FREE_RUNNING,
1499         RenderData.pKernelParam[HDRKernelID]->Thread_Count,
1500         RenderData.iCurbeLength,
1501         0,
1502         nullptr);
1503 
1504     //----------------------------------
1505     // Load kernel to GSH
1506     //----------------------------------
1507     INIT_MHW_KERNEL_PARAM(MhwKernelParam, &RenderData.KernelEntry[HDRKernelID]);
1508 
1509     iKrnAllocation = pRenderHal->pfnLoadKernel(
1510         pRenderHal,
1511         RenderData.pKernelParam[HDRKernelID],
1512         &MhwKernelParam,
1513         nullptr);
1514 
1515     if (iKrnAllocation < 0)
1516     {
1517         VPHAL_RENDER_ASSERTMESSAGE("HDR Load kernel to GSH failed");
1518         eStatus = MOS_STATUS_UNKNOWN;
1519         goto finish;
1520     }
1521 
1522     //----------------------------------
1523     // Allocate Media ID, link to kernel
1524     //----------------------------------
1525     RenderData.iMediaID = pRenderHal->pfnAllocateMediaID(
1526         pRenderHal,
1527         iKrnAllocation,
1528         RenderData.iBindingTable,
1529         iCurbeOffset,
1530         RenderData.iCurbeLength,
1531         0,
1532         nullptr);
1533 
1534     if (RenderData.iMediaID < 0)
1535     {
1536         VPHAL_RENDER_ASSERTMESSAGE("HDR Allocate Media ID failed");
1537         eStatus = MOS_STATUS_UNKNOWN;
1538         goto finish;
1539     }
1540 
1541     // Set Perf Tag
1542     pOsInterface->pfnResetPerfBufferID(pOsInterface);
1543     pOsInterface->pfnSetPerfTag(pOsInterface, RenderData.PerfTag);
1544 
1545     if (pHdrState->bFtrComputeWalker)
1546     {
1547         // Setup Compute Walker
1548         pWalkerParams = nullptr;
1549         pComputeWalkerParams = &ComputeWalkerParams;
1550 
1551         VPHAL_RENDER_CHK_STATUS(Vphal_HdrSetupComputeWalker(
1552             pHdrState,
1553             &RenderData,
1554             &ComputeWalkerParams));
1555     }
1556     else
1557     {
1558         // Setup Media Walker Object
1559         VpHal_PreprocessHdrSetupWalkerObject(
1560             pHdrState,
1561             &RenderData,
1562             &WalkerParams,
1563             iKDTIndex,
1564             0);
1565     }
1566 
1567     // Submit all media states to HW
1568     VPHAL_RENDER_CHK_STATUS(VpHal_RndrSubmitCommands(
1569         pRenderHal,
1570         nullptr,
1571         pHdrState->bNullHwRenderHdr,
1572         &WalkerParams,
1573         &ComputeWalkerParams,
1574         &pHdrState->StatusTableUpdateParams,
1575         (VpKernelID)kernelHdrPreprocess,
1576         0,
1577         nullptr,
1578         bLastSummit));
1579 
1580 #if (_DEBUG || _RELEASE_INTERNAL)
1581     if (sEnableKernelDump)
1582     {
1583         VphalSurfaceDumper surfaceDumper(pOsInterface);
1584         std::string fileName("Preprocessed_HDRMandatory_coefficient_8x98");
1585         surfaceDumper.DumpSurfaceToFile(pOsInterface, &pHdrState->CoeffSurface, fileName.c_str(), 0, true, false, nullptr);
1586     }
1587 #endif
1588 
1589     eStatus = MOS_STATUS_SUCCESS;
1590 
1591 finish:
1592     VPHAL_RENDER_EXITMESSAGE("eStatus %d", eStatus);
1593     return eStatus;
1594 }
1595 
1596 
1597 //!
1598 //! \brief    Calculate Yuv Range and Offest
1599 //! \details  Calculate Yuv Range and Offest
1600 //! \param    VPHAL_CSPACE cspace
1601 //!           [in] Source color space
1602 //! \param    float* pLumaOffset
1603 //!           [out] Pointer to Luma Offset
1604 //! \param    float* pLumaExcursion
1605 //!           [out] Pointer to Luma Excursion
1606 //! \param    float* pChromaZero
1607 //!           [out] Pointer to Chroma Offset
1608 //! \param    float* pChromaExcursion
1609 //!           [out] Pointer to Chroma Excursion
1610 //! \return   MOS_STATUS
1611 //!
VpHal_HdrGetYuvRangeAndOffset(VPHAL_CSPACE cspace,float * pLumaOffset,float * pLumaExcursion,float * pChromaZero,float * pChromaExcursion)1612 MOS_STATUS VpHal_HdrGetYuvRangeAndOffset(
1613     VPHAL_CSPACE cspace,
1614     float*       pLumaOffset,
1615     float*       pLumaExcursion,
1616     float*       pChromaZero,
1617     float*       pChromaExcursion)
1618 {
1619     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1620 
1621     VPHAL_PUBLIC_CHK_NULL(pLumaOffset);
1622     VPHAL_PUBLIC_CHK_NULL(pLumaExcursion);
1623     VPHAL_PUBLIC_CHK_NULL(pChromaZero);
1624     VPHAL_PUBLIC_CHK_NULL(pChromaExcursion);
1625 
1626     switch (cspace)
1627     {
1628     case CSpace_BT601_FullRange:
1629     case CSpace_BT709_FullRange:
1630     case CSpace_BT601Gray_FullRange:
1631     case CSpace_BT2020_FullRange:
1632         *pLumaOffset = 0.0f;
1633         *pLumaExcursion = 255.0f;
1634         *pChromaZero = 128.0f;
1635         *pChromaExcursion = 255.0f;
1636         break;
1637 
1638     case CSpace_BT601:
1639     case CSpace_BT709:
1640     case CSpace_xvYCC601: // since matrix is the same as 601, use the same range
1641     case CSpace_xvYCC709: // since matrix is the same as 709, use the same range
1642     case CSpace_BT601Gray:
1643     case CSpace_BT2020:
1644         *pLumaOffset = 16.0f;
1645         *pLumaExcursion = 219.0f;
1646         *pChromaZero = 128.0f;
1647         *pChromaExcursion = 224.0f;
1648         break;
1649 
1650     default:
1651         *pLumaOffset = 0.0f;
1652         *pLumaExcursion = 255.0f;
1653         *pChromaZero = 128.0f;
1654         *pChromaExcursion = 255.0f;
1655         break;
1656     }
1657 
1658     *pLumaOffset /= 255.0f;
1659     *pLumaExcursion /= 255.0f;
1660     *pChromaZero /= 255.0f;
1661     *pChromaExcursion /= 255.0f;
1662 
1663 finish:
1664     return eStatus;
1665 }
1666 
1667 //!
1668 //! \brief    Calculate Rgb Range and Offest
1669 //! \details  Calculate Rgb Range and Offest
1670 //! \param    VPHAL_CSPACE cspace
1671 //!           [in] Source color space
1672 //! \param    float* pLumaOffset
1673 //!           [out] Pointer to Rgb Offset
1674 //! \param    float* pLumaExcursion
1675 //!           [out] Pointer to Rgb Excursion
1676 //! \return   MOS_STATUS
1677 //!
VpHal_HdrGetRgbRangeAndOffset(VPHAL_CSPACE cspace,float * pRgbOffset,float * pRgbExcursion)1678 MOS_STATUS VpHal_HdrGetRgbRangeAndOffset(
1679     VPHAL_CSPACE cspace,
1680     float*       pRgbOffset,
1681     float*       pRgbExcursion)
1682 {
1683     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1684 
1685     VPHAL_PUBLIC_CHK_NULL(pRgbOffset);
1686     VPHAL_PUBLIC_CHK_NULL(pRgbExcursion);
1687 
1688     switch (cspace)
1689     {
1690     case CSpace_sRGB:
1691     case CSpace_BT2020_RGB:
1692         *pRgbOffset = 0.0f;
1693         *pRgbExcursion = 255.0f;
1694         break;
1695 
1696     case CSpace_stRGB:
1697     case CSpace_BT2020_stRGB:
1698         *pRgbOffset = 16.0f;
1699         *pRgbExcursion = 219.0f;
1700         break;
1701 
1702     default:
1703         *pRgbOffset = 0.0f;
1704         *pRgbExcursion = 255.0f;
1705         break;
1706     }
1707 
1708     *pRgbOffset /= 255.0f;
1709     *pRgbExcursion /= 255.0f;
1710 
1711 finish:
1712     return eStatus;
1713 }
1714 
1715 //!
1716 //! \brief    Calculate Yuv To Rgb Matrix
1717 //! \details  Calculate Yuv To Rgb Matrix
1718 //! \param    VPHAL_CSPACE src
1719 //!           [in] Source color space
1720 //! \param    VPHAL_CSPACE dst
1721 //!           [in] Dest color space
1722 //! \param    float* pTransferMatrix
1723 //!           [in] Pointer to input transfer matrix
1724 //! \param    float* pOutMatrix
1725 //!           [out] Pointer to output transfer matrix for curbe
1726 //! \return   MOS_STATUS
1727 //!
VpHal_HdrCalcYuvToRgbMatrix(VPHAL_CSPACE src,VPHAL_CSPACE dst,float * pTransferMatrix,float * pOutMatrix)1728 MOS_STATUS VpHal_HdrCalcYuvToRgbMatrix(
1729     VPHAL_CSPACE    src,
1730     VPHAL_CSPACE    dst,
1731     float*          pTransferMatrix,
1732     float*          pOutMatrix)
1733 {
1734     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1735     float   Y_o = 0.0f, Y_e = 0.0f, C_z = 0.0f, C_e = 0.0f;
1736     float   R_o = 0.0f, R_e = 0.0f;
1737 
1738     VPHAL_PUBLIC_CHK_NULL(pTransferMatrix);
1739     VPHAL_PUBLIC_CHK_NULL(pOutMatrix);
1740 
1741     VpHal_HdrGetRgbRangeAndOffset(dst, &R_o, &R_e);
1742     VpHal_HdrGetYuvRangeAndOffset(src, &Y_o, &Y_e, &C_z, &C_e);
1743 
1744     // after + (3x3)(3x3)
1745     pOutMatrix[0] = pTransferMatrix[0] * R_e / Y_e;
1746     pOutMatrix[4] = pTransferMatrix[4] * R_e / Y_e;
1747     pOutMatrix[8] = pTransferMatrix[8] * R_e / Y_e;
1748     pOutMatrix[1] = pTransferMatrix[1] * R_e / C_e;
1749     pOutMatrix[5] = pTransferMatrix[5] * R_e / C_e;
1750     pOutMatrix[9] = pTransferMatrix[9] * R_e / C_e;
1751     pOutMatrix[2] = pTransferMatrix[2] * R_e / C_e;
1752     pOutMatrix[6] = pTransferMatrix[6] * R_e / C_e;
1753     pOutMatrix[10] = pTransferMatrix[10] * R_e / C_e;
1754 
1755     // (3x1) - (3x3)(3x3)(3x1)
1756     pOutMatrix[3] = R_o - (pOutMatrix[0] * Y_o + pOutMatrix[1] * C_z + pOutMatrix[2] * C_z);
1757     pOutMatrix[7] = R_o - (pOutMatrix[4] * Y_o + pOutMatrix[5] * C_z + pOutMatrix[6] * C_z);
1758     pOutMatrix[11] = R_o - (pOutMatrix[8] * Y_o + pOutMatrix[9] * C_z + pOutMatrix[10] * C_z);
1759 
1760 finish:
1761     return eStatus;
1762 }
1763 
1764 //!
1765 //! \brief    Calculate Rgb To Yuv Matrix
1766 //! \details  Calculate Rgb To Yuv Matrix
1767 //! \param    VPHAL_CSPACE src
1768 //!           [in] Source color space
1769 //! \param    VPHAL_CSPACE dst
1770 //!           [in] Dest color space
1771 //! \param    float* pTransferMatrix
1772 //!           [in] Pointer to input transfer matrix
1773 //! \param    float* pOutMatrix
1774 //!           [out] Pointer to output transfer matrix for curbe
1775 //! \return   MOS_STATUS
1776 //!
VpHal_HdrCalcRgbToYuvMatrix(VPHAL_CSPACE src,VPHAL_CSPACE dst,float * pTransferMatrix,float * pOutMatrix)1777 MOS_STATUS VpHal_HdrCalcRgbToYuvMatrix(
1778     VPHAL_CSPACE    src,
1779     VPHAL_CSPACE    dst,
1780     float*          pTransferMatrix,
1781     float*          pOutMatrix)
1782 {
1783     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1784     float   Y_o = 0.0f, Y_e = 0.0f, C_z = 0.0f, C_e = 0.0f;
1785     float   R_o = 0.0f, R_e = 0.0f;
1786 
1787     VPHAL_PUBLIC_CHK_NULL(pTransferMatrix);
1788     VPHAL_PUBLIC_CHK_NULL(pOutMatrix);
1789 
1790     VpHal_HdrGetRgbRangeAndOffset(src, &R_o, &R_e);
1791     VpHal_HdrGetYuvRangeAndOffset(dst, &Y_o, &Y_e, &C_z, &C_e);
1792 
1793     // multiplication of + onwards
1794     pOutMatrix[0] = pTransferMatrix[0] * Y_e / R_e;
1795     pOutMatrix[1] = pTransferMatrix[1] * Y_e / R_e;
1796     pOutMatrix[2] = pTransferMatrix[2] * Y_e / R_e;
1797     pOutMatrix[4] = pTransferMatrix[4] * C_e / R_e;
1798     pOutMatrix[5] = pTransferMatrix[5] * C_e / R_e;
1799     pOutMatrix[6] = pTransferMatrix[6] * C_e / R_e;
1800     pOutMatrix[8] = pTransferMatrix[8] * C_e / R_e;
1801     pOutMatrix[9] = pTransferMatrix[9] * C_e / R_e;
1802     pOutMatrix[10] = pTransferMatrix[10] * C_e / R_e;
1803 
1804     pOutMatrix[7] = Y_o - Y_e * R_o / R_e;
1805     pOutMatrix[3] = C_z;
1806     pOutMatrix[11] = C_z;
1807 
1808 finish:
1809     return eStatus;
1810 }
1811 
1812 //!
1813 //! \brief    Calculate CCM Matrix
1814 //! \details  Calculate CCM Matrix
1815 //! \param    float* pTransferMatrix
1816 //!           [in] Pointer to input transfer matrix
1817 //! \param    float* pOutMatrix
1818 //!           [out] Pointer to output transfer matrix for curbe
1819 //! \return   MOS_STATUS
1820 //!
VpHal_HdrCalcCCMMatrix(float * pTransferMatrix,float * pOutMatrix)1821 MOS_STATUS VpHal_HdrCalcCCMMatrix(
1822     float*          pTransferMatrix,
1823     float*          pOutMatrix)
1824 {
1825     MOS_STATUS  eStatus = MOS_STATUS_SUCCESS;
1826 
1827     VPHAL_PUBLIC_CHK_NULL(pTransferMatrix);
1828     VPHAL_PUBLIC_CHK_NULL(pOutMatrix);
1829 
1830     // multiplication of + onwards
1831     pOutMatrix[0] = pTransferMatrix[1];
1832     pOutMatrix[1] = pTransferMatrix[2];
1833     pOutMatrix[2] = pTransferMatrix[0];
1834     pOutMatrix[4] = pTransferMatrix[5];
1835     pOutMatrix[5] = pTransferMatrix[6];
1836     pOutMatrix[6] = pTransferMatrix[4];
1837     pOutMatrix[8] = pTransferMatrix[9];
1838     pOutMatrix[9] = pTransferMatrix[10];
1839     pOutMatrix[10] = pTransferMatrix[8];
1840 
1841     pOutMatrix[3] = pTransferMatrix[11];
1842     pOutMatrix[7] = pTransferMatrix[3];
1843     pOutMatrix[11] = pTransferMatrix[7];
1844 
1845 finish:
1846     return eStatus;
1847 }