1 /*
2 * Copyright (c) 2018-2021, 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     vp_resource_manager.cpp
24 //! \brief    The source file of the base class of vp resource manager
25 //! \details  all the vp resources will be traced here for usages using intermeida
26 //!           surfaces.
27 //!
28 #include "vp_resource_manager.h"
29 #include "vp_vebox_cmd_packet.h"
30 #include "sw_filter_pipe.h"
31 #include "vp_utils.h"
32 #include "vp_platform_interface.h"
33 
34 using namespace std;
35 namespace vp
36 {
37 
38 #define VP_SAME_SAMPLE_THRESHOLD        0
39 #define VP_COMP_CMFC_COEFF_WIDTH        64
40 #define VP_COMP_CMFC_COEFF_HEIGHT       8
41 
IsInterleaveFirstField(VPHAL_SAMPLE_TYPE sampleType)42 inline bool IsInterleaveFirstField(VPHAL_SAMPLE_TYPE sampleType)
43 {
44     VP_FUNC_CALL();
45     return ((sampleType == SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD)   ||
46             (sampleType == SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD)     ||
47             (sampleType == SAMPLE_SINGLE_TOP_FIELD));
48 }
49 
50 extern const VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATION g_cInit_VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATIONS =
51 {
52     // DWORD 0
53     {
54         {NOISE_BLF_RANGE_THRESHOLD_S0_DEFAULT},           // RangeThrStart0
55     },
56 
57     // DWORD 1
58     {
59         {NOISE_BLF_RANGE_THRESHOLD_S1_DEFAULT},           // RangeThrStart1
60     },
61 
62     // DWORD 2
63     {
64         {NOISE_BLF_RANGE_THRESHOLD_S2_DEFAULT},           // RangeThrStart2
65     },
66 
67     // DWORD 3
68     {
69         {NOISE_BLF_RANGE_THRESHOLD_S3_DEFAULT},           // RangeThrStart3
70     },
71 
72     // DWORD 4
73     {
74         {NOISE_BLF_RANGE_THRESHOLD_S4_DEFAULT},           // RangeThrStart4
75     },
76 
77     // DWORD 5
78     {
79         {NOISE_BLF_RANGE_THRESHOLD_S5_DEFAULT},           // RangeThrStart5
80     },
81 
82     // DWORD 6
83     {
84         {0},                                              // Reserved
85     },
86 
87     // DWORD 7
88     {
89         {0},                                              // Reserved
90     },
91 
92     // DWORD 8
93     {
94         {NOISE_BLF_RANGE_WGTS0_DEFAULT},                  // RangeWgt0
95     },
96 
97     // DWORD 9
98     {
99         {NOISE_BLF_RANGE_WGTS1_DEFAULT},                  // RangeWgt1
100     },
101 
102     // DWORD 10
103     {
104         {NOISE_BLF_RANGE_WGTS2_DEFAULT},                  // RangeWgt2
105     },
106 
107     // DWORD 11
108     {
109         {NOISE_BLF_RANGE_WGTS3_DEFAULT},                  // RangeWgt3
110     },
111 
112     // DWORD 12
113     {
114         {NOISE_BLF_RANGE_WGTS4_DEFAULT},                  // RangeWgt4
115     },
116 
117     // DWORD 13
118     {
119         {NOISE_BLF_RANGE_WGTS5_DEFAULT},                  // RangeWgt5
120     },
121 
122     // DWORD 14
123     {
124         {0},                                              // Reserved
125     },
126 
127     // DWORD 15
128     {
129         {0},                                              // Reserved
130     },
131 
132     // DWORD 16 - 41: DistWgt[5][5]
133     {
134         {NOISE_BLF_DISTANCE_WGTS00_DEFAULT, NOISE_BLF_DISTANCE_WGTS01_DEFAULT, NOISE_BLF_DISTANCE_WGTS02_DEFAULT, NOISE_BLF_DISTANCE_WGTS01_DEFAULT, NOISE_BLF_DISTANCE_WGTS00_DEFAULT},
135         {NOISE_BLF_DISTANCE_WGTS10_DEFAULT, NOISE_BLF_DISTANCE_WGTS11_DEFAULT, NOISE_BLF_DISTANCE_WGTS12_DEFAULT, NOISE_BLF_DISTANCE_WGTS11_DEFAULT, NOISE_BLF_DISTANCE_WGTS10_DEFAULT},
136         {NOISE_BLF_DISTANCE_WGTS20_DEFAULT, NOISE_BLF_DISTANCE_WGTS21_DEFAULT, NOISE_BLF_DISTANCE_WGTS22_DEFAULT, NOISE_BLF_DISTANCE_WGTS21_DEFAULT, NOISE_BLF_DISTANCE_WGTS20_DEFAULT},
137         {NOISE_BLF_DISTANCE_WGTS10_DEFAULT, NOISE_BLF_DISTANCE_WGTS11_DEFAULT, NOISE_BLF_DISTANCE_WGTS12_DEFAULT, NOISE_BLF_DISTANCE_WGTS11_DEFAULT, NOISE_BLF_DISTANCE_WGTS10_DEFAULT},
138         {NOISE_BLF_DISTANCE_WGTS00_DEFAULT, NOISE_BLF_DISTANCE_WGTS01_DEFAULT, NOISE_BLF_DISTANCE_WGTS02_DEFAULT, NOISE_BLF_DISTANCE_WGTS01_DEFAULT, NOISE_BLF_DISTANCE_WGTS00_DEFAULT},
139     },
140 
141     // Padding
142     {
143         0,                                      // Padding
144         0,                                      // Padding
145         0,                                      // Padding
146         0,                                      // Padding
147         0,                                      // Padding
148         0,                                      // Padding
149         0,                                      // Padding
150     }
151 };
152 
VpResourceManager(MOS_INTERFACE & osInterface,VpAllocator & allocator,VphalFeatureReport & reporting,vp::VpPlatformInterface & vpPlatformInterface)153 VpResourceManager::VpResourceManager(MOS_INTERFACE &osInterface, VpAllocator &allocator, VphalFeatureReport &reporting, vp::VpPlatformInterface &vpPlatformInterface)
154     : m_osInterface(osInterface), m_allocator(allocator), m_reporting(reporting), m_vpPlatformInterface(vpPlatformInterface)
155 {
156     InitSurfaceConfigMap();
157 }
158 
~VpResourceManager()159 VpResourceManager::~VpResourceManager()
160 {
161     // Clean all intermedia Resource
162     DestoryVeboxOutputSurface();
163     DestoryVeboxDenoiseOutputSurface();
164 
165     for (uint32_t i = 0; i < VP_NUM_STMM_SURFACES; i++)
166     {
167         if (m_veboxSTMMSurface[i])
168         {
169             m_allocator.DestroyVpSurface(m_veboxSTMMSurface[i]);
170         }
171     }
172 
173     if (m_veboxStatisticsSurface)
174     {
175         m_allocator.DestroyVpSurface(m_veboxStatisticsSurface);
176     }
177 
178     if (m_veboxRgbHistogram)
179     {
180         m_allocator.DestroyVpSurface(m_veboxRgbHistogram);
181     }
182 
183     if (m_veboxDNTempSurface)
184     {
185         m_allocator.DestroyVpSurface(m_veboxDNTempSurface);
186     }
187 
188     if (m_veboxDNSpatialConfigSurface)
189     {
190         m_allocator.DestroyVpSurface(m_veboxDNSpatialConfigSurface);
191     }
192 
193     if (m_vebox3DLookUpTables)
194     {
195         m_allocator.DestroyVpSurface(m_vebox3DLookUpTables);
196     }
197 
198     while (!m_intermediaSurfaces.empty())
199     {
200         VP_SURFACE * surf = m_intermediaSurfaces.back();
201         m_allocator.DestroyVpSurface(surf);
202         m_intermediaSurfaces.pop_back();
203     }
204 
205     for (int i = 0; i < VP_NUM_FC_INTERMEDIA_SURFACES; ++i)
206     {
207         m_allocator.DestroyVpSurface(m_fcIntermediateSurface[i]);
208     }
209 
210     m_allocator.DestroyVpSurface(m_cmfcCoeff);
211 
212     m_allocator.CleanRecycler();
213 }
214 
CleanTempSurfaces()215 void VpResourceManager::CleanTempSurfaces()
216 {
217     VP_FUNC_CALL();
218 
219     while (!m_tempSurface.empty())
220     {
221         auto it = m_tempSurface.begin();
222         m_allocator.DestroyVpSurface(it->second);
223         m_tempSurface.erase(it);
224     }
225 }
226 
OnNewFrameProcessStart(SwFilterPipe & pipe)227 MOS_STATUS VpResourceManager::OnNewFrameProcessStart(SwFilterPipe &pipe)
228 {
229     VP_FUNC_CALL();
230 
231     VP_SURFACE *inputSurface    = pipe.GetSurface(true, 0);
232     VP_SURFACE *outputSurface   = pipe.GetSurface(false, 0);
233     SwFilter   *diFilter        = pipe.GetSwFilter(true, 0, FeatureTypeDi);
234 
235     if (nullptr == inputSurface && nullptr == outputSurface)
236     {
237         VP_PUBLIC_ASSERTMESSAGE("Both input and output surface being nullptr!");
238         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
239     }
240 
241     if (0 != m_currentPipeIndex)
242     {
243         VP_PUBLIC_ASSERTMESSAGE("m_currentPipeIndex(%d) is not 0. May caused by OnNewFrameProcessEnd not paired with OnNewFrameProcessStart!");
244         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
245     }
246 
247     VP_SURFACE *pastSurface   = pipe.GetPastSurface(0);
248     VP_SURFACE *futureSurface = pipe.GetFutureSurface(0);
249 
250     int32_t currentFrameId = inputSurface ? inputSurface->FrameID : (outputSurface ? outputSurface->FrameID : 0);
251     int32_t pastFrameId = pastSurface ? pastSurface->FrameID : 0;
252     int32_t futureFrameId = futureSurface ? futureSurface->FrameID : 0;
253 
254     m_currentFrameIds.valid                     = true;
255     m_currentFrameIds.diEnabled                 = nullptr != diFilter;
256     m_currentFrameIds.currentFrameId            = currentFrameId;
257     m_currentFrameIds.pastFrameId               = pastFrameId;
258     m_currentFrameIds.futureFrameId             = futureFrameId;
259     m_currentFrameIds.pastFrameAvailable        = pastSurface ? true : false;
260     m_currentFrameIds.futureFrameAvailable      = futureSurface ? true : false;
261 
262     // Only set sameSamples flag DI enabled frames.
263     if (m_pastFrameIds.valid && m_currentFrameIds.pastFrameAvailable &&
264         m_pastFrameIds.diEnabled && m_currentFrameIds.diEnabled)
265     {
266         m_sameSamples   =
267                WITHIN_BOUNDS(
268                       m_currentFrameIds.currentFrameId - m_pastFrameIds.currentFrameId,
269                       -VP_SAME_SAMPLE_THRESHOLD,
270                       VP_SAME_SAMPLE_THRESHOLD) &&
271                WITHIN_BOUNDS(
272                       m_currentFrameIds.pastFrameId - m_pastFrameIds.pastFrameId,
273                       -VP_SAME_SAMPLE_THRESHOLD,
274                       VP_SAME_SAMPLE_THRESHOLD);
275 
276         if (m_sameSamples)
277         {
278             m_outOfBound = false;
279         }
280         else
281         {
282             m_outOfBound =
283                 OUT_OF_BOUNDS(
284                         m_currentFrameIds.pastFrameId - m_pastFrameIds.currentFrameId,
285                         -VP_SAME_SAMPLE_THRESHOLD,
286                         VP_SAME_SAMPLE_THRESHOLD);
287         }
288     }
289     // bSameSamples flag also needs to be set for no reference case
290     else if (m_pastFrameIds.valid && !m_currentFrameIds.pastFrameAvailable &&
291         m_pastFrameIds.diEnabled && m_currentFrameIds.diEnabled)
292     {
293         m_sameSamples   =
294                WITHIN_BOUNDS(
295                       m_currentFrameIds.currentFrameId - m_pastFrameIds.currentFrameId,
296                       -VP_SAME_SAMPLE_THRESHOLD,
297                       VP_SAME_SAMPLE_THRESHOLD);
298         m_outOfBound    = false;
299     }
300     else
301     {
302         m_sameSamples   = false;
303         m_outOfBound    = false;
304     }
305 
306     if (inputSurface)
307     {
308         m_maxSrcRect.right  = MOS_MAX(m_maxSrcRect.right, inputSurface->rcSrc.right);
309         m_maxSrcRect.bottom = MOS_MAX(m_maxSrcRect.bottom, inputSurface->rcSrc.bottom);
310     }
311 
312     // Swap buffers for next iteration
313     if (!m_sameSamples)
314     {
315         m_currentDnOutput   = (m_currentDnOutput + 1) & 1;
316         m_currentStmmIndex  = (m_currentStmmIndex + 1) & 1;
317     }
318 
319     m_pastFrameIds = m_currentFrameIds;
320 
321     m_isFcIntermediateSurfacePrepared = false;
322 
323     return MOS_STATUS_SUCCESS;
324 }
325 
GetFormatForFcIntermediaSurface(MOS_FORMAT & format,MEDIA_CSPACE & colorSpace,SwFilterPipe & featurePipe)326 MOS_STATUS VpResourceManager::GetFormatForFcIntermediaSurface(MOS_FORMAT& format,
327     MEDIA_CSPACE &colorSpace, SwFilterPipe &featurePipe)
328 {
329     VP_FUNC_CALL();
330 
331     PVP_SURFACE                     target = nullptr;
332     int32_t                         surfCount = (int32_t)featurePipe.GetSurfaceCount(true);
333     PVP_SURFACE                     src = nullptr;
334     int32_t                         i = 0, j = 0;
335     int32_t                         csc_count = 0;
336     int32_t                         csc_min = surfCount + 1;
337     int32_t                         cspace_in_use[CSpace_Count] = {};
338     bool                            bYUVTarget = false;
339     MEDIA_CSPACE                    cs = CSpace_Any;
340     MEDIA_CSPACE                    tempColorSpace = CSpace_Any;
341     MEDIA_CSPACE                    mainColorSpace = CSpace_None;
342 
343     auto PostProcess = [&](MOS_STATUS status)
344     {
345         VP_PUBLIC_NORMALMESSAGE("Main_ColorSpace %d, Temp_ColorSpace %d, csc_count %d.",
346             mainColorSpace, tempColorSpace, csc_count);
347         colorSpace = tempColorSpace;
348         // Set AYUV or ARGB output depending on intermediate cspace
349         if (KernelDll_IsCspace(colorSpace, CSpace_RGB))
350         {
351             format = Format_A8R8G8B8;
352         }
353         else
354         {
355             format = Format_AYUV;
356         }
357         return status;
358     };
359 
360     // Check if target is YUV
361     target     = featurePipe.GetSurface(false, 0);
362 
363     VP_PUBLIC_CHK_NULL_RETURN(target);
364     VP_PUBLIC_CHK_NULL_RETURN(target->osSurface);
365 
366     bYUVTarget = IS_RGB_FORMAT(target->osSurface->Format) ? false : true;
367 
368     // Gets primary video cspace
369     // Implements xvYCC passthrough mode
370     // Set Color Spaces in use
371     MOS_ZeroMemory(cspace_in_use, sizeof(cspace_in_use));
372     for (i = 0; i < surfCount; i++)
373     {
374         // Get current source
375         src = featurePipe.GetSurface(true, i);
376         VP_PUBLIC_CHK_NULL_RETURN(src);
377         VP_PUBLIC_CHK_NULL_RETURN(src->osSurface);
378 
379         // Save Main Video color space
380         if (src->SurfType == SURF_IN_PRIMARY &&
381             mainColorSpace == CSpace_None)
382         {
383             mainColorSpace = src->ColorSpace;
384         }
385 
386         // Set xvYCC pass through mode
387         if (bYUVTarget &&
388             (src->ColorSpace == CSpace_xvYCC709 ||
389              src->ColorSpace == CSpace_xvYCC601))
390         {
391             tempColorSpace = src->ColorSpace;
392             return PostProcess(MOS_STATUS_SUCCESS);
393         }
394 
395         // Don't take PAL formats into consideration
396         if ((!IS_PAL_FORMAT(src->osSurface->Format)) &&
397              src->ColorSpace > CSpace_Any &&
398              src->ColorSpace < CSpace_Count)
399         {
400             cs = KernelDll_TranslateCspace(src->ColorSpace);
401             if (cs >= CSpace_Any)
402             {
403                 cspace_in_use[cs]++;
404             }
405         }
406     }
407 
408     // For every CS in use, iterate through source CS and keep a
409     // count of number of CSC operation needed. Determine the Temporary
410     // color space as the one requiring min. # of CSC ops.
411     for (j = (CSpace_Any + 1); j < CSpace_Count; j++)
412     {
413         // Skip color spaces not in use
414         if (!cspace_in_use[j])
415         {
416             continue;
417         }
418 
419         // Count # of CS conversions
420         cs = (MEDIA_CSPACE) j;
421         csc_count = 0;
422         for (i = 0; i < surfCount; i++)
423         {
424             // Get current source
425             src = featurePipe.GetSurface(true, i);
426             VP_PUBLIC_CHK_NULL_RETURN(src);
427             VP_PUBLIC_CHK_NULL_RETURN(src->osSurface);
428 
429             auto featureSubPipe = featurePipe.GetSwFilterSubPipe(true, i);
430             VP_PUBLIC_CHK_NULL_RETURN(featureSubPipe);
431 
432             // Ignore palletized layers
433             if (IS_PAL_FORMAT(src->osSurface->Format) ||
434                 src->ColorSpace == CSpace_Any)
435             {
436                 continue;
437             }
438 
439             auto procamp = dynamic_cast<SwFilterProcamp *>(featureSubPipe->GetSwFilter(FeatureTypeProcamp));
440             // Check if CSC/PA is required
441             if (KernelDll_TranslateCspace(src->ColorSpace) != cs ||
442                 (procamp &&
443                  procamp->GetSwFilterParams().procampParams &&
444                  procamp->GetSwFilterParams().procampParams->bEnabled))
445             {
446                 csc_count++;
447             }
448         }
449 
450         // Save best choice as requiring minimum number of CSC operations
451         // Use main cspace as default if same CSC count
452         if ((csc_count <  csc_min) ||
453             (csc_count == csc_min && cs == mainColorSpace))
454         {
455             tempColorSpace = cs;
456             csc_min = csc_count;
457         }
458     }
459 
460     // If all layers are palletized, use the CS from first layer (as good as any other)
461     if (tempColorSpace == CSpace_Any && surfCount > 0)
462     {
463         src = featurePipe.GetSurface(true, 0);
464         VP_PUBLIC_CHK_NULL_RETURN(src);
465         tempColorSpace = src->ColorSpace;
466     }
467 
468     return PostProcess(MOS_STATUS_SUCCESS);
469 }
470 
PrepareFcIntermediateSurface(SwFilterPipe & featurePipe)471 MOS_STATUS VpResourceManager::PrepareFcIntermediateSurface(SwFilterPipe &featurePipe)
472 {
473     VP_FUNC_CALL();
474 
475     if (m_isFcIntermediateSurfacePrepared)
476     {
477         return MOS_STATUS_SUCCESS;
478     }
479 
480     m_isFcIntermediateSurfacePrepared = true;
481 
482     MOS_FORMAT      format      = Format_Any;
483     MEDIA_CSPACE    colorSpace  = CSpace_Any;
484 
485     VP_PUBLIC_CHK_STATUS_RETURN(GetFormatForFcIntermediaSurface(format, colorSpace, featurePipe));
486 
487     auto target = featurePipe.GetSurface(false, 0);
488     VP_PUBLIC_CHK_NULL_RETURN(target);
489     VP_PUBLIC_CHK_NULL_RETURN(target->osSurface);
490 
491     uint32_t tempWidth  = target->osSurface->dwWidth;
492     uint32_t tempHeight = target->osSurface->dwHeight;
493 
494     uint32_t curWidth = 0;
495     uint32_t curHeight = 0;
496 
497     if (m_fcIntermediateSurface[0])
498     {
499         VP_PUBLIC_CHK_NULL_RETURN(m_fcIntermediateSurface[0]->osSurface);
500         curWidth    = m_fcIntermediateSurface[0]->osSurface->dwWidth;
501         curHeight   = m_fcIntermediateSurface[0]->osSurface->dwHeight;
502     }
503 
504     // Allocate buffer in fixed increments
505     tempWidth  = MOS_ALIGN_CEIL(tempWidth , VPHAL_BUFFER_SIZE_INCREMENT);
506     tempHeight = MOS_ALIGN_CEIL(tempHeight, VPHAL_BUFFER_SIZE_INCREMENT);
507 
508     for (int i = 0; i < VP_NUM_FC_INTERMEDIA_SURFACES; ++i)
509     {
510         if (tempWidth > curWidth || tempHeight > curHeight)
511         {
512             bool allocated = false;
513             // Get surface parameter.
514             // Use A8R8G8B8 instead of real surface format to ensure the surface can be reused for both AYUV and A8R8G8B8,
515             // since for A8R8G8B8, tile64 is used, while for AYUV, both tile4 and tile64 is ok.
516             if (m_fcIntermediateSurface[i] && m_fcIntermediateSurface[i]->osSurface)
517             {
518                 m_fcIntermediateSurface[i]->osSurface->Format = Format_A8R8G8B8;
519             }
520             VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
521                 m_fcIntermediateSurface[i],
522                 "fcIntermediaSurface",
523                 Format_A8R8G8B8,
524                 MOS_GFXRES_2D,
525                 MOS_TILE_Y,
526                 tempWidth,
527                 tempHeight,
528                 false,
529                 MOS_MMC_DISABLED,
530                 allocated,
531                 false,
532                 IsDeferredResourceDestroyNeeded(),
533                 MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_RENDER,
534                 MOS_TILE_UNSET_GMM,
535                 MOS_MEMPOOL_DEVICEMEMORY,
536                 true));
537             m_fcIntermediateSurface[i]->osSurface->Format = format;
538             m_fcIntermediateSurface[i]->ColorSpace = colorSpace;
539         }
540         else
541         {
542             m_fcIntermediateSurface[i]->osSurface->dwWidth = tempWidth;
543             m_fcIntermediateSurface[i]->osSurface->dwHeight = tempHeight;
544             m_fcIntermediateSurface[i]->osSurface->Format = format;
545             m_fcIntermediateSurface[i]->ColorSpace = colorSpace;
546         }
547         m_fcIntermediateSurface[i]->rcSrc = target->rcSrc;
548         m_fcIntermediateSurface[i]->rcDst = target->rcDst;
549     }
550 
551     return MOS_STATUS_SUCCESS;
552 }
553 
OnNewFrameProcessEnd()554 void VpResourceManager::OnNewFrameProcessEnd()
555 {
556     VP_FUNC_CALL();
557     m_allocator.CleanRecycler();
558     m_currentPipeIndex = 0;
559     CleanTempSurfaces();
560 }
561 
InitSurfaceConfigMap()562 void VpResourceManager::InitSurfaceConfigMap()
563 {
564     VP_FUNC_CALL();
565     ///*             _b64DI
566     //               |      _sfcEnable
567     //               |      |      _sameSample
568     //               |      |      |      _outOfBound
569     //               |      |      |      |      _pastRefAvailable
570     //               |      |      |      |      |      _futureRefAvailable
571     //               |      |      |      |      |      |      _firstDiField
572     //               |      |      |      |      |      |      |      _currentInputSurface
573     //               |      |      |      |      |      |      |      |                     _pastInputSurface
574     //               |      |      |      |      |      |      |      |                     |                       _currentOutputSurface
575     //               |      |      |      |      |      |      |      |                     |                       |                     _pastOutputSurface*/
576     //               |      |      |      |      |      |      |      |                     |                       |                     |                 */
577     AddSurfaceConfig(true,  true,  false, false, true,  false, true,  VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_PAST_REF, VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_FRAME0);
578     AddSurfaceConfig(true,  true,  true,  false, true,  false, false, VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_NULL,     VEBOX_SURFACE_NULL,   VEBOX_SURFACE_NULL);
579     AddSurfaceConfig(true,  true,  false, false, false, false, true,  VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_NULL,     VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_NULL);
580     AddSurfaceConfig(true,  true,  false, false, false, false, false, VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_NULL,     VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_NULL);
581     AddSurfaceConfig(true,  true,  false, false, true,  false, false, VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_PAST_REF, VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_FRAME0);
582     AddSurfaceConfig(true,  true,  true,  false, false, false, true,  VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_NULL,     VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_NULL);
583     AddSurfaceConfig(true,  true,  true,  false, false, false, false, VEBOX_SURFACE_INPUT,  VEBOX_SURFACE_NULL,     VEBOX_SURFACE_FRAME1, VEBOX_SURFACE_NULL);
584 }
585 
GetHistogramSurfaceSize(VP_EXECUTE_CAPS & caps,uint32_t inputWidth,uint32_t inputHeight)586 uint32_t VpResourceManager::GetHistogramSurfaceSize(VP_EXECUTE_CAPS& caps, uint32_t inputWidth, uint32_t inputHeight)
587 {
588     VP_FUNC_CALL();
589 
590     // Allocate Rgb Histogram surface----------------------------------------------
591     // Size of RGB histograms, 1 set for each slice. For single slice, other set will be 0
592     uint32_t dwSize = VP_VEBOX_RGB_HISTOGRAM_SIZE;
593     dwSize += VP_VEBOX_RGB_ACE_HISTOGRAM_SIZE_RESERVED;
594     // Size of ACE histograms, 1 set for each slice. For single slice, other set will be 0
595     dwSize += VP_VEBOX_ACE_HISTOGRAM_SIZE_PER_FRAME_PER_SLICE *         // Ace histogram size per slice
596         VP_NUM_FRAME_PREVIOUS_CURRENT *                                 // Ace for Prev + Curr
597         VP_VEBOX_HISTOGRAM_SLICES_COUNT;                                // Total number of slices
598     return dwSize;
599 }
600 
GetResourceHint(std::vector<FeatureType> & featurePool,SwFilterPipe & executedFilters,RESOURCE_ASSIGNMENT_HINT & hint)601 MOS_STATUS VpResourceManager::GetResourceHint(std::vector<FeatureType> &featurePool, SwFilterPipe& executedFilters, RESOURCE_ASSIGNMENT_HINT &hint)
602 {
603     VP_FUNC_CALL();
604 
605     uint32_t    index      = 0;
606     SwFilterSubPipe *inputPipe = executedFilters.GetSwFilterSubPipe(true, index);
607 
608     // only process Primary surface
609     if (inputPipe == nullptr)
610     {
611         VP_PUBLIC_NORMALMESSAGE("No inputPipe, so there is no hint message!");
612         return MOS_STATUS_SUCCESS;
613     }
614     for (auto filterID : featurePool)
615     {
616         SwFilter* feature = (SwFilter*)inputPipe->GetSwFilter(FeatureType(filterID));
617         if (feature)
618         {
619             VP_PUBLIC_CHK_STATUS_RETURN(feature->SetResourceAssignmentHint(hint));
620         }
621     }
622     return MOS_STATUS_SUCCESS;
623 }
624 
625 struct VP_SURFACE_PARAMS
626 {
627     uint32_t                width               = 0;
628     uint32_t                height              = 0;
629     MOS_FORMAT              format              = Format_None;
630     MOS_TILE_TYPE           tileType            = MOS_TILE_X;
631     MOS_RESOURCE_MMC_MODE   surfCompressionMode = MOS_MMC_DISABLED;
632     bool                    surfCompressible    = false;
633     VPHAL_CSPACE            colorSpace          = CSpace_None;
634     RECT                    rcSrc               = {0, 0, 0, 0};  //!< Source rectangle
635     RECT                    rcDst               = {0, 0, 0, 0};  //!< Destination rectangle
636     RECT                    rcMaxSrc            = {0, 0, 0, 0};  //!< Max source rectangle
637     VPHAL_SAMPLE_TYPE       sampleType          = SAMPLE_PROGRESSIVE;
638 };
Get3DLutOutputColorAndFormat(VPHAL_CSPACE & colorSpace,MOS_FORMAT & format,SwFilterPipe & executedFilters)639 MOS_STATUS VpResourceManager::Get3DLutOutputColorAndFormat(VPHAL_CSPACE &colorSpace, MOS_FORMAT &format, SwFilterPipe &executedFilters)
640 {
641     SwFilterHdr *hdr = dynamic_cast<SwFilterHdr *>(executedFilters.GetSwFilter(true, 0, FeatureType::FeatureTypeHdr));
642     if (hdr)
643     {
644         colorSpace = hdr->GetSwFilterParams().dstColorSpace;
645         format     = hdr->GetSwFilterParams().formatOutput;
646     }
647     else
648     {   // caps.b3DlutOutput =1, in hdr tests hdr flag should not be false.
649         VP_PUBLIC_ASSERTMESSAGE("It is unexcepted for HDR case with caps.b3DlutOutput as true, return INVALID_PARAMETER");
650         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
651 
652     }
653     return MOS_STATUS_SUCCESS;
654 }
GetIntermediaOutputSurfaceColorAndFormat(VP_EXECUTE_CAPS & caps,SwFilterPipe & executedFilters,MOS_FORMAT & format,VPHAL_CSPACE & colorSpace)655 MOS_STATUS VpResourceManager::GetIntermediaOutputSurfaceColorAndFormat(VP_EXECUTE_CAPS &caps, SwFilterPipe &executedFilters, MOS_FORMAT &format, VPHAL_CSPACE &colorSpace)
656 {
657     VP_SURFACE *inputSurface = executedFilters.GetSurface(true, 0);
658     VP_PUBLIC_CHK_NULL_RETURN(inputSurface);
659     if (caps.bRender)
660     {
661         SwFilterCsc *csc = dynamic_cast<SwFilterCsc *>(executedFilters.GetSwFilter(true, 0, FeatureType::FeatureTypeCscOnRender));
662         if (csc)
663         {
664             format            = csc->GetSwFilterParams().formatOutput;
665             colorSpace        = csc->GetSwFilterParams().output.colorSpace;
666             return MOS_STATUS_SUCCESS;
667         }
668 
669     }
670     else if (caps.bSFC)
671     {
672         SwFilterCsc *csc = dynamic_cast<SwFilterCsc *>(executedFilters.GetSwFilter(true, 0, FeatureType::FeatureTypeCscOnSfc));
673         if (csc)
674         {
675             format            = csc->GetSwFilterParams().formatOutput;
676             colorSpace        = csc->GetSwFilterParams().output.colorSpace;
677             return MOS_STATUS_SUCCESS;
678         }
679     }
680     else if (caps.b3DlutOutput)
681     {
682         VP_PUBLIC_CHK_STATUS_RETURN(Get3DLutOutputColorAndFormat(colorSpace, format, executedFilters));
683         return MOS_STATUS_SUCCESS;
684     }
685     else if (caps.bVebox)
686     {
687         SwFilterCsc *csc = dynamic_cast<SwFilterCsc *>(executedFilters.GetSwFilter(true, 0, FeatureType::FeatureTypeCscOnVebox));
688         if (csc)
689         {
690             format            = csc->GetSwFilterParams().formatOutput;
691             colorSpace        = csc->GetSwFilterParams().output.colorSpace;
692             return MOS_STATUS_SUCCESS;
693         }
694     }
695 
696     format            = inputSurface->osSurface->Format;
697     colorSpace        = inputSurface->ColorSpace;
698     return MOS_STATUS_SUCCESS;
699 }
700 
GetIntermediaOutputSurfaceParams(VP_EXECUTE_CAPS & caps,VP_SURFACE_PARAMS & params,SwFilterPipe & executedFilters)701 MOS_STATUS VpResourceManager::GetIntermediaOutputSurfaceParams(VP_EXECUTE_CAPS& caps, VP_SURFACE_PARAMS &params, SwFilterPipe &executedFilters)
702 {
703     VP_FUNC_CALL();
704 
705     SwFilterScaling *scaling = dynamic_cast<SwFilterScaling *>(executedFilters.GetSwFilter(true, 0, FeatureType::FeatureTypeScaling));
706     SwFilterRotMir *rotMir = dynamic_cast<SwFilterRotMir *>(executedFilters.GetSwFilter(true, 0, FeatureType::FeatureTypeRotMir));
707     SwFilterDeinterlace *di = dynamic_cast<SwFilterDeinterlace *>(executedFilters.GetSwFilter(true, 0, FeatureType::FeatureTypeDi));
708     VP_SURFACE *inputSurface = executedFilters.GetSurface(true, 0);
709 
710     VP_PUBLIC_CHK_NULL_RETURN(inputSurface);
711 
712     if (scaling)
713     {
714         params.width = scaling->GetSwFilterParams().output.dwWidth;
715         params.height = scaling->GetSwFilterParams().output.dwHeight;
716         params.sampleType = scaling->GetSwFilterParams().output.sampleType;
717         params.rcSrc = scaling->GetSwFilterParams().output.rcSrc;
718         params.rcDst = scaling->GetSwFilterParams().output.rcDst;
719         params.rcMaxSrc = scaling->GetSwFilterParams().output.rcMaxSrc;
720     }
721     else
722     {
723         params.width = inputSurface->osSurface->dwWidth;
724         params.height = inputSurface->osSurface->dwHeight;
725         params.sampleType = di ? SAMPLE_PROGRESSIVE : inputSurface->SampleType;
726         params.rcSrc = inputSurface->rcSrc;
727         params.rcDst = inputSurface->rcDst;
728         params.rcMaxSrc = inputSurface->rcMaxSrc;
729     }
730 
731     // Do not use rotatoin flag in scaling swfilter as it has not been initialized here.
732     // It will be initialized during pipe update after resource being assigned.
733     if (rotMir &&
734         (rotMir->GetSwFilterParams().rotation == VPHAL_ROTATION_90 ||
735         rotMir->GetSwFilterParams().rotation == VPHAL_ROTATION_270 ||
736         rotMir->GetSwFilterParams().rotation == VPHAL_ROTATE_90_MIRROR_VERTICAL ||
737         rotMir->GetSwFilterParams().rotation == VPHAL_ROTATE_90_MIRROR_HORIZONTAL))
738     {
739         swap(params.width, params.height);
740         RECT tmp = params.rcSrc;
741         RECT_ROTATE(params.rcSrc, tmp);
742         tmp = params.rcDst;
743         RECT_ROTATE(params.rcDst, tmp);
744         tmp = params.rcMaxSrc;
745         RECT_ROTATE(params.rcMaxSrc, tmp);
746     }
747 
748     VP_PUBLIC_CHK_STATUS_RETURN(GetIntermediaOutputSurfaceColorAndFormat(caps, executedFilters, params.format, params.colorSpace));
749 
750     params.tileType = MOS_TILE_Y;
751     params.surfCompressionMode = caps.bRender ? MOS_MMC_RC : MOS_MMC_MC;
752     params.surfCompressible = true;
753 
754     return MOS_STATUS_SUCCESS;
755 }
756 
GetFcIntermediateSurfaceForOutput(VP_SURFACE * & intermediaSurface,SwFilterPipe & executedFilters)757 MOS_STATUS VpResourceManager::GetFcIntermediateSurfaceForOutput(VP_SURFACE *&intermediaSurface, SwFilterPipe &executedFilters)
758 {
759     VP_FUNC_CALL();
760 
761     if (!m_isFcIntermediateSurfacePrepared)
762     {
763         VP_PUBLIC_ASSERTMESSAGE("Fc intermediate surface is not allocated.");
764         VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
765     }
766 
767     intermediaSurface = nullptr;
768 
769     for (uint32_t i = 0; i < executedFilters.GetSurfaceCount(true); ++i)
770     {
771         uint32_t j = 0;
772         auto surf = executedFilters.GetSurface(true, i);
773         VP_PUBLIC_CHK_NULL_RETURN(surf);
774         for (j = 0; j < VP_NUM_FC_INTERMEDIA_SURFACES; ++j)
775         {
776             auto intermediateSurface = m_fcIntermediateSurface[j];
777             VP_PUBLIC_CHK_NULL_RETURN(intermediateSurface);
778             if (surf->GetAllocationHandle(&m_osInterface) == intermediateSurface->GetAllocationHandle(&m_osInterface))
779             {
780                 uint32_t selIndex = (j + 1) % VP_NUM_FC_INTERMEDIA_SURFACES;
781                 intermediaSurface = m_fcIntermediateSurface[selIndex];
782                 break;
783             }
784         }
785         if (j < VP_NUM_FC_INTERMEDIA_SURFACES)
786         {
787             break;
788         }
789     }
790     // If intermediate surface not in use in current pipe, use first one by default.
791     if (nullptr == intermediaSurface)
792     {
793         intermediaSurface = m_fcIntermediateSurface[0];
794     }
795 
796     return MOS_STATUS_SUCCESS;
797 }
798 
AssignIntermediaSurface(VP_EXECUTE_CAPS & caps,SwFilterPipe & executedFilters)799 MOS_STATUS VpResourceManager::AssignIntermediaSurface(VP_EXECUTE_CAPS& caps, SwFilterPipe &executedFilters)
800 {
801     VP_FUNC_CALL();
802 
803     VP_SURFACE *outputSurface = executedFilters.GetSurface(false, 0);
804     VP_SURFACE *intermediaSurface = nullptr;
805     if (outputSurface)
806     {
807         // No need intermedia surface.
808         return MOS_STATUS_SUCCESS;
809     }
810 
811     if (caps.bComposite)
812     {
813         VP_PUBLIC_CHK_STATUS_RETURN(GetFcIntermediateSurfaceForOutput(intermediaSurface, executedFilters));
814     }
815     else
816     {
817         while (m_currentPipeIndex >= m_intermediaSurfaces.size())
818         {
819             m_intermediaSurfaces.push_back(nullptr);
820         }
821         VP_SURFACE_PARAMS params = {};
822         bool allocated = false;
823         // Get surface parameter.
824         GetIntermediaOutputSurfaceParams(caps, params, executedFilters);
825 
826         VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
827             m_intermediaSurfaces[m_currentPipeIndex],
828             "IntermediaSurface",
829             params.format,
830             MOS_GFXRES_2D,
831             params.tileType,
832             params.width,
833             params.height,
834             params.surfCompressible,
835             params.surfCompressionMode,
836             allocated,
837             false,
838             IsDeferredResourceDestroyNeeded(),
839             MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_RENDER));
840 
841         VP_PUBLIC_CHK_NULL_RETURN(m_intermediaSurfaces[m_currentPipeIndex]);
842 
843         m_intermediaSurfaces[m_currentPipeIndex]->ColorSpace = params.colorSpace;
844         m_intermediaSurfaces[m_currentPipeIndex]->rcDst      = params.rcDst;
845         m_intermediaSurfaces[m_currentPipeIndex]->rcSrc      = params.rcSrc;
846         m_intermediaSurfaces[m_currentPipeIndex]->rcMaxSrc   = params.rcMaxSrc;
847         m_intermediaSurfaces[m_currentPipeIndex]->SampleType = params.sampleType;
848 
849         intermediaSurface = m_intermediaSurfaces[m_currentPipeIndex];
850     }
851 
852     VP_PUBLIC_CHK_NULL_RETURN(intermediaSurface);
853     VP_SURFACE *output = m_allocator.AllocateVpSurface(*intermediaSurface);
854     VP_PUBLIC_CHK_NULL_RETURN(output);
855     output->SurfType = SURF_OUT_RENDERTARGET;
856 
857     executedFilters.AddSurface(output, false, 0);
858 
859     return MOS_STATUS_SUCCESS;
860 }
861 
GetCopyInstOfExtSurface(VP_SURFACE * surf)862 VP_SURFACE * VpResourceManager::GetCopyInstOfExtSurface(VP_SURFACE* surf)
863 {
864     VP_FUNC_CALL();
865 
866     if (nullptr == surf || 0 == surf->GetAllocationHandle(&m_osInterface))
867     {
868         return nullptr;
869     }
870     // Do not use allocation handle as key as some parameters in VP_SURFACE
871     // may be different for same allocation, e.g. SurfType for intermedia surface.
872     auto it = m_tempSurface.find((uint64_t)surf);
873     if (it != m_tempSurface.end())
874     {
875         return it->second;
876     }
877     VP_SURFACE *surface = m_allocator.AllocateVpSurface(*surf);
878     if (surface)
879     {
880         m_tempSurface.insert(make_pair((uint64_t)surf, surface));
881     }
882     else
883     {
884         VP_PUBLIC_ASSERTMESSAGE("Allocate temp surface faild!");
885     }
886 
887     return surface;
888 }
889 
AssignFcResources(VP_EXECUTE_CAPS & caps,std::vector<VP_SURFACE * > & inputSurfaces,VP_SURFACE * outputSurface,std::vector<VP_SURFACE * > & pastSurfaces,std::vector<VP_SURFACE * > & futureSurfaces,RESOURCE_ASSIGNMENT_HINT resHint,VP_SURFACE_SETTING & surfSetting)890 MOS_STATUS VpResourceManager::AssignFcResources(VP_EXECUTE_CAPS &caps, std::vector<VP_SURFACE *> &inputSurfaces, VP_SURFACE *outputSurface,
891     std::vector<VP_SURFACE *> &pastSurfaces, std::vector<VP_SURFACE *> &futureSurfaces,
892     RESOURCE_ASSIGNMENT_HINT resHint, VP_SURFACE_SETTING &surfSetting)
893 {
894     VP_FUNC_CALL();
895 
896     bool allocated = false;
897     auto *skuTable = MosInterface::GetSkuTable(m_osInterface.osStreamState);
898     Mos_MemPool memTypeSurfVideoMem = MOS_MEMPOOL_VIDEOMEMORY;
899 
900     if (skuTable && MEDIA_IS_SKU(skuTable, FtrLimitedLMemBar))
901     {
902         memTypeSurfVideoMem = MOS_MEMPOOL_DEVICEMEMORY;
903     }
904 
905     for (size_t i = 0; i < inputSurfaces.size(); ++i)
906     {
907         surfSetting.surfGroup.insert(std::make_pair((SurfaceType)(SurfaceTypeFcInputLayer0 + i), inputSurfaces[i]));
908 
909         if (!resHint.isIScalingTypeNone)
910         {
911             // For Interlaced scaling, 2nd field is part of the same frame.
912             // For Field weaving, 2nd field is passed in as a ref.
913             VP_SURFACE *surfField1Dual = nullptr;
914             if (resHint.isFieldWeaving)
915             {
916                 surfField1Dual = pastSurfaces[i];
917                 VP_PUBLIC_NORMALMESSAGE("Field weaving case. 2nd field is passed in as a ref.");
918             }
919             else
920             {
921                 surfField1Dual = GetCopyInstOfExtSurface(inputSurfaces[i]);
922                 VP_PUBLIC_NORMALMESSAGE("Interlaced scaling. 2nd field is part of the same frame.");
923             }
924             VP_PUBLIC_CHK_NULL_RETURN(surfField1Dual);
925             surfSetting.surfGroup.insert(std::make_pair((SurfaceType)(SurfaceTypeFcInputLayer0Field1Dual + i), surfField1Dual));
926         }
927     }
928     surfSetting.surfGroup.insert(std::make_pair(SurfaceTypeFcTarget0, outputSurface));
929 
930     // Allocate auto CSC Coeff Surface
931     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
932         m_cmfcCoeff,
933         "CSCCoeffSurface",
934         Format_L8,
935         MOS_GFXRES_2D,
936         MOS_TILE_LINEAR,
937         VP_COMP_CMFC_COEFF_WIDTH,
938         VP_COMP_CMFC_COEFF_HEIGHT,
939         false,
940         MOS_MMC_DISABLED,
941         allocated,
942         false,
943         IsDeferredResourceDestroyNeeded(),
944         MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_RENDER,
945         MOS_TILE_UNSET_GMM,
946         memTypeSurfVideoMem,
947         MOS_MEMPOOL_DEVICEMEMORY == memTypeSurfVideoMem));
948 
949     surfSetting.surfGroup.insert(std::make_pair(SurfaceTypeFcCscCoeff, m_cmfcCoeff));
950 
951     return MOS_STATUS_SUCCESS;
952 }
953 
AssignRenderResource(VP_EXECUTE_CAPS & caps,std::vector<VP_SURFACE * > & inputSurfaces,VP_SURFACE * outputSurface,std::vector<VP_SURFACE * > & pastSurfaces,std::vector<VP_SURFACE * > & futureSurfaces,RESOURCE_ASSIGNMENT_HINT resHint,VP_SURFACE_SETTING & surfSetting)954 MOS_STATUS VpResourceManager::AssignRenderResource(VP_EXECUTE_CAPS &caps, std::vector<VP_SURFACE *> &inputSurfaces, VP_SURFACE *outputSurface,
955     std::vector<VP_SURFACE *> &pastSurfaces, std::vector<VP_SURFACE *> &futureSurfaces, RESOURCE_ASSIGNMENT_HINT resHint, VP_SURFACE_SETTING &surfSetting)
956 {
957     VP_FUNC_CALL();
958 
959     if (caps.bComposite)
960     {
961         VP_PUBLIC_CHK_STATUS_RETURN(AssignFcResources(caps, inputSurfaces, outputSurface, pastSurfaces, futureSurfaces, resHint, surfSetting));
962     }
963     else
964     {
965         if (1 != inputSurfaces.size())
966         {
967             VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
968         }
969         surfSetting.surfGroup.insert(std::make_pair(SurfaceTypeRenderInput, inputSurfaces[0]));
970         VP_PUBLIC_CHK_STATUS_RETURN(AssignVeboxResourceForRender(caps, inputSurfaces[0], resHint, surfSetting));
971     }
972     return MOS_STATUS_SUCCESS;
973 }
974 
AssignVeboxResourceForRender(VP_EXECUTE_CAPS & caps,VP_SURFACE * inputSurface,RESOURCE_ASSIGNMENT_HINT resHint,VP_SURFACE_SETTING & surfSetting)975 MOS_STATUS VpResourceManager::AssignVeboxResourceForRender(VP_EXECUTE_CAPS &caps, VP_SURFACE *inputSurface, RESOURCE_ASSIGNMENT_HINT resHint, VP_SURFACE_SETTING &surfSetting)
976 {
977     VP_FUNC_CALL();
978 
979     if (!caps.bRender)
980     {
981         return MOS_STATUS_INVALID_PARAMETER;
982     }
983 
984     return MOS_STATUS_SUCCESS;
985 }
986 
AssignExecuteResource(std::vector<FeatureType> & featurePool,VP_EXECUTE_CAPS & caps,SwFilterPipe & executedFilters)987 MOS_STATUS VpResourceManager::AssignExecuteResource(std::vector<FeatureType> &featurePool, VP_EXECUTE_CAPS& caps, SwFilterPipe &executedFilters)
988 {
989     VP_FUNC_CALL();
990 
991     std::vector<VP_SURFACE *> inputSurfaces, pastSurfaces, futureSurfaces;
992     for (uint32_t i = 0; i < executedFilters.GetSurfaceCount(true); ++i)
993     {
994         VP_SURFACE *inputSurface = GetCopyInstOfExtSurface(executedFilters.GetSurface(true, i));
995         VP_PUBLIC_CHK_NULL_RETURN(inputSurface);
996         inputSurfaces.push_back(inputSurface);
997 
998         VP_SURFACE *pastSurface = GetCopyInstOfExtSurface(executedFilters.GetPastSurface(i));
999         pastSurfaces.push_back(pastSurface ? pastSurface : nullptr);
1000 
1001         VP_SURFACE *futureSurface = GetCopyInstOfExtSurface(executedFilters.GetFutureSurface(i));
1002         futureSurfaces.push_back(futureSurface ? futureSurface : nullptr);
1003     }
1004     VP_SURFACE                  *outputSurface  = GetCopyInstOfExtSurface(executedFilters.GetSurface(false, 0));
1005 
1006     RESOURCE_ASSIGNMENT_HINT    resHint         = {};
1007 
1008     VP_PUBLIC_CHK_STATUS_RETURN(GetResourceHint(featurePool, executedFilters, resHint));
1009 
1010     if (nullptr == outputSurface && IsOutputSurfaceNeeded(caps))
1011     {
1012         VP_PUBLIC_CHK_STATUS_RETURN(AssignIntermediaSurface(caps, executedFilters));
1013         outputSurface  = GetCopyInstOfExtSurface(executedFilters.GetSurface(false, 0));
1014         VP_PUBLIC_CHK_NULL_RETURN(outputSurface);
1015     }
1016 
1017     VP_PUBLIC_CHK_STATUS_RETURN(AssignExecuteResource(caps, inputSurfaces, outputSurface,
1018         pastSurfaces, futureSurfaces, resHint, executedFilters.GetSurfacesSetting()));
1019     ++m_currentPipeIndex;
1020     return MOS_STATUS_SUCCESS;
1021 }
1022 
AssignExecuteResource(VP_EXECUTE_CAPS & caps,std::vector<VP_SURFACE * > & inputSurfaces,VP_SURFACE * outputSurface,std::vector<VP_SURFACE * > & pastSurfaces,std::vector<VP_SURFACE * > & futureSurfaces,RESOURCE_ASSIGNMENT_HINT resHint,VP_SURFACE_SETTING & surfSetting)1023 MOS_STATUS VpResourceManager::AssignExecuteResource(VP_EXECUTE_CAPS& caps, std::vector<VP_SURFACE *> &inputSurfaces, VP_SURFACE *outputSurface,
1024     std::vector<VP_SURFACE *> &pastSurfaces, std::vector<VP_SURFACE *> &futureSurfaces, RESOURCE_ASSIGNMENT_HINT resHint, VP_SURFACE_SETTING &surfSetting)
1025 {
1026     VP_FUNC_CALL();
1027 
1028     surfSetting.Clean();
1029 
1030     if (caps.bVebox || caps.bDnKernelUpdate)
1031     {
1032         // Create Vebox Resources
1033         VP_PUBLIC_CHK_STATUS_RETURN(AssignVeboxResource(caps, inputSurfaces[0], outputSurface, pastSurfaces[0], futureSurfaces[0], resHint, surfSetting));
1034     }
1035 
1036     if (caps.bRender)
1037     {
1038         VP_PUBLIC_CHK_STATUS_RETURN(AssignRenderResource(caps, inputSurfaces, outputSurface, pastSurfaces, futureSurfaces, resHint, surfSetting));
1039     }
1040 
1041     return MOS_STATUS_SUCCESS;
1042 }
1043 
GetVeboxOutputParams(VP_EXECUTE_CAPS & executeCaps,MOS_FORMAT inputFormat,MOS_TILE_TYPE inputTileType,MOS_FORMAT outputFormat,MOS_FORMAT & veboxOutputFormat,MOS_TILE_TYPE & veboxOutputTileType)1044 MOS_STATUS GetVeboxOutputParams(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, MOS_TILE_TYPE inputTileType, MOS_FORMAT outputFormat,
1045                                 MOS_FORMAT &veboxOutputFormat, MOS_TILE_TYPE &veboxOutputTileType)
1046 {
1047     VP_FUNC_CALL();
1048 
1049     // Vebox Chroma Co-Sited downsampleing is part of VEO. It only affects format of vebox output surface, but not
1050     // affect sfc input format, that's why different logic between GetSfcInputFormat and GetVeboxOutputParams.
1051     // Check DI first and downsampling to NV12 if possible to save bandwidth no matter IECP enabled or not.
1052     if (executeCaps.bDI || executeCaps.bDiProcess2ndField)
1053     {
1054         // NV12 will be used if target output is not YUV2 to save bandwidth.
1055         if (outputFormat == Format_YUY2)
1056         {
1057             veboxOutputFormat = Format_YUY2;
1058         }
1059         else
1060         {
1061             veboxOutputFormat = Format_NV12;
1062         }
1063         veboxOutputTileType = MOS_TILE_Y;
1064     }
1065     else if (executeCaps.bIECP && executeCaps.bCGC && executeCaps.bBt2020ToRGB)
1066     {
1067         veboxOutputFormat   = Format_A8B8G8R8;
1068         veboxOutputTileType = inputTileType;
1069     }
1070     else if (executeCaps.bIECP)
1071     {
1072         // Upsampling to yuv444 for IECP input/output.
1073         // To align with legacy path, need to check whether inputFormat can also be used for IECP case,
1074         // in which case IECP down sampling will be applied.
1075         veboxOutputFormat = Format_AYUV;
1076         veboxOutputTileType = inputTileType;
1077     }
1078     else
1079     {
1080         veboxOutputFormat = inputFormat;
1081         veboxOutputTileType = inputTileType;
1082     }
1083 
1084     return MOS_STATUS_SUCCESS;
1085 }
1086 
GetSfcInputFormat(VP_EXECUTE_CAPS & executeCaps,MOS_FORMAT inputFormat,VPHAL_CSPACE colorSpaceOutput)1087 MOS_FORMAT GetSfcInputFormat(VP_EXECUTE_CAPS &executeCaps, MOS_FORMAT inputFormat, VPHAL_CSPACE colorSpaceOutput)
1088 {
1089     VP_FUNC_CALL();
1090 
1091     // Vebox Chroma Co-Sited downsampling is part of VEO. It only affects format of vebox output surface, but not
1092     // affect sfc input format, that's why different logic between GetSfcInputFormat and GetVeboxOutputParams.
1093     // Check HDR case first, since 3DLUT output is fixed RGB32.
1094     // Then Check IECP, since IECP is done after DI, and the vebox downsampling not affect the vebox input.
1095     if (executeCaps.b3DlutOutput)
1096     {
1097         return IS_COLOR_SPACE_BT2020(colorSpaceOutput) ? Format_R10G10B10A2 : Format_A8B8G8R8;
1098     }
1099     else if (executeCaps.bIECP && executeCaps.bCGC && executeCaps.bBt2020ToRGB)
1100     {
1101         // Upsampling to RGB444, and using ABGR as Vebox output
1102         return Format_A8B8G8R8;
1103     }
1104     else if (executeCaps.bIECP)
1105     {
1106         // Upsampling to yuv444 for IECP input/output.
1107         // To align with legacy path, need to check whether inputFormat can also be used for IECP case,
1108         // in which case IECP down sampling will be applied.
1109         return Format_AYUV;
1110     }
1111     else if (executeCaps.bDI)
1112     {
1113         // If the input is 4:2:0, then chroma data is doubled vertically to 4:2:2
1114         // For executeCaps.bDiProcess2ndField, no DI enabled in vebox, so no need
1115         // set to YUY2 here.
1116         return Format_YUY2;
1117     }
1118 
1119     return inputFormat;
1120 }
1121 
ReAllocateVeboxOutputSurface(VP_EXECUTE_CAPS & caps,VP_SURFACE * inputSurface,VP_SURFACE * outputSurface,bool & allocated)1122 MOS_STATUS VpResourceManager::ReAllocateVeboxOutputSurface(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface,  bool &allocated)
1123 {
1124     VP_FUNC_CALL();
1125 
1126     MOS_RESOURCE_MMC_MODE           surfCompressionMode = MOS_MMC_DISABLED;
1127     bool                            bSurfCompressible   = false;
1128     uint32_t                        i                   = 0;
1129     auto                           *skuTable            = MosInterface::GetSkuTable(m_osInterface.osStreamState);
1130     Mos_MemPool                     memTypeSurfVideoMem = MOS_MEMPOOL_VIDEOMEMORY;
1131 
1132     VP_PUBLIC_CHK_NULL_RETURN(inputSurface);
1133     VP_PUBLIC_CHK_NULL_RETURN(inputSurface->osSurface);
1134     VP_PUBLIC_CHK_NULL_RETURN(outputSurface);
1135     VP_PUBLIC_CHK_NULL_RETURN(outputSurface->osSurface);
1136 
1137     if (skuTable && MEDIA_IS_SKU(skuTable, FtrLimitedLMemBar))
1138     {
1139         memTypeSurfVideoMem = MOS_MEMPOOL_DEVICEMEMORY;
1140     }
1141 
1142     MOS_FORMAT      veboxOutputFormat                   = inputSurface->osSurface->Format;
1143     MOS_TILE_TYPE   veboxOutputTileType                 = inputSurface->osSurface->TileType;
1144 
1145     VP_PUBLIC_CHK_STATUS_RETURN(GetVeboxOutputParams(caps, inputSurface->osSurface->Format, inputSurface->osSurface->TileType,
1146                                             outputSurface->osSurface->Format, veboxOutputFormat, veboxOutputTileType));
1147 
1148     allocated = false;
1149     if (IS_VP_VEBOX_DN_ONLY(caps))
1150     {
1151         bSurfCompressible = inputSurface->osSurface->bCompressible;
1152         surfCompressionMode = inputSurface->osSurface->CompressionMode;
1153     }
1154     else
1155     {
1156         bSurfCompressible = true;
1157         surfCompressionMode = MOS_MMC_MC;
1158     }
1159 
1160     if (m_currentFrameIds.pastFrameAvailable && m_currentFrameIds.futureFrameAvailable)
1161     {
1162         // Not switch back to 2 after being set to 4.
1163         m_veboxOutputCount = 4;
1164     }
1165 
1166     for (i = 0; i < m_veboxOutputCount; i++)
1167     {
1168         VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
1169             m_veboxOutput[i],
1170             "VeboxSurfaceOutput",
1171             veboxOutputFormat,
1172             MOS_GFXRES_2D,
1173             veboxOutputTileType,
1174             inputSurface->osSurface->dwWidth,
1175             inputSurface->osSurface->dwHeight,
1176             bSurfCompressible,
1177             surfCompressionMode,
1178             allocated,
1179             false,
1180             IsDeferredResourceDestroyNeeded(),
1181             MOS_HW_RESOURCE_USAGE_VP_OUTPUT_PICTURE_FF,
1182             MOS_TILE_UNSET_GMM,
1183             memTypeSurfVideoMem,
1184             MOS_MEMPOOL_DEVICEMEMORY == memTypeSurfVideoMem));
1185 
1186         m_veboxOutput[i]->ColorSpace = inputSurface->ColorSpace;
1187         m_veboxOutput[i]->rcDst      = inputSurface->rcDst;
1188         m_veboxOutput[i]->rcSrc      = inputSurface->rcSrc;
1189         m_veboxOutput[i]->rcMaxSrc   = inputSurface->rcMaxSrc;
1190 
1191         m_veboxOutput[i]->SampleType = SAMPLE_PROGRESSIVE;
1192     }
1193 
1194     if (allocated)
1195     {
1196         // Report Compress Status
1197         if (m_veboxOutput[0]->osSurface)
1198         {
1199             m_reporting.GetFeatures().ffdiCompressible = m_veboxOutput[0]->osSurface->bIsCompressed;
1200             m_reporting.GetFeatures().ffdiCompressMode = (uint8_t)m_veboxOutput[0]->osSurface->CompressionMode;
1201         }
1202     }
1203 
1204     return MOS_STATUS_SUCCESS;
1205 }
1206 
ReAllocateVeboxDenoiseOutputSurface(VP_EXECUTE_CAPS & caps,VP_SURFACE * inputSurface,bool & allocated)1207 MOS_STATUS VpResourceManager::ReAllocateVeboxDenoiseOutputSurface(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, bool &allocated)
1208 {
1209     VP_FUNC_CALL();
1210 
1211     MOS_RESOURCE_MMC_MODE           surfCompressionMode = MOS_MMC_DISABLED;
1212     bool                            bSurfCompressible   = false;
1213     MOS_TILE_MODE_GMM               tileModeByForce     = MOS_TILE_UNSET_GMM;
1214     auto *                          skuTable            = MosInterface::GetSkuTable(m_osInterface.osStreamState);
1215     Mos_MemPool                     memTypeSurfVideoMem = MOS_MEMPOOL_VIDEOMEMORY;
1216     uint32_t                        dwHeight;
1217     MOS_TILE_TYPE                   TileType;
1218 
1219     VP_PUBLIC_CHK_NULL_RETURN(inputSurface);
1220     VP_PUBLIC_CHK_NULL_RETURN(inputSurface->osSurface);
1221 
1222     if (skuTable)
1223     {
1224         //DN output surface must be tile64 only when input format is bayer
1225         if (MEDIA_IS_SKU(skuTable, FtrMediaTile64) &&
1226             IS_BAYER_FORMAT(inputSurface->osSurface->Format))
1227         {
1228             tileModeByForce = MOS_TILE_64_GMM;
1229         }
1230 
1231         if (MEDIA_IS_SKU(skuTable, FtrLimitedLMemBar))
1232         {
1233             memTypeSurfVideoMem = MOS_MEMPOOL_DEVICEMEMORY;
1234         }
1235     }
1236 
1237     allocated = false;
1238     if (IS_VP_VEBOX_DN_ONLY(caps))
1239     {
1240         bSurfCompressible = inputSurface->osSurface->bCompressible;
1241         surfCompressionMode = inputSurface->osSurface->CompressionMode;
1242     }
1243     else
1244     {
1245         bSurfCompressible = true;
1246         surfCompressionMode = MOS_MMC_MC;
1247     }
1248 
1249     if (caps.bCappipe)
1250     {
1251         bSurfCompressible   = false;
1252         surfCompressionMode = MOS_MMC_DISABLED;
1253         // Add 4 to input height for DN and STMM if Bayer Pattern offset is 10 or 11
1254         if (IS_BAYER_GRBG_FORMAT(inputSurface->osSurface->Format) ||
1255             IS_BAYER_GBRG_FORMAT(inputSurface->osSurface->Format))
1256         {
1257             dwHeight = inputSurface->osSurface->dwHeight + 4;
1258         }
1259         else
1260         {
1261             dwHeight = inputSurface->osSurface->dwHeight;
1262         }
1263         // For Bayer pattern inputs only the Current Denoised Output/Previous Denoised Input are in Tile-Y
1264         TileType = IS_BAYER_FORMAT(inputSurface->osSurface->Format) ? MOS_TILE_Y : inputSurface->osSurface->TileType;
1265     }
1266     else
1267     {
1268         dwHeight = inputSurface->osSurface->dwHeight;
1269         TileType = inputSurface->osSurface->TileType;
1270     }
1271 
1272     for (uint32_t i = 0; i < VP_NUM_DN_SURFACES; i++)
1273     {
1274         VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
1275             m_veboxDenoiseOutput[i],
1276             "VeboxFFDNSurface",
1277             inputSurface->osSurface->Format,
1278             MOS_GFXRES_2D,
1279             TileType,
1280             inputSurface->osSurface->dwWidth,
1281             dwHeight,
1282             bSurfCompressible,
1283             surfCompressionMode,
1284             allocated,
1285             false,
1286             IsDeferredResourceDestroyNeeded(),
1287             MOS_HW_RESOURCE_USAGE_VP_INPUT_REFERENCE_FF,
1288             tileModeByForce,
1289             memTypeSurfVideoMem,
1290             MOS_MEMPOOL_DEVICEMEMORY == memTypeSurfVideoMem));
1291 
1292         // if allocated, pVeboxState->PastSurface is not valid for DN reference.
1293         if (allocated)
1294         {
1295             // If DI is enabled, try to use app's reference if provided
1296             if (caps.bRefValid && caps.bDI)
1297             {
1298                 //CopySurfaceValue(pVeboxState->m_previousSurface, pVeboxState->m_currentSurface->pBwdRef);
1299             }
1300             else
1301             {
1302                 caps.bRefValid = false;
1303             }
1304             // Report Compress Status
1305             if (m_veboxDenoiseOutput[i]->osSurface)
1306             {
1307                 m_reporting.GetFeatures().ffdnCompressible = m_veboxDenoiseOutput[i]->osSurface->bIsCompressed;
1308                 m_reporting.GetFeatures().ffdnCompressMode = (uint8_t)m_veboxDenoiseOutput[i]->osSurface->CompressionMode;
1309             }
1310         }
1311         else
1312         {
1313             caps.bRefValid = true;
1314         }
1315 
1316         // DN's output format should be same to input
1317         m_veboxDenoiseOutput[i]->SampleType =
1318             inputSurface->SampleType;
1319 
1320         // Set Colorspace of FFDN
1321         m_veboxDenoiseOutput[i]->ColorSpace = inputSurface->ColorSpace;
1322 
1323         // Copy FrameID and parameters, as DN output will be used as next blt's current
1324         m_veboxDenoiseOutput[i]->FrameID = inputSurface->FrameID;
1325 
1326         // Place Holder to update report for debug purpose
1327     }
1328     return MOS_STATUS_SUCCESS;
1329 }
1330 
1331 //!
1332 //! \brief    Vebox initialize STMM History
1333 //! \details  Initialize STMM History surface
1334 //! Description:
1335 //!   This function is used by VEBox for initializing
1336 //!   the STMM surface.  The STMM / Denoise history is a custom surface used
1337 //!   for both input and output. Each cache line contains data for 4 4x4s.
1338 //!   The STMM for each 4x4 is 8 bytes, while the denoise history is 1 byte
1339 //!   and the chroma denoise history is 1 byte for each U and V.
1340 //!   Byte    Data\n
1341 //!   0       STMM for 2 luma values at luma Y=0, X=0 to 1\n
1342 //!   1       STMM for 2 luma values at luma Y=0, X=2 to 3\n
1343 //!   2       Luma Denoise History for 4x4 at 0,0\n
1344 //!   3       Not Used\n
1345 //!   4-5     STMM for luma from X=4 to 7\n
1346 //!   6       Luma Denoise History for 4x4 at 0,4\n
1347 //!   7       Not Used\n
1348 //!   8-15    Repeat for 4x4s at 0,8 and 0,12\n
1349 //!   16      STMM for 2 luma values at luma Y=1,X=0 to 1\n
1350 //!   17      STMM for 2 luma values at luma Y=1, X=2 to 3\n
1351 //!   18      U Chroma Denoise History\n
1352 //!   19      Not Used\n
1353 //!   20-31   Repeat for 3 4x4s at 1,4, 1,8 and 1,12\n
1354 //!   32      STMM for 2 luma values at luma Y=2,X=0 to 1\n
1355 //!   33      STMM for 2 luma values at luma Y=2, X=2 to 3\n
1356 //!   34      V Chroma Denoise History\n
1357 //!   35      Not Used\n
1358 //!   36-47   Repeat for 3 4x4s at 2,4, 2,8 and 2,12\n
1359 //!   48      STMM for 2 luma values at luma Y=3,X=0 to 1\n
1360 //!   49      STMM for 2 luma values at luma Y=3, X=2 to 3\n
1361 //!   50-51   Not Used\n
1362 //!   36-47   Repeat for 3 4x4s at 3,4, 3,8 and 3,12\n
1363 //! \param    [in] iSurfaceIndex
1364 //!           Index of STMM surface array
1365 //! \return   MOS_STATUS
1366 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1367 //!
VeboxInitSTMMHistory(MOS_SURFACE * stmmSurface)1368 MOS_STATUS VpResourceManager::VeboxInitSTMMHistory(MOS_SURFACE *stmmSurface)
1369 {
1370     VP_FUNC_CALL();
1371 
1372     uint32_t            dwSize = 0;
1373     int32_t             x = 0, y = 0;
1374     uint8_t*            pByte = nullptr;
1375     MOS_LOCK_PARAMS     LockFlags;
1376 
1377     VP_PUBLIC_CHK_NULL_RETURN(stmmSurface);
1378     MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS));
1379 
1380     LockFlags.WriteOnly = 1;
1381     LockFlags.TiledAsTiled = 1; // Set TiledAsTiled flag for STMM surface initialization.
1382 
1383     // Lock the surface for writing
1384     pByte = (uint8_t*)m_allocator.Lock(
1385         &stmmSurface->OsResource,
1386         &LockFlags);
1387     VP_PUBLIC_CHK_NULL_RETURN(pByte);
1388 
1389     dwSize = stmmSurface->dwWidth >> 2;
1390 
1391     // Fill STMM surface with DN history init values.
1392     for (y = 0; y < (int32_t)stmmSurface->dwHeight; y++)
1393     {
1394         for (x = 0; x < (int32_t)dwSize; x++)
1395         {
1396             MOS_FillMemory(pByte, 2, DNDI_HISTORY_INITVALUE);
1397             // skip denosie history init.
1398             pByte += 4;
1399         }
1400 
1401         pByte += stmmSurface->dwPitch - stmmSurface->dwWidth;
1402     }
1403 
1404     // Unlock the surface
1405     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.UnLock(&stmmSurface->OsResource));
1406     return MOS_STATUS_SUCCESS;
1407 }
1408 
1409 // Allocate STMM (Spatial-Temporal Motion Measure) Surfaces
ReAllocateVeboxSTMMSurface(VP_EXECUTE_CAPS & caps,VP_SURFACE * inputSurface,bool & allocated)1410 MOS_STATUS VpResourceManager::ReAllocateVeboxSTMMSurface(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, bool &allocated)
1411 {
1412     VP_FUNC_CALL();
1413 
1414     MOS_RESOURCE_MMC_MODE           surfCompressionMode = MOS_MMC_DISABLED;
1415     bool                            bSurfCompressible   = false;
1416     uint32_t                        i                   = 0;
1417     MOS_TILE_MODE_GMM               tileModeByForce     = MOS_TILE_UNSET_GMM;
1418     auto *                          skuTable            = MosInterface::GetSkuTable(m_osInterface.osStreamState);
1419     Mos_MemPool                     memTypeHistStat     = GetHistStatMemType();
1420     uint32_t                        dwHeight;
1421 
1422     VP_PUBLIC_CHK_NULL_RETURN(inputSurface);
1423     VP_PUBLIC_CHK_NULL_RETURN(inputSurface->osSurface);
1424 
1425     if (skuTable && MEDIA_IS_SKU(skuTable, FtrMediaTile64))
1426     {
1427         tileModeByForce = MOS_TILE_64_GMM;
1428     }
1429 
1430     if (caps.bCappipe)
1431     {
1432         // Add 4 to input height for DN and STMM if Bayer Pattern offset is 10 or 11
1433         if (IS_BAYER_GRBG_FORMAT(inputSurface->osSurface->Format) ||
1434             IS_BAYER_GBRG_FORMAT(inputSurface->osSurface->Format))
1435         {
1436             dwHeight = inputSurface->osSurface->dwHeight + 4;
1437         }
1438         else
1439         {
1440             dwHeight = inputSurface->osSurface->dwHeight;
1441         }
1442     }
1443     else
1444     {
1445         dwHeight = inputSurface->osSurface->dwHeight;
1446     }
1447 
1448     allocated = false;
1449     for (i = 0; i < VP_NUM_STMM_SURFACES; i++)
1450     {
1451         VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
1452             m_veboxSTMMSurface[i],
1453             "VeboxSTMMSurface",
1454             Format_STMM,
1455             MOS_GFXRES_2D,
1456             MOS_TILE_Y,
1457             inputSurface->osSurface->dwWidth,
1458             dwHeight,
1459             bSurfCompressible,
1460             surfCompressionMode,
1461             allocated,
1462             false,
1463             IsDeferredResourceDestroyNeeded(),
1464             MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_FF,
1465             tileModeByForce,
1466             memTypeHistStat,
1467             MOS_MEMPOOL_DEVICEMEMORY == memTypeHistStat));
1468 
1469         if (allocated)
1470         {
1471             VP_PUBLIC_CHK_NULL_RETURN(m_veboxSTMMSurface[i]);
1472             if (MOS_MEMPOOL_DEVICEMEMORY != memTypeHistStat)
1473             {
1474                 VP_PUBLIC_CHK_STATUS_RETURN(VeboxInitSTMMHistory(m_veboxSTMMSurface[i]->osSurface));
1475             }
1476             // Report Compress Status
1477             m_reporting.GetFeatures().stmmCompressible = bSurfCompressible;
1478             m_reporting.GetFeatures().stmmCompressMode = (uint8_t)surfCompressionMode;
1479         }
1480     }
1481     return MOS_STATUS_SUCCESS;
1482 }
1483 
DestoryVeboxOutputSurface()1484 void VpResourceManager::DestoryVeboxOutputSurface()
1485 {
1486     VP_FUNC_CALL();
1487 
1488     for (uint32_t i = 0; i < VP_MAX_NUM_VEBOX_SURFACES; i++)
1489     {
1490         m_allocator.DestroyVpSurface(m_veboxOutput[i], IsDeferredResourceDestroyNeeded());
1491     }
1492 }
1493 
DestoryVeboxDenoiseOutputSurface()1494 void VpResourceManager::DestoryVeboxDenoiseOutputSurface()
1495 {
1496     VP_FUNC_CALL();
1497 
1498     for (uint32_t i = 0; i < VP_NUM_DN_SURFACES; i++)
1499     {
1500         m_allocator.DestroyVpSurface(m_veboxDenoiseOutput[i], IsDeferredResourceDestroyNeeded());
1501     }
1502 }
1503 
DestoryVeboxSTMMSurface()1504 void VpResourceManager::DestoryVeboxSTMMSurface()
1505 {
1506     VP_FUNC_CALL();
1507 
1508     // Free DI history buffers (STMM = Spatial-temporal motion measure)
1509     for (uint32_t i = 0; i < VP_NUM_STMM_SURFACES; i++)
1510     {
1511         m_allocator.DestroyVpSurface(m_veboxSTMMSurface[i], IsDeferredResourceDestroyNeeded());
1512     }
1513 }
1514 
Get3DLutSize()1515 uint32_t VpResourceManager::Get3DLutSize()
1516 {
1517     VP_FUNC_CALL();
1518 
1519     return VP_VEBOX_HDR_3DLUT65;
1520 }
1521 
GetHistStatMemType()1522 Mos_MemPool VpResourceManager::GetHistStatMemType()
1523 {
1524     VP_FUNC_CALL();
1525 
1526     return MOS_MEMPOOL_VIDEOMEMORY;
1527 }
1528 
AllocateVeboxResource(VP_EXECUTE_CAPS & caps,VP_SURFACE * inputSurface,VP_SURFACE * outputSurface)1529 MOS_STATUS VpResourceManager::AllocateVeboxResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface)
1530 {
1531     VP_FUNC_CALL();
1532     MOS_FORMAT                      format;
1533     MOS_TILE_TYPE                   TileType;
1534     uint32_t                        dwWidth;
1535     uint32_t                        dwHeight;
1536     uint32_t                        dwSize;
1537     uint32_t                        i;
1538     MOS_RESOURCE_MMC_MODE           surfCompressionMode = MOS_MMC_DISABLED;
1539     bool                            bSurfCompressible   = false;
1540     bool                            bAllocated          = false;
1541     uint8_t                         InitValue           = 0;
1542     Mos_MemPool                     memTypeHistStat     = GetHistStatMemType();
1543 
1544     VP_PUBLIC_CHK_NULL_RETURN(inputSurface);
1545     VP_PUBLIC_CHK_NULL_RETURN(inputSurface->osSurface);
1546     VP_PUBLIC_CHK_NULL_RETURN(outputSurface);
1547     VP_PUBLIC_CHK_NULL_RETURN(outputSurface->osSurface);
1548 
1549     // change the init value when null hw is enabled
1550     if (NullHW::IsEnabled())
1551     {
1552         InitValue = 0x80;
1553     }
1554 
1555     if (IS_VP_VEBOX_DN_ONLY(caps))
1556     {
1557         bSurfCompressible = inputSurface->osSurface->bCompressible;
1558         surfCompressionMode = inputSurface->osSurface->CompressionMode;
1559     }
1560     else
1561     {
1562         bSurfCompressible = true;
1563         surfCompressionMode = MOS_MMC_MC;
1564     }
1565 
1566     // Decide DN output surface
1567     if (VeboxOutputNeeded(caps))
1568     {
1569         VP_PUBLIC_CHK_STATUS_RETURN(ReAllocateVeboxOutputSurface(caps, inputSurface, outputSurface, bAllocated));
1570     }
1571     else
1572     {
1573         DestoryVeboxOutputSurface();
1574     }
1575 
1576     if (VeboxDenoiseOutputNeeded(caps))
1577     {
1578         VP_PUBLIC_CHK_STATUS_RETURN(ReAllocateVeboxDenoiseOutputSurface(caps, inputSurface, bAllocated));
1579         if (bAllocated)
1580         {
1581             m_currentDnOutput = 0;
1582             m_pastDnOutputValid = false;
1583         }
1584     }
1585     else
1586     {
1587         DestoryVeboxDenoiseOutputSurface();
1588         m_pastDnOutputValid = false;
1589     }
1590 
1591     if (VeboxSTMMNeeded(caps, false))
1592     {
1593         VP_PUBLIC_CHK_STATUS_RETURN(ReAllocateVeboxSTMMSurface(caps, inputSurface, bAllocated));
1594         if (bAllocated)
1595         {
1596             m_currentStmmIndex = 0;
1597         }
1598     }
1599     else
1600     {
1601         DestoryVeboxSTMMSurface();
1602     }
1603 
1604 #if VEBOX_AUTO_DENOISE_SUPPORTED
1605     // Allocate Temp Surface for Vebox Update kernels----------------------------------------
1606     // the surface size is one Page
1607     dwSize = MHW_PAGE_SIZE;
1608     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
1609         m_veboxDNTempSurface,
1610         "VeboxDNTempSurface",
1611         Format_Buffer,
1612         MOS_GFXRES_BUFFER,
1613         MOS_TILE_LINEAR,
1614         dwSize,
1615         1,
1616         false,
1617         MOS_MMC_DISABLED,
1618         bAllocated,
1619         true,
1620         IsDeferredResourceDestroyNeeded(),
1621         MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_FF));
1622 
1623     // Allocate Spatial Attributes Configuration Surface for DN kernel Gen9+-----------
1624     dwSize = MHW_PAGE_SIZE;
1625     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
1626         m_veboxDNSpatialConfigSurface,
1627         "VeboxSpatialAttributesConfigurationSurface",
1628         Format_RAW,
1629         MOS_GFXRES_BUFFER,
1630         MOS_TILE_LINEAR,
1631         dwSize,
1632         1,
1633         false,
1634         MOS_MMC_DISABLED,
1635         bAllocated,
1636         false,
1637         IsDeferredResourceDestroyNeeded(),
1638         MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_FF));
1639 
1640     if (bAllocated)
1641     {
1642         // initialize Spatial Attributes Configuration Surface
1643         VP_PUBLIC_CHK_STATUS_RETURN(InitVeboxSpatialAttributesConfiguration());
1644     }
1645 
1646 #endif
1647 
1648     dwSize = GetHistogramSurfaceSize(caps, inputSurface->osSurface->dwWidth, inputSurface->osSurface->dwHeight);
1649 
1650     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
1651         m_veboxRgbHistogram,
1652         "VeboxLaceAceRgbHistogram",
1653         Format_Buffer,
1654         MOS_GFXRES_BUFFER,
1655         MOS_TILE_LINEAR,
1656         dwSize,
1657         1,
1658         false,
1659         MOS_MMC_DISABLED,
1660         bAllocated,
1661         false,
1662         IsDeferredResourceDestroyNeeded(),
1663         MOS_HW_RESOURCE_USAGE_VP_INTERNAL_WRITE_FF,
1664         MOS_TILE_UNSET_GMM,
1665         memTypeHistStat,
1666         MOS_MEMPOOL_DEVICEMEMORY == memTypeHistStat));
1667 
1668     m_isHistogramReallocated = bAllocated;
1669 
1670     if (bAllocated && NullHW::IsEnabled())
1671     {
1672         // Initialize veboxRgbHistogram Surface
1673         VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.OsFillResource(
1674             &(m_veboxRgbHistogram->osSurface->OsResource),
1675             dwSize,
1676             InitValue));
1677     }
1678 
1679     // Allocate Statistics State Surface----------------------------------------
1680     // Width to be a aligned on 64 bytes and height is 1/4 the height
1681     // Per frame information written twice per frame for 2 slices
1682     // Surface to be a rectangle aligned with dwWidth to get proper dwSize
1683     // APG PAth need to make sure input surface width/height is what to processed width/Height
1684     uint32_t statistic_size = m_vpPlatformInterface.VeboxQueryStaticSurfaceSize();
1685     dwWidth = MOS_ALIGN_CEIL(inputSurface->osSurface->dwWidth, 64);
1686     dwHeight = MOS_ROUNDUP_DIVIDE(inputSurface->osSurface->dwHeight, 4) +
1687                MOS_ROUNDUP_DIVIDE(statistic_size * sizeof(uint32_t), dwWidth);
1688     dwSize = dwWidth * dwHeight;
1689 
1690     VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
1691         m_veboxStatisticsSurface,
1692         "VeboxStatisticsSurface",
1693         Format_Buffer,
1694         MOS_GFXRES_BUFFER,
1695         MOS_TILE_LINEAR,
1696         dwWidth,
1697         dwHeight,
1698         false,
1699         MOS_MMC_DISABLED,
1700         bAllocated,
1701         true,
1702         IsDeferredResourceDestroyNeeded(),
1703         MOS_HW_RESOURCE_USAGE_VP_INTERNAL_WRITE_FF,
1704         MOS_TILE_UNSET_GMM,
1705         memTypeHistStat,
1706         MOS_MEMPOOL_DEVICEMEMORY == memTypeHistStat));
1707 
1708     if (bAllocated)
1709     {
1710         if (MOS_MEMPOOL_DEVICEMEMORY != memTypeHistStat)
1711         {
1712             // Initialize veboxStatisticsSurface Surface
1713             VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.OsFillResource(
1714                 &(m_veboxStatisticsSurface->osSurface->OsResource),
1715                 dwSize,
1716                 InitValue));
1717             m_dwVeboxPerBlockStatisticsWidth  = dwWidth;
1718             m_dwVeboxPerBlockStatisticsHeight = MOS_ROUNDUP_DIVIDE(inputSurface->osSurface->dwHeight, 4);
1719         }
1720     }
1721 
1722     if (caps.bHDR3DLUT)
1723     {
1724         // HDR
1725         dwSize = Get3DLutSize();
1726         VP_PUBLIC_CHK_STATUS_RETURN(m_allocator.ReAllocateSurface(
1727             m_vebox3DLookUpTables,
1728             "Vebox3DLutTableSurface",
1729             Format_Buffer,
1730             MOS_GFXRES_BUFFER,
1731             MOS_TILE_LINEAR,
1732             dwSize,
1733             1,
1734             false,
1735             MOS_MMC_DISABLED,
1736             bAllocated,
1737             false,
1738             IsDeferredResourceDestroyNeeded()));
1739     }
1740     // cappipe
1741 
1742     return MOS_STATUS_SUCCESS;
1743 }
1744 
AssignSurface(VP_EXECUTE_CAPS caps,VEBOX_SURFACE_ID & surfaceId,SurfaceType surfaceType,VP_SURFACE * inputSurface,VP_SURFACE * outputSurface,VP_SURFACE * pastSurface,VP_SURFACE * futureSurface,VP_SURFACE_GROUP & surfGroup)1745 MOS_STATUS VpResourceManager::AssignSurface(VP_EXECUTE_CAPS caps, VEBOX_SURFACE_ID &surfaceId, SurfaceType surfaceType, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface, VP_SURFACE *pastSurface, VP_SURFACE *futureSurface, VP_SURFACE_GROUP &surfGroup)
1746 {
1747     VP_FUNC_CALL();
1748 
1749     switch (surfaceId)
1750     {
1751     case VEBOX_SURFACE_INPUT:
1752         if (nullptr == inputSurface)
1753         {
1754             VP_PUBLIC_ASSERTMESSAGE("inputSurface should not be nullptr when surfaceId being VEBOX_SURFACE_INPUT.");
1755             break;
1756         }
1757         surfGroup.insert(std::make_pair(surfaceType, inputSurface));
1758         break;
1759     case VEBOX_SURFACE_OUTPUT:
1760         if (nullptr == outputSurface)
1761         {
1762             VP_PUBLIC_ASSERTMESSAGE("outputSurface should not be nullptr when surfaceId being VEBOX_SURFACE_OUTPUT.");
1763             break;
1764         }
1765         surfGroup.insert(std::make_pair(surfaceType, outputSurface));
1766         break;
1767     case VEBOX_SURFACE_PAST_REF:
1768         if (caps.bDN && m_pastDnOutputValid)
1769         {
1770             surfGroup.insert(std::make_pair(surfaceType, m_veboxDenoiseOutput[(m_currentDnOutput + 1) & 1]));
1771         }
1772         else
1773         {
1774             auto curDnOutputSurface = m_veboxDenoiseOutput[m_currentDnOutput];
1775 
1776             if (nullptr == pastSurface)
1777             {
1778                 VP_PUBLIC_ASSERTMESSAGE("pastSurface should not be nullptr when surfaceId being VEBOX_SURFACE_PAST_REF.");
1779                 break;
1780             }
1781 
1782             if (!caps.bDN                               ||
1783                 nullptr == curDnOutputSurface           ||
1784                 // When FtrMediaTile64 is true, DN output surface will be tile64 when input is bayer format,
1785                 // while pastSurface passed by OS maybe tile4, which is different from DN output surface.
1786                 // For such case, passSurface cannot be used, as vebox previous input surface and vebox
1787                 // DN output surface must share same setting. The derive pitch in vebox output surface
1788                 // state is for both of them. Check pitch to handle it.
1789                 pastSurface->osSurface->dwPitch == curDnOutputSurface->osSurface->dwPitch)
1790             {
1791                 surfGroup.insert(std::make_pair(surfaceType, pastSurface));
1792             }
1793             else
1794             {
1795                 // DN case with m_pastDnOutputValid being false. pastSurface cannot be used here as pitch
1796                 // of pastSurface is different from current DN output surface.
1797                 VP_PUBLIC_NORMALMESSAGE("Do not use pastSurface. pastSurf (TileModeGmm: %d, pitch: %d) vs curDnOutputSurface (TileModeGmm: %d, pitch: %d)",
1798                     pastSurface->osSurface->TileModeGMM,
1799                     pastSurface->osSurface->dwPitch,
1800                     curDnOutputSurface->osSurface->TileModeGMM,
1801                     curDnOutputSurface->osSurface->dwPitch);
1802             }
1803         }
1804         break;
1805     case VEBOX_SURFACE_FUTURE_REF:
1806         if (nullptr == futureSurface)
1807         {
1808             VP_PUBLIC_ASSERTMESSAGE("futureSurface should not be nullptr when surfaceId being VEBOX_SURFACE_FUTURE_REF.");
1809             break;
1810         }
1811         surfGroup.insert(std::make_pair(surfaceType, futureSurface));
1812         break;
1813     case VEBOX_SURFACE_FRAME0:
1814         surfGroup.insert(std::make_pair(surfaceType, m_veboxOutput[(m_currentDnOutput + 0) % m_veboxOutputCount]));
1815         break;
1816     case VEBOX_SURFACE_FRAME1:
1817         surfGroup.insert(std::make_pair(surfaceType, m_veboxOutput[(m_currentDnOutput + 1) % m_veboxOutputCount]));
1818         break;
1819     case VEBOX_SURFACE_FRAME2:
1820         surfGroup.insert(std::make_pair(surfaceType, m_veboxOutput[(m_currentDnOutput + 2) % m_veboxOutputCount]));
1821         break;
1822     case VEBOX_SURFACE_FRAME3:
1823         surfGroup.insert(std::make_pair(surfaceType, m_veboxOutput[(m_currentDnOutput + 3) % m_veboxOutputCount]));
1824         break;
1825     default:
1826         break;
1827     }
1828     return MOS_STATUS_SUCCESS;
1829 }
1830 
AssignVeboxResource(VP_EXECUTE_CAPS & caps,VP_SURFACE * inputSurface,VP_SURFACE * outputSurface,VP_SURFACE * pastSurface,VP_SURFACE * futureSurface,RESOURCE_ASSIGNMENT_HINT resHint,VP_SURFACE_SETTING & surfSetting)1831 MOS_STATUS VpResourceManager::AssignVeboxResource(VP_EXECUTE_CAPS& caps, VP_SURFACE *inputSurface, VP_SURFACE *outputSurface,
1832     VP_SURFACE *pastSurface, VP_SURFACE *futureSurface, RESOURCE_ASSIGNMENT_HINT resHint, VP_SURFACE_SETTING &surfSetting)
1833 {
1834     VP_FUNC_CALL();
1835     VP_PUBLIC_CHK_NULL_RETURN(inputSurface);
1836     VP_PUBLIC_CHK_NULL_RETURN(inputSurface->osSurface);
1837     VP_PUBLIC_CHK_NULL_RETURN(outputSurface);
1838     VP_PUBLIC_CHK_NULL_RETURN(outputSurface->osSurface);
1839 
1840     MOS_FORMAT                      format;
1841     MOS_TILE_TYPE                   TileType;
1842     uint32_t                        dwWidth;
1843     uint32_t                        dwHeight;
1844     uint32_t                        dwSize;
1845     uint32_t                        i;
1846     auto&                           surfGroup = surfSetting.surfGroup;
1847 
1848     // Render case reuse vebox resource, and don`t need re-allocate.
1849     if (!caps.bRender ||
1850         (caps.bRender && caps.bDnKernelUpdate))
1851     {
1852         VP_PUBLIC_CHK_STATUS_RETURN(AllocateVeboxResource(caps, inputSurface, outputSurface));
1853     }
1854 
1855     if (caps.bDI || caps.bDiProcess2ndField)
1856     {
1857         bool b60fpsDi = resHint.b60fpsDi || caps.bDiProcess2ndField;
1858         VEBOX_SURFACES_CONFIG cfg(b60fpsDi, caps.bSFC, m_sameSamples, m_outOfBound, m_currentFrameIds.pastFrameAvailable,
1859             m_currentFrameIds.futureFrameAvailable, IsInterleaveFirstField(inputSurface->SampleType));
1860         auto it = m_veboxSurfaceConfigMap.find(cfg.value);
1861         if (m_veboxSurfaceConfigMap.end() == it)
1862         {
1863             VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
1864         }
1865         auto surfaces = it->second;
1866         VP_PUBLIC_CHK_STATUS_RETURN(AssignSurface(caps, surfaces.currentInputSurface, SurfaceTypeVeboxInput, inputSurface, outputSurface, pastSurface, futureSurface, surfSetting.surfGroup));
1867         VP_PUBLIC_CHK_STATUS_RETURN(AssignSurface(caps, surfaces.pastInputSurface, SurfaceTypeVeboxPreviousInput, inputSurface, outputSurface, pastSurface, futureSurface, surfSetting.surfGroup));
1868         VP_PUBLIC_CHK_STATUS_RETURN(AssignSurface(caps, surfaces.currentOutputSurface, SurfaceTypeVeboxCurrentOutput, inputSurface, outputSurface, pastSurface, futureSurface, surfSetting.surfGroup));
1869         VP_PUBLIC_CHK_STATUS_RETURN(AssignSurface(caps, surfaces.pastOutputSurface, SurfaceTypeVeboxPreviousOutput, inputSurface, outputSurface, pastSurface, futureSurface, surfSetting.surfGroup));
1870 
1871         if (caps.bDN)
1872         {
1873             // Insert DN output surface
1874             surfGroup.insert(std::make_pair(SurfaceTypeDNOutput, m_veboxDenoiseOutput[m_currentDnOutput]));
1875         }
1876 
1877         caps.bRefValid = surfGroup.find(SurfaceTypeVeboxPreviousInput) != surfGroup.end();
1878     }
1879     else
1880     {
1881         surfGroup.insert(std::make_pair(SurfaceTypeVeboxInput, inputSurface));
1882         surfGroup.insert(std::make_pair(SurfaceTypeVeboxCurrentOutput, GetVeboxOutputSurface(caps, outputSurface)));
1883 
1884         if (caps.bDN)
1885         {
1886             // Insert DN output surface
1887             surfGroup.insert(std::make_pair(SurfaceTypeDNOutput, m_veboxDenoiseOutput[m_currentDnOutput]));
1888             // Insert DN Reference surface
1889             if (caps.bRefValid)
1890             {
1891                 surfGroup.insert(std::make_pair(SurfaceTypeVeboxPreviousInput, m_veboxDenoiseOutput[(m_currentDnOutput + 1) & 1]));
1892             }
1893         }
1894     }
1895 
1896     if (VeboxSTMMNeeded(caps, true))
1897     {
1898         // Insert STMM input surface
1899         surfGroup.insert(std::make_pair(SurfaceTypeSTMMIn, m_veboxSTMMSurface[m_currentStmmIndex]));
1900         // Insert STMM output surface
1901         surfGroup.insert(std::make_pair(SurfaceTypeSTMMOut, m_veboxSTMMSurface[(m_currentStmmIndex + 1) & 1]));
1902     }
1903 
1904 #if VEBOX_AUTO_DENOISE_SUPPORTED
1905     // Insert Vebox auto DN noise level surface
1906     surfGroup.insert(std::make_pair(SurfaceTypeAutoDNNoiseLevel, m_veboxDNTempSurface));
1907     // Insert Vebox auto DN spatial config surface/buffer
1908     surfGroup.insert(std::make_pair(SurfaceTypeAutoDNSpatialConfig, m_veboxDNSpatialConfigSurface));
1909 #endif
1910 
1911     // Insert Vebox histogram surface
1912     surfGroup.insert(std::make_pair(SurfaceTypeLaceAceRGBHistogram, m_veboxRgbHistogram));
1913 
1914     // Insert Vebox statistics surface
1915     surfGroup.insert(std::make_pair(SurfaceTypeStatistics, m_veboxStatisticsSurface));
1916     surfSetting.dwVeboxPerBlockStatisticsHeight = m_dwVeboxPerBlockStatisticsHeight;
1917     surfSetting.dwVeboxPerBlockStatisticsWidth  = m_dwVeboxPerBlockStatisticsWidth;
1918 
1919     if (VeboxHdr3DlutNeeded(caps))
1920     {
1921         // Insert Vebox 3Dlut surface
1922         surfGroup.insert(std::make_pair(SurfaceType3dLut, m_vebox3DLookUpTables));
1923     }
1924 
1925     // Update previous Dn output flag for next frame to use.
1926     if (surfGroup.find(SurfaceTypeDNOutput) != surfGroup.end() || m_sameSamples && m_pastDnOutputValid)
1927     {
1928         m_pastDnOutputValid = true;
1929     }
1930     else
1931     {
1932         m_pastDnOutputValid = false;
1933     }
1934 
1935     return MOS_STATUS_SUCCESS;
1936 }
1937 
IsOutputSurfaceNeeded(VP_EXECUTE_CAPS caps)1938 bool VpResourceManager::IsOutputSurfaceNeeded(VP_EXECUTE_CAPS caps)
1939 {
1940     VP_FUNC_CALL();
1941 
1942     // check whether intermedia surface needed to create based on caps
1943     if (caps.bDnKernelUpdate ||  // State Heap as putput, but it was not tracked in resource manager yet
1944         caps.bVeboxSecureCopy)   // State Heap as putput, but it was not tracked in resource manager yet
1945     {
1946         return false;
1947     }
1948     else
1949     {
1950         return true;
1951     }
1952 }
1953 
GetVeboxOutputSurface(VP_EXECUTE_CAPS & caps,VP_SURFACE * outputSurface)1954 VP_SURFACE* VpResourceManager::GetVeboxOutputSurface(VP_EXECUTE_CAPS& caps, VP_SURFACE *outputSurface)
1955 {
1956     VP_FUNC_CALL();
1957 
1958     if (caps.bRender)
1959     {
1960         // Place Holder when enable DI
1961         return nullptr;
1962     }
1963 
1964     if (!caps.bSFC) // Vebox output directlly to output surface
1965     {
1966         // RenderTarget will be assigned in VpVeboxCmdPacket::GetSurface.
1967         return outputSurface;
1968     }
1969     else if (caps.bDI && caps.bVebox) // Vebox DI enable
1970     {
1971         // Place Holder when enable DI
1972         return nullptr;
1973     }
1974     else if (caps.bIECP) // SFC + IECP enabled, output to internal surface
1975     {
1976         return m_veboxOutput[m_currentDnOutput];
1977     }
1978     else if (caps.bDN) // SFC + DN case
1979     {
1980         // DN + SFC scenario needs IECP implicitly, which need vebox output surface being assigned.
1981         // Use m_currentDnOutput to ensure m_veboxOutput surface paired with DN output surface.
1982         return m_veboxOutput[m_currentDnOutput];
1983     }
1984     else
1985     {
1986         // Write to SFC cases, Vebox output is not needed.
1987         VP_PUBLIC_NORMALMESSAGE("No need output for Vebox output");
1988         return nullptr;
1989     }
1990 }
1991 
InitVeboxSpatialAttributesConfiguration()1992 MOS_STATUS VpResourceManager::InitVeboxSpatialAttributesConfiguration()
1993 {
1994     VP_FUNC_CALL();
1995 
1996     VP_PUBLIC_CHK_NULL_RETURN(m_veboxDNSpatialConfigSurface);
1997     VP_PUBLIC_CHK_NULL_RETURN(m_veboxDNSpatialConfigSurface->osSurface);
1998 
1999     uint8_t* data = (uint8_t*)& g_cInit_VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATIONS;
2000     return m_allocator.Write1DSurface(m_veboxDNSpatialConfigSurface, data,
2001         (uint32_t)sizeof(VEBOX_SPATIAL_ATTRIBUTES_CONFIGURATION));
2002 }
2003 
VeboxOutputNeeded(VP_EXECUTE_CAPS & caps)2004 bool VpResourceManager::VeboxOutputNeeded(VP_EXECUTE_CAPS& caps)
2005 {
2006     VP_FUNC_CALL();
2007 
2008     // If DN and/or Hotpixel are the only functions enabled then the only output is the Denoised Output
2009     // and no need vebox output.
2010     // For any other vebox features being enabled, vebox output surface is needed.
2011     if (caps.bDI                ||
2012         caps.bQueryVariance     ||
2013         caps.bDiProcess2ndField ||
2014         caps.bIECP              ||
2015         caps.bCappipe           ||
2016         (caps.bDN && caps.bSFC))  // DN + SFC needs IECP implicitly and outputs to DI surface
2017     {
2018         return true;
2019     }
2020     else
2021     {
2022         return false;
2023     }
2024 }
2025 
VeboxDenoiseOutputNeeded(VP_EXECUTE_CAPS & caps)2026 bool VpResourceManager::VeboxDenoiseOutputNeeded(VP_EXECUTE_CAPS& caps)
2027 {
2028     VP_FUNC_CALL();
2029 
2030     return caps.bDN;
2031 }
2032 
VeboxHdr3DlutNeeded(VP_EXECUTE_CAPS & caps)2033 bool VpResourceManager::VeboxHdr3DlutNeeded(VP_EXECUTE_CAPS &caps)
2034 {
2035     VP_FUNC_CALL();
2036 
2037     return caps.bHDR3DLUT;
2038 }
2039 
2040 // In some case, STMM should not be destroyed even when not being used by current workload to maintain data,
2041 // e.g. DI second field case.
2042 // If queryAssignment == true, query whether STMM needed by current workload.
2043 // If queryAssignment == false, query whether STMM needed to be allocated.
VeboxSTMMNeeded(VP_EXECUTE_CAPS & caps,bool queryAssignment)2044 bool VpResourceManager::VeboxSTMMNeeded(VP_EXECUTE_CAPS& caps, bool queryAssignment)
2045 {
2046     VP_FUNC_CALL();
2047 
2048     if (queryAssignment)
2049     {
2050         return caps.bDI || caps.bDN;
2051     }
2052     else
2053     {
2054         return caps.bDI || caps.bDiProcess2ndField || caps.bDN;
2055     }
2056 }
2057 
2058 };
2059