1 /*
2 * Copyright (c) 2016-2019, 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_composite.cpp
24 //! \brief    Composite related VPHAL functions
25 //! \details  Unified VP HAL Composite module including render initialization,
26 //!           resource allocation/free and rendering
27 //!
28 #include "vphal_render_composite.h"
29 #include "vphal_renderer.h"         // for VpHal_RenderAllocateBB
30 #include "vphal_render_common.h"    // for VPHAL_RENDER_CACHE_CNTL
31 #include "vphal_render_ief.h"
32 
33 // Compositing surface binding table index
34 #define VPHAL_COMP_BTINDEX_LAYER0          0
35 #define VPHAL_COMP_BTINDEX_LAYER0_FIELD0   0
36 #define VPHAL_COMP_BTINDEX_LAYER1          3
37 #define VPHAL_COMP_BTINDEX_LAYER2          6
38 #define VPHAL_COMP_BTINDEX_LAYER3          9
39 #define VPHAL_COMP_BTINDEX_LAYER4         12
40 #define VPHAL_COMP_BTINDEX_LAYER5         15
41 #define VPHAL_COMP_BTINDEX_LAYER6         18
42 #define VPHAL_COMP_BTINDEX_LAYER7         21
43 #define VPHAL_COMP_BTINDEX_RENDERTARGET   24
44 #define VPHAL_COMP_BTINDEX_RT_SECOND      27    // Pre-SKL
45 #define VPHAL_COMP_BTINDEX_L0_FIELD1_DUAL 48    // Pre-SKL
46 
47 #define VPHAL_HORIZONTAL_16X16BLOCK_MASK   0
48 #define VPHAL_VERTICAL_16X16BLOCK_MASK     1
49 
50 // CMFC macro
51 #define VPHAL_COMP_CMFC_COEFF_WIDTH        24
52 #define VPHAL_COMP_CMFC_COEFF_HEIGHT       8
53 #define VPHAL_COMP_BTINDEX_CSC_COEFF       34
54 
55 //!
56 //! \brief  Sampler State Indices
57 //!
58 #define VPHAL_SAMPLER_8x8_AVS_Y         4
59 #define VPHAL_SAMPLER_8x8_AVS_U         8
60 #define VPHAL_SAMPLER_8x8_AVS_V         12
61 
62 static const MEDIA_OBJECT_KA2_STATIC_DATA g_cInit_MEDIA_OBJECT_KA2_STATIC_DATA =
63 {
64     // DWORD 0
65     {
66         0,                                      // CscConstantC0
67         0                                       // CscConstantC1
68     },
69 
70     // DWORD 1
71     {
72         0,                                      // CscConstantC2
73         0                                       // CscConstantC3
74     },
75 
76     // DWORD 2
77     {
78         0,                                      // CscConstantC4
79         0                                       // CscConstantC5
80     },
81 
82     // DWORD 3
83     {
84         0,                                      // CscConstantC6
85         0                                       // CscConstantC7
86     },
87 
88     // DWORD 4
89     {
90         0,                                      // CscConstantC8
91         0                                       // CscConstantC9
92     },
93 
94     // DWORD 5
95     {
96         0,                                      // CscConstantC10
97         0                                       // CscConstantC11
98     },
99 
100     // DWORD 6
101     {
102         0,                                      // ConstantBlendingAlphaLayer1
103         0,                                      // ConstantBlendingAlphaLayer2
104         0,                                      // ConstantBlendingAlphaLayer3
105         0                                       // ConstantBlendingAlphaLayer4
106     },
107 
108     // DWORD 7
109     {
110         0,                                      // ConstantBlendingAlphaLayer5
111         0,                                      // ConstantBlendingAlphaLayer6
112         0,                                      // ConstantBlendingAlphaLayer7
113         7                                       // PointerToInlineParameters
114     },
115 
116     // DWORD 8
117     {
118         0,                                      // DestinationRectangleWidth
119         0                                       // DestinationRectangleHeight
120     },
121 
122     // DWORD 9
123     {
124         0,                                      // RotationMirrorMode
125         0,                                      // RotationMirrorAllLayer
126         0,                                      // DualOutputMode
127         0,                                      // ChannelSwap
128     },
129 
130     // DWORD 10
131     0,
132 
133     // DWORD 11
134     0,
135 
136     // DWORD 12
137     {
138         0,                                      // ColorProcessingEnable
139         0,                                      // MessageFormat
140         0                                       // ColorProcessingStatePointer
141     },
142 
143     // DWORD 13
144     {
145         0,                                      // ColorFill_R
146         0,                                      // ColorFill_G
147         0,                                      // ColorFill_B
148         0                                       // ColorFill_A
149     },
150 
151     // DWORD 14
152     {
153         0,                                      // LumakeyLowThreshold
154         0,                                      // LumakeyHighThreshold
155         0,                                      // NLASEnable
156     },
157 
158     // DWORD 15
159     {
160         0,                                      // DestinationPackedYOffset
161         0,                                      // DestinationPackedUOffset
162         0,                                      // DestinationPackedVOffset
163         0                                       // DestinationRGBFormat
164     },
165 
166     // DWORD 16
167     0,                                          // HorizontalScalingStepRatioLayer0
168 
169     // DWORD 17
170     0,                                          // HorizontalScalingStepRatioLayer1
171 
172     // DWORD 18
173     0,                                          // HorizontalScalingStepRatioLayer2
174 
175     // DWORD 19
176     0,                                          // HorizontalScalingStepRatioLayer3
177 
178     // DWORD 20
179     0,                                          // HorizontalScalingStepRatioLayer4
180 
181     // DWORD 21
182     0,                                          // HorizontalScalingStepRatioLayer5
183 
184     // DWORD 22
185     0,                                          // HorizontalScalingStepRatioLayer6
186 
187     // DWORD 23
188     0,                                          // HorizontalScalingStepRatioLayer7
189 
190     // DWORD 24
191     0,                                          // VerticalScalingStepRatioLayer0
192 
193     // DWORD 25
194     0,                                          // VerticalScalingStepRatioLayer1
195 
196     // DWORD 26
197     0,                                          // VerticalScalingStepRatioLayer2
198 
199     // DWORD 27
200     0,                                          // VerticalScalingStepRatioLayer3
201 
202     // DWORD 28
203     0,                                          // VerticalScalingStepRatioLayer4
204 
205     // DWORD 29
206     0,                                          // VerticalScalingStepRatioLayer5
207 
208     // DWORD 30
209     0,                                          // VerticalScalingStepRatioLayer6
210 
211     // DWORD 31
212     0,                                          // VerticalScalingStepRatioLayer7
213 
214     // DWORD 32
215     0,                                          // VerticalFrameOriginLayer0
216 
217     // DWORD 33
218     0,                                          // VerticalFrameOriginLayer1
219 
220     // DWORD 34
221     0,                                          // VerticalFrameOriginLayer2
222 
223     // DWORD 35
224     0,                                          // VerticalFrameOriginLayer3
225 
226     // DWORD 36
227     0,                                          // VerticalFrameOriginLayer4
228 
229     // DWORD 37
230     0,                                          // VerticalFrameOriginLayer5
231 
232     // DWORD 38
233     0,                                          // VerticalFrameOriginLayer6
234 
235     // DWORD 39
236     0,                                          // VerticalFrameOriginLayer7
237 
238     // DWORD 40
239     0,                                          // HorizontalFrameOriginLayer0
240 
241     // DWORD 41
242     0,                                          // HorizontalFrameOriginLayer1
243 
244     // DWORD 42
245     0,                                          // HorizontalFrameOriginLayer2
246 
247     // DWORD 43
248     0,                                          // HorizontalFrameOriginLayer3
249 
250     // DWORD 44
251     0,                                          // HorizontalFrameOriginLayer4
252 
253     // DWORD 45
254     0,                                          // HorizontalFrameOriginLayer5
255 
256     // DWORD 46
257     0,                                          // HorizontalFrameOriginLayer6
258 
259     // DWORD 47
260     0                                           // HorizontalFrameOriginLayer7
261 };
262 
263 static const MEDIA_WALKER_KA2_STATIC_DATA g_cInit_MEDIA_WALKER_KA2_STATIC_DATA =
264 {
265     // DWORD 0
266     {
267         0,                                      // CscConstantC0
268         0                                       // CscConstantC1
269     },
270 
271     // DWORD 1
272     {
273         0,                                      // CscConstantC2
274         0                                       // CscConstantC3
275     },
276 
277     // DWORD 2
278     {
279         0,                                      // CscConstantC4
280         0                                       // CscConstantC5
281     },
282 
283     // DWORD 3
284     {
285         0,                                      // CscConstantC6
286         0                                       // CscConstantC7
287     },
288 
289     // DWORD 4
290     {
291         0,                                      // CscConstantC8
292         0                                       // CscConstantC9
293     },
294 
295     // DWORD 5
296     {
297         0,                                      // CscConstantC10
298         0                                       // CscConstantC11
299     },
300 
301     // DWORD 6
302     {
303         0,                                      // ConstantBlendingAlphaLayer1
304         0,                                      // ConstantBlendingAlphaLayer2
305         0,                                      // ConstantBlendingAlphaLayer3
306         0                                       // ConstantBlendingAlphaLayer4
307     },
308 
309     // DWORD 7
310     {
311         0,                                      // ConstantBlendingAlphaLayer5
312         0,                                      // ConstantBlendingAlphaLayer6
313         0,                                      // ConstantBlendingAlphaLayer7
314         7                                       // PointerToInlineParameters
315     },
316 
317     // DWORD 8
318     {
319         0,                                      // DestinationRectangleWidth
320         0                                       // DestinationRectangleHeight
321     },
322 
323     // DWORD 9
324     {
325         0,                                      // RotationMirrorMode
326         0,                                      // RotationMirrorAllLayer
327         0,                                      // DualOutputMode
328         0,                                      // ChannelSwap
329     },
330 
331     // DWORD 10
332     0,
333 
334     // DWORD 11
335     0,
336 
337     // DWORD 12
338     {
339         0,                                      // ColorProcessingEnable
340         0,                                      // MessageFormat
341         0                                       // ColorProcessingStatePointer
342     },
343 
344     // DWORD 13
345     {
346         0,                                      // ColorFill_R
347         0,                                      // ColorFill_G
348         0,                                      // ColorFill_B
349         0                                       // ColorFill_A
350     },
351 
352     // DWORD 14
353     {
354         0,                                      // LumakeyLowThreshold
355         0,                                      // LumakeyHighThreshold
356         0,                                  // NLASEnable
357     },
358 
359     // DWORD 15
360     {
361         0,                                      // DestinationPackedYOffset
362         0,                                      // DestinationPackedUOffset
363         0,                                      // DestinationPackedVOffset
364         0                                       // DestinationRGBFormat
365     },
366 
367     // DWORD 16
368     0,                                          // HorizontalScalingStepRatioLayer0
369 
370     // DWORD 17
371     0,                                          // HorizontalScalingStepRatioLayer1
372 
373     // DWORD 18
374     0,                                          // HorizontalScalingStepRatioLayer2
375 
376     // DWORD 19
377     0,                                          // HorizontalScalingStepRatioLayer3
378 
379     // DWORD 20
380     0,                                          // HorizontalScalingStepRatioLayer4
381 
382     // DWORD 21
383     0,                                          // HorizontalScalingStepRatioLayer5
384 
385     // DWORD 22
386     0,                                          // HorizontalScalingStepRatioLayer6
387 
388     // DWORD 23
389     0,                                          // HorizontalScalingStepRatioLayer7
390 
391     // DWORD 24
392     0,                                          // VerticalScalingStepRatioLayer0
393 
394     // DWORD 25
395     0,                                          // VerticalScalingStepRatioLayer1
396 
397     // DWORD 26
398     0,                                          // VerticalScalingStepRatioLayer2
399 
400     // DWORD 27
401     0,                                          // VerticalScalingStepRatioLayer3
402 
403     // DWORD 28
404     0,                                          // VerticalScalingStepRatioLayer4
405 
406     // DWORD 29
407     0,                                          // VerticalScalingStepRatioLayer5
408 
409     // DWORD 30
410     0,                                          // VerticalScalingStepRatioLayer6
411 
412     // DWORD 31
413     0,                                          // VerticalScalingStepRatioLayer7
414 
415     // DWORD 32
416     0,                                          // VerticalFrameOriginLayer0
417 
418     // DWORD 33
419     0,                                          // VerticalFrameOriginLayer1
420 
421     // DWORD 34
422     0,                                          // VerticalFrameOriginLayer2
423 
424     // DWORD 35
425     0,                                          // VerticalFrameOriginLayer3
426 
427     // DWORD 36
428     0,                                          // VerticalFrameOriginLayer4
429 
430     // DWORD 37
431     0,                                          // VerticalFrameOriginLayer5
432 
433     // DWORD 38
434     0,                                          // VerticalFrameOriginLayer6
435 
436     // DWORD 39
437     0,                                          // VerticalFrameOriginLayer7
438 
439     // DWORD 40
440     0,                                          // HorizontalFrameOriginLayer0
441 
442     // DWORD 41
443     0,                                          // HorizontalFrameOriginLayer1
444 
445     // DWORD 42
446     0,                                          // HorizontalFrameOriginLayer2
447 
448     // DWORD 43
449     0,                                          // HorizontalFrameOriginLayer3
450 
451     // DWORD 44
452     0,                                          // HorizontalFrameOriginLayer4
453 
454     // DWORD 45
455     0,                                          // HorizontalFrameOriginLayer5
456 
457     // DWORD 46
458     0,                                          // HorizontalFrameOriginLayer6
459 
460     // DWORD 47
461     0,                                          // HorizontalFrameOriginLayer7
462 
463     // DWORD 48
464 
465     {
466        0,                                       //  DestXTopLeftLayer0
467        0                                        //  DestYTopLeftLayer0
468     },
469 
470    // DWORD 49
471    {
472        0,                                      //  DestXTopLeftLayer1
473        0                                       //  DestYTopLeftLayer1
474    },
475 
476    // DWORD 50
477    {
478        0,                                      //  DestXTopLeftLayer2
479        0                                       //  DestYTopLeftLayer2
480    },
481 
482    // DWORD 51
483    {
484        0,                                      //  DestXTopLeftLayer3
485        0                                       //  DestYTopLeftLayer3
486    },
487 
488    // DWORD 52
489    {
490        0,                                      //  DestXTopLeftLayer4
491        0                                       //  DestYTopLeftLayer4
492    },
493 
494    // DWORD 53
495    {
496        0,                                      //  DestXTopLeftLayer5
497        0                                       //  DestYTopLeftLayer5
498    },
499 
500    // DWORD 54
501    {
502        0,                                      //  DestXTopLeftLayer6
503        0                                       //  DestYTopLeftLayer6
504    },
505 
506    // DWORD 55
507    {
508        0,                                      //  DestXTopLeftLayer7
509        0                                       //  DestYTopLeftLayer7
510    },
511 
512    // DWORD 56
513    {
514        0,                                      // DestXBottomRightLayer0
515        0                                       // DestYBottomRightLayer0
516    },
517 
518    // DWORD 57
519    {
520        0,                                      // DestXBottomRightLayer1
521        0                                       // DestYBottomRightLayer1
522    },
523 
524    // DWORD 58
525    {
526        0,                                      // DestXBottomRightLayer2
527        0                                       // DestYBottomRightLayer2
528    },
529 
530    // DWORD 59
531    {
532        0,                                      // DestXBottomRightLayer3
533        0                                       // DestYBottomRightLayer3
534    },
535 
536    // DWORD 60
537    {
538        0,                                      // DestXBottomRightLayer4
539        0                                       // DestYBottomRightLayer4
540    },
541 
542    // DWORD 61
543    {
544        0,                                      // DestXBottomRightLayer5
545        0                                       // DestYBottomRightLayer5
546    },
547 
548    // DWORD 62
549    {
550        0,                                     // DestXBottomRightLayer6
551        0                                      // DestYBottomRightLayer6
552    },
553 
554    // DWORD 63
555    {
556        0,                                     // DestXBottomRightLayer7
557        0                                      // DestYBottomRightLayer7
558    },
559 
560    // DWORD 64
561    0,                                         // MainVideoXScalingStepLeft
562 
563    // DWORD 65
564    0,                                         // VideoStepDeltaForNonLinearRegion
565 
566    // DWORD 66
567    {
568        0,                                     // StartofLinearScalingInPixelPositionC0
569        0                                      // StartofRHSNonLinearScalingInPixelPositionC1
570    },
571 
572    // DWORD 67
573    0,                                         // MainVideoXScalingStepCenter
574 
575    // DWORD 68
576    0,                                         // MainVideoXScalingStepRight
577 
578    // DWORD 69
579    {
580        0,                                     // DestHorizontalBlockOrigin
581        0                                      // DestVerticalBlockOrigin
582    },
583 
584    // DWORD 70 - DWORD 71
585    {0,0}
586 };
587 
588 static const MEDIA_OBJECT_NLAS_INLINE_DATA g_cInit_MEDIA_OBJECT_NLAS_INLINE_DATA =
589 {
590     0,                                          // HorizontalFrameOriginLayer0
591     0,                                          // HorizontalFrameOriginLayer1
592     0,                                          // HorizontalFrameOriginLayer2
593     0,                                          // HorizontalFrameOriginLayer3
594     0,                                          // HorizontalFrameOriginLayer4
595     0,                                          // HorizontalFrameOriginLayer5
596     0,                                          // HorizontalFrameOriginLayer6
597     0                                           // HorizontalFrameOriginLayer7
598 };
599 
600 const Kdll_Layer g_cSurfaceType_Layer[] =
601 {
602     Layer_None        ,    //!< SURF_NONE
603     Layer_Background  ,    //!< SURF_IN_BACKGROUND
604     Layer_MainVideo   ,    //!< SURF_IN_PRIMARY
605     Layer_SubVideo    ,    //!< SURF_IN_SECONDARY
606     Layer_SubPicture1 ,    //!< SURF_IN_SUBSTREAM
607     Layer_Graphics    ,    //!< SURF_IN_GRAPHICS
608     Layer_Invalid     ,    //!< SURF_IN_REFERENCE
609     Layer_RenderTarget     //!< SURF_OUT_RENDERTARGET
610 };
611 
612 const int32_t g_cBindingTableIndex[] =
613 {
614     VPHAL_COMP_BTINDEX_RENDERTARGET,
615     VPHAL_COMP_BTINDEX_LAYER0,
616     VPHAL_COMP_BTINDEX_LAYER1,
617     VPHAL_COMP_BTINDEX_LAYER2,
618     VPHAL_COMP_BTINDEX_LAYER3,
619     VPHAL_COMP_BTINDEX_LAYER4,
620     VPHAL_COMP_BTINDEX_LAYER5,
621     VPHAL_COMP_BTINDEX_LAYER6,
622     VPHAL_COMP_BTINDEX_LAYER7
623 };
624 
625 const RENDERHAL_KERNEL_PARAM g_cInitKernelParamsComposite =
626 {
627     7,                              //!< Number of registers (7 => 128 registers)
628     40,                             //!< Number of BT entries
629     3,                              //!< Number of samplers (3 => 9-12 samplers)
630     VPHAL_USE_MEDIA_THREADS_MAX,    //!< Number of threads
631     0,                              //!< Start register
632     6,                              //!< Constant URB length (in 256-bits) (6 => 48 dwords)
633     VPHAL_COMP_BLOCK_WIDTH,         //!< Block width
634     VPHAL_COMP_BLOCK_HEIGHT,        //!< Block height
635     1,                              //!< Blocks in x
636     1                               //!< Blocks in y
637 };
638 
639 //!
640 //! \brief    Reverse bits in a word
641 //! \details  Convert a post-rotated 16x16 block mask to a pre-rotated one
642 //! \param    [in] x
643 //!           16x16 block mask
644 //! \return   uint16_t
645 //!           Return bit-reversed word
646 //!
ReverseWord(uint16_t x)647 static uint16_t ReverseWord(uint16_t x)
648 {
649     x = (((x & 0xaaaa) >> 1) | ((x & 0x5555) << 1));
650     x = (((x & 0xcccc) >> 2) | ((x & 0x3333) << 2));
651     x = (((x & 0xf0f0) >> 4) | ((x & 0x0f0f) << 4));
652     return ((x >> 8) | (x << 8));
653 }
654 
655 //!
656 //! \brief    Judge whether Bob Di should be enabled
657 //! \details  Judge whether Bob Di should be enabled according to the parameter
658 //!           of pDeinterlaceParams and the height of the input surface
659 //! \param    [in] pSrc
660 //!           Pointer to Source Surface
661 //! \return   bool
662 //!           Return true if Bob DI should be enabled, otherwise false
663 //!
IsBobDiEnabled(PVPHAL_SURFACE pSrc)664 bool CompositeState::IsBobDiEnabled(PVPHAL_SURFACE pSrc)
665 {
666     bool  bRet = false;
667 
668     VPHAL_RENDER_CHK_NULL_NO_STATUS(m_pOsInterface);
669 
670     // Kernel don't support inderlaced Y410/Y210 as input format
671     bRet = (pSrc->pDeinterlaceParams     &&
672            (pSrc->Format != Format_Y410  &&
673             pSrc->Format != Format_Y210  &&
674             pSrc->Format != Format_Y216  &&
675             pSrc->Format != Format_Y416) &&
676             !VpHal_RndrCommonIsAlignmentWANeeded(pSrc, m_pOsInterface->CurrentGpuContextOrdinal));
677 
678 finish:
679     return bRet;
680 }
681 
682 //!
683 //! \brief    Judge whether 8-tap adaptive filter for all channels should be enabled
684 //! \details  Judge whether 8-tap adaptive filter for all channels should be enabled according to the input parameter
685 //! \param    [in] pSrc
686 //!           Pointer to Source Surface
687 //! \param    [in] fScaleX
688 //!           width scaling ratio
689 //! \param    [in] fScaleY
690 //!           height scaling ratio
691 //! \return   bool
692 //!           Return true 8-tap adaptive filter for all channels should be enabled, otherwise false
693 //!
Is8TapAdaptiveEnabled(PVPHAL_SURFACE pSrc,float fScaleX,float fScaleY)694 bool CompositeState::Is8TapAdaptiveEnabled(
695     PVPHAL_SURFACE          pSrc,
696     float                   fScaleX,
697     float                   fScaleY)
698 {
699     return (m_b8TapAdaptiveEnable       &&
700             (fScaleX > 1.0F || fScaleY > 1.0F)    &&
701             (IS_RGB32_FORMAT(pSrc->Format)        ||
702              pSrc->Format == Format_A16R16G16B16  ||
703              pSrc->Format == Format_AYUV          ||
704              pSrc->Format == Format_Y410          ||
705              pSrc->Format == Format_Y416));
706 }
707 
708 //!
709 //! \brief    Set 16x16 block inline mask based on the rotation
710 //! \details  Set 16x16 block inline mask with a pre-rotated 16x16 MB based on a
711 //!           post-rotated 16x16 block mask
712 //! \param    [in] rotation
713 //!           Rotation Degrees
714 //! \param    [out] pInlineDword
715 //!           Pointer to HW Interface
716 //! \param    [in] wMask
717 //!           Inline Mask
718 //! \param    [in] maskDirection
719 //!           Mask Direction
720 //! \return   void
721 //!
SetInline16x16Mask(VPHAL_ROTATION rotation,PVPHAL_16X16BLOCK_COMPOSITE_MASK pInlineDword,uint16_t wMask,uint32_t maskDirection)722 static void SetInline16x16Mask(
723     VPHAL_ROTATION                      rotation,
724     PVPHAL_16X16BLOCK_COMPOSITE_MASK    pInlineDword,
725     uint16_t                            wMask,
726     uint32_t                            maskDirection)
727 {
728     if (VPHAL_VERTICAL_16X16BLOCK_MASK == maskDirection)
729     {
730         switch (rotation)
731         {
732             case VPHAL_ROTATION_IDENTITY:
733             case VPHAL_MIRROR_HORIZONTAL:
734                 pInlineDword->VerticalBlockCompositeMask = wMask;
735                 break;
736             case VPHAL_ROTATION_90:
737             case VPHAL_ROTATE_90_MIRROR_HORIZONTAL:
738                 // swap vertical/horizontal
739                 pInlineDword->HorizontalBlockCompositeMask = wMask;
740                 break;
741             case VPHAL_ROTATION_180:
742             case VPHAL_MIRROR_VERTICAL:
743                 // reverse bits
744                 pInlineDword->VerticalBlockCompositeMask = ReverseWord(wMask);
745                 break;
746             case VPHAL_ROTATION_270:
747             case VPHAL_ROTATE_90_MIRROR_VERTICAL:
748                 // reverse bits and swap vertical/horizontal
749                 pInlineDword->HorizontalBlockCompositeMask = ReverseWord(wMask);
750                 break;
751             default:
752                 VPHAL_RENDER_ASSERTMESSAGE("Invalid Rotation Angle.");
753                 break;
754         }
755     }
756     else    // must be VPHAL_HORIZONTAL_16X16BLOCK_MASK
757     {
758         switch (rotation)
759         {
760             case VPHAL_ROTATION_IDENTITY:
761             case VPHAL_MIRROR_VERTICAL:
762                 pInlineDword->HorizontalBlockCompositeMask = wMask;
763                 break;
764             case VPHAL_ROTATION_90:
765             case VPHAL_ROTATE_90_MIRROR_VERTICAL:
766                 // reverse bits and swap vertical/horizontal
767                 pInlineDword->VerticalBlockCompositeMask = ReverseWord(wMask);
768                 break;
769             case VPHAL_ROTATION_180:
770             case VPHAL_MIRROR_HORIZONTAL:
771                 // reverse bits
772                 pInlineDword->HorizontalBlockCompositeMask = ReverseWord(wMask);
773                 break;
774             case VPHAL_ROTATION_270:
775             case VPHAL_ROTATE_90_MIRROR_HORIZONTAL:
776                 // swap vertical/horizontal
777                 pInlineDword->VerticalBlockCompositeMask = wMask;
778                 break;
779             default:
780                 VPHAL_RENDER_ASSERTMESSAGE("Invalid Rotation Angle.");
781                 break;
782         }
783     }
784 }
785 
786 //!
787 //! \brief    Load Palette Data
788 //! \details  Load Palette Data according to color space and CSC matrix.
789 //! \param    [in] pInPalette
790 //!           Pointer to Input Palette structure
791 //! \param    [in] srcCspace
792 //!           Source color space
793 //! \param    [in] dstCspace
794 //!           Destination color space
795 //! \param    [in] piCscMatrix
796 //!           Pointer to CSC matrix to use in fixed point format
797 //! \param    [in] iNumEntries
798 //!           Number of Palette entries to be filled
799 //! \param    [in,out] pPaletteData
800 //!           Pointer to Output Palette Address
801 //! \return   MOS_STATUS
802 //!           MOS_STATUS_SUCCESS, otherwise MOS_STATUS_UNIMPLEMENTED if Destination Colorspace not supported,
803 //!            or MOS_STATUS_INVALID_PARAMETER/MOS_STATUS_NULL_POINTER
804 //!
LoadPaletteData(PVPHAL_PALETTE pInPalette,VPHAL_CSPACE srcCspace,VPHAL_CSPACE dstCspace,int32_t * piCscMatrix,int32_t iNumEntries,void * pPaletteData)805 MOS_STATUS CompositeState::LoadPaletteData(
806     PVPHAL_PALETTE          pInPalette,
807     VPHAL_CSPACE            srcCspace,
808     VPHAL_CSPACE            dstCspace,
809     int32_t*                piCscMatrix,
810     int32_t                 iNumEntries,
811     void*                   pPaletteData)
812 {
813     PVPHAL_COLOR_SAMPLE_8   pSrcColor, pDstColor;
814     bool                    bHasAlpha;
815     int32_t                 R, G, B;
816     int32_t                 Y, U, V;
817     int32_t                 i;
818     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
819 
820     VPHAL_RENDER_CHK_NULL(pInPalette);
821     VPHAL_RENDER_CHK_NULL(pInPalette->pPalette8);
822     VPHAL_RENDER_CHK_NULL(piCscMatrix);
823     VPHAL_RENDER_CHK_NULL(pPaletteData);
824 
825     if (pInPalette->iNumEntries < 1)
826     {
827         VPHAL_RENDER_ASSERTMESSAGE("invalid parameters.");
828         eStatus = MOS_STATUS_INVALID_PARAMETER;
829         goto finish;
830     }
831 
832     bHasAlpha = pInPalette->bHasAlpha;
833 
834     // Obtain pointer to in/out color entries
835     pSrcColor   = pInPalette->pPalette8;
836     pDstColor   = (PVPHAL_COLOR_SAMPLE_8)pPaletteData;
837 
838     // Load Palette by performing the required conversions
839     if (srcCspace == dstCspace)
840     {
841         // No conversion needed
842         if ((dstCspace == CSpace_sRGB) || (dstCspace == CSpace_stRGB))
843         {
844             for (i = 0; i < iNumEntries; i++, pSrcColor++, pDstColor++)
845             {
846                 pDstColor->A = (bHasAlpha) ? pSrcColor->A : 255;
847                 pDstColor->R = pSrcColor->R;
848                 pDstColor->G = pSrcColor->G;
849                 pDstColor->B = pSrcColor->B;
850             }
851         }
852         else
853         {
854             for (i = 0; i < iNumEntries; i++, pSrcColor++, pDstColor++)
855             {
856                 pDstColor->a = (bHasAlpha) ? pSrcColor->Alpha : 255;
857                 pDstColor->V = pSrcColor->Cr;
858                 pDstColor->Y = pSrcColor->YY;
859                 pDstColor->U = pSrcColor->Cb;
860             }
861         }
862     }
863     else
864     {
865         // Conversion needed
866         switch (dstCspace)
867         {
868             case CSpace_sRGB:
869             case CSpace_stRGB:
870                 for (i = 0; i < iNumEntries; i++, pSrcColor++, pDstColor++)
871                 {
872                     // YUV to RGB conversions
873                     Y = pSrcColor->YY;
874                     U = pSrcColor->Cb;
875                     V = pSrcColor->Cr;
876 
877                     R = (Y * piCscMatrix[0]  + U * piCscMatrix[1]  +
878                          V * piCscMatrix[2]  +     piCscMatrix[3]  + 0x00080000) >> 20;
879                     G = (Y * piCscMatrix[4]  + U * piCscMatrix[5]  +
880                          V * piCscMatrix[6]  +     piCscMatrix[7]  + 0x00080000) >> 20;
881                     B = (Y * piCscMatrix[8]  + U * piCscMatrix[9]  +
882                          V * piCscMatrix[10] +     piCscMatrix[11] + 0x00080000) >> 20;
883 
884                     pDstColor->A = (bHasAlpha) ? pSrcColor->Alpha : 255;
885                     if (dstCspace == CSpace_sRGB)
886                     {
887                         pDstColor->R = MOS_MIN(MOS_MAX(0,R),255);
888                         pDstColor->G = MOS_MIN(MOS_MAX(0,G),255);
889                         pDstColor->B = MOS_MIN(MOS_MAX(0,B),255);
890                     }
891                     else
892                     {
893                         pDstColor->R = MOS_MIN(MOS_MAX(16,R),235);
894                         pDstColor->G = MOS_MIN(MOS_MAX(16,G),235);
895                         pDstColor->B = MOS_MIN(MOS_MAX(16,B),235);
896                     }
897                 }
898                 break;
899 
900             case CSpace_BT601:
901             case CSpace_BT709:
902             case CSpace_xvYCC601:
903             case CSpace_xvYCC709:
904             case CSpace_BT601_FullRange:
905             case CSpace_BT709_FullRange:
906                 for (i = 0; i < iNumEntries; i++, pSrcColor++, pDstColor++)
907                 {
908                     R = pSrcColor->R;
909                     G = pSrcColor->G;
910                     B = pSrcColor->B;
911 
912                     Y = (piCscMatrix[0]  * R + piCscMatrix[1]  * G +
913                          piCscMatrix[2]  * B + piCscMatrix[3]      + 0x00080000) >> 20;
914                     U = (piCscMatrix[4]  * R + piCscMatrix[5]  * G +
915                          piCscMatrix[6]  * B + piCscMatrix[7]      + 0x00080000) >> 20;
916                     V = (piCscMatrix[8]  * R + piCscMatrix[9]  * G +
917                          piCscMatrix[10] * B + piCscMatrix[11]     + 0x00080000) >> 20;
918 
919                     pDstColor->a = (bHasAlpha) ? pSrcColor->Alpha : 255;
920                     if ((dstCspace == CSpace_BT601) ||
921                         (dstCspace == CSpace_BT709))
922                     {
923                         pDstColor->V = MOS_MIN(MOS_MAX(16,V),240);
924                         pDstColor->Y = MOS_MIN(MOS_MAX(16,Y),235);
925                         pDstColor->U = MOS_MIN(MOS_MAX(16,U),240);
926                     }
927                     else
928                     {
929                         pDstColor->V = MOS_MIN(MOS_MAX(0,V),255);
930                         pDstColor->Y = MOS_MIN(MOS_MAX(0,Y),255);
931                         pDstColor->U = MOS_MIN(MOS_MAX(0,U),255);
932                     }
933                 }
934                 break;
935 
936             default:
937                 VPHAL_RENDER_ASSERTMESSAGE("Destination Colorspace not supported.");
938                 eStatus = MOS_STATUS_UNIMPLEMENTED;
939                 break;
940         }
941     }
942 
943 finish:
944     return eStatus;
945 }
946 
947 //!
948 //! \brief    Recalculate Sampler Avs 8x8 Horizontal/Vertical scaling table
949 //! \param    [in] SrcFormat
950 //!           Source Format
951 //! \param    [in] fScale
952 //!           Horizontal or Vertical Scale Factor
953 //! \param    [in] bVertical
954 //!           true if Vertical Scaling, else Horizontal Scaling
955 //! \param    [in] dwChromaSiting
956 //!           Chroma Siting
957 //! \param    [in] bBalancedFilter
958 //!           true if Gen9+, balanced filter
959 //! \param    [in] b8TapAdaptiveEnable
960 //!           true if 8Tap Adaptive Enable
961 //! \param    [in,out] pAvsParams
962 //!           Pointer to AVS Params
963 //! \return   MOS_STATUS
964 //!
SamplerAvsCalcScalingTable(MOS_FORMAT SrcFormat,float fScale,bool bVertical,uint32_t dwChromaSiting,bool bBalancedFilter,bool b8TapAdaptiveEnable,PMHW_AVS_PARAMS pAvsParams)965 static MOS_STATUS SamplerAvsCalcScalingTable(
966     MOS_FORMAT                      SrcFormat,
967     float                           fScale,
968     bool                            bVertical,
969     uint32_t                        dwChromaSiting,
970     bool                            bBalancedFilter,
971     bool                            b8TapAdaptiveEnable,
972     PMHW_AVS_PARAMS                 pAvsParams)
973 {
974     MOS_STATUS                      eStatus = MOS_STATUS_SUCCESS;
975     MHW_PLANE                       Plane;
976     int32_t                         iUvPhaseOffset;
977     uint32_t                        dwHwPhrase;
978     uint32_t                        YCoefTableSize;
979     uint32_t                        UVCoefTableSize;
980     float                           fScaleParam;
981     int32_t*                        piYCoefsParam;
982     int32_t*                        piUVCoefsParam;
983     float                           fHPStrength;
984 
985     VPHAL_RENDER_CHK_NULL(pAvsParams);
986     VPHAL_RENDER_CHK_NULL(pAvsParams->piYCoefsY);
987     VPHAL_RENDER_CHK_NULL(pAvsParams->piYCoefsX);
988     VPHAL_RENDER_CHK_NULL(pAvsParams->piUVCoefsY);
989     VPHAL_RENDER_CHK_NULL(pAvsParams->piUVCoefsX);
990 
991     if (bBalancedFilter)
992     {
993         YCoefTableSize      = POLYPHASE_Y_COEFFICIENT_TABLE_SIZE_G9;
994         UVCoefTableSize     = POLYPHASE_UV_COEFFICIENT_TABLE_SIZE_G9;
995         dwHwPhrase          = NUM_HW_POLYPHASE_TABLES_G9;
996     }
997     else
998     {
999         YCoefTableSize      = POLYPHASE_Y_COEFFICIENT_TABLE_SIZE_G8;
1000         UVCoefTableSize     = POLYPHASE_UV_COEFFICIENT_TABLE_SIZE_G8;
1001         dwHwPhrase          = MHW_NUM_HW_POLYPHASE_TABLES;
1002     }
1003 
1004     fHPStrength = 0.0F;
1005     piYCoefsParam   = bVertical ? pAvsParams->piYCoefsY : pAvsParams->piYCoefsX;
1006     piUVCoefsParam  = bVertical ? pAvsParams->piUVCoefsY : pAvsParams->piUVCoefsX;
1007     fScaleParam     = bVertical ? pAvsParams->fScaleY : pAvsParams->fScaleX;
1008 
1009     // Recalculate Horizontal or Vertical scaling table
1010     if (SrcFormat != pAvsParams->Format || fScale != fScaleParam)
1011     {
1012         MOS_ZeroMemory(piYCoefsParam, YCoefTableSize);
1013         MOS_ZeroMemory(piUVCoefsParam, UVCoefTableSize);
1014 
1015         // 4-tap filtering for RGB format G-channel if 8tap adaptive filter is not enabled.
1016         Plane = ((IS_RGB32_FORMAT(SrcFormat) || (SrcFormat == Format_Y410) || (SrcFormat == Format_AYUV) || (SrcFormat == Format_Y416)) && !b8TapAdaptiveEnable) ? MHW_U_PLANE : MHW_Y_PLANE;
1017         if (bVertical)
1018         {
1019             pAvsParams->fScaleY = fScale;
1020         }
1021         else
1022         {
1023             pAvsParams->fScaleX = fScale;
1024         }
1025 
1026         // For 1x scaling in horizontal direction, use special coefficients for filtering
1027         // we don't do this when bForcePolyPhaseCoefs flag is set
1028         if (fScale == 1.0F && !pAvsParams->bForcePolyPhaseCoefs)
1029         {
1030             VPHAL_RENDER_CHK_STATUS(Mhw_SetNearestModeTable(
1031                 piYCoefsParam,
1032                 Plane,
1033                 bBalancedFilter));
1034             // If the 8-tap adaptive is enabled for all channel, then UV/RB use the same coefficient as Y/G
1035             // So, coefficient for UV/RB channels caculation can be passed
1036             if (!b8TapAdaptiveEnable)
1037             {
1038                 VPHAL_RENDER_CHK_STATUS(Mhw_SetNearestModeTable(
1039                     piUVCoefsParam,
1040                     MHW_U_PLANE,
1041                     bBalancedFilter));
1042             }
1043         }
1044         else
1045         {
1046             // Clamp the Scaling Factor if > 1.0x
1047             fScale = MOS_MIN(1.0F, fScale);
1048 
1049             VPHAL_RENDER_CHK_STATUS(Mhw_CalcPolyphaseTablesY(
1050                 piYCoefsParam,
1051                 fScale,
1052                 Plane,
1053                 SrcFormat,
1054                 fHPStrength,
1055                 true,
1056                 dwHwPhrase,
1057                 0));
1058 
1059             // If the 8-tap adaptive is enabled for all channel, then UV/RB use the same coefficient as Y/G
1060             // So, coefficient for UV/RB channels caculation can be passed
1061             if (!b8TapAdaptiveEnable)
1062             {
1063                 if (!bBalancedFilter)
1064                 {
1065                     VPHAL_RENDER_CHK_STATUS(Mhw_CalcPolyphaseTablesY(
1066                         piUVCoefsParam,
1067                         fScale,
1068                         MHW_U_PLANE,
1069                         SrcFormat,
1070                         fHPStrength,
1071                         true,
1072                         dwHwPhrase,
1073                         0));
1074                 }
1075                 else
1076                 {
1077                     // If Chroma Siting info is present
1078                     if (dwChromaSiting & (bVertical ? MHW_CHROMA_SITING_VERT_TOP : MHW_CHROMA_SITING_HORZ_LEFT))
1079                     {
1080                         // No Chroma Siting
1081                         VPHAL_RENDER_CHK_STATUS(Mhw_CalcPolyphaseTablesUV(
1082                             piUVCoefsParam,
1083                             2.0F,
1084                             fScale));
1085                     }
1086                     else
1087                     {
1088                         // Chroma siting offset needs to be added
1089                         if (dwChromaSiting & (bVertical ? MHW_CHROMA_SITING_VERT_CENTER : MHW_CHROMA_SITING_HORZ_CENTER))
1090                         {
1091                             iUvPhaseOffset = MOS_UF_ROUND(0.5F * 16.0F);   // U0.4
1092                         }
1093                         else //if (ChromaSiting & (bVertical ? MHW_CHROMA_SITING_VERT_BOTTOM : MHW_CHROMA_SITING_HORZ_RIGHT))
1094                         {
1095                             iUvPhaseOffset = MOS_UF_ROUND(1.0F * 16.0F);   // U0.4
1096                         }
1097 
1098                         VPHAL_RENDER_CHK_STATUS(Mhw_CalcPolyphaseTablesUVOffset(
1099                             piUVCoefsParam,
1100                             3.0F,
1101                             fScale,
1102                             iUvPhaseOffset));
1103                     }
1104                 }
1105             }
1106         }
1107     }
1108 
1109 finish:
1110     return eStatus;
1111 }
1112 
1113 //!
1114 //! \brief    Set Sampler Avs 8x8 Table
1115 //! \param    [in] pRenderHal
1116 //!           Pointer to RenderHal Interface Structure
1117 //! \param    [in] pSamplerStateParams
1118 //!           Pointer to Sampler State Params
1119 //! \param    [in,out] pAvsParams
1120 //!           Pointer to AVS Params
1121 //! \param    [in] SrcFormat
1122 //!           Source Format
1123 //! \param    [in] fScaleX
1124 //!           Horizontal Scale Factor
1125 //! \param    [in] fScaleY
1126 //!           Vertical Scale Factor
1127 //! \param    [in] dwChromaSiting
1128 //!           Chroma Siting
1129 //! \return   MOS_STATUS
1130 //!
SetSamplerAvsTableParam(PRENDERHAL_INTERFACE pRenderHal,PMHW_SAMPLER_STATE_PARAM pSamplerStateParams,PMHW_AVS_PARAMS pAvsParams,MOS_FORMAT SrcFormat,float fScaleX,float fScaleY,uint32_t dwChromaSiting)1131 MOS_STATUS CompositeState::SetSamplerAvsTableParam(
1132     PRENDERHAL_INTERFACE            pRenderHal,
1133     PMHW_SAMPLER_STATE_PARAM        pSamplerStateParams,
1134     PMHW_AVS_PARAMS                 pAvsParams,
1135     MOS_FORMAT                      SrcFormat,
1136     float                           fScaleX,
1137     float                           fScaleY,
1138     uint32_t                        dwChromaSiting)
1139 {
1140     MOS_STATUS                   eStatus = MOS_STATUS_SUCCESS;
1141     bool                         bBalancedFilter;
1142     PMHW_SAMPLER_AVS_TABLE_PARAM pMhwSamplerAvsTableParam;
1143     bool                         bIsUpScaleAndYuvFormat;
1144 
1145     VPHAL_RENDER_CHK_NULL(pSamplerStateParams);
1146     VPHAL_RENDER_CHK_NULL(pAvsParams);
1147     VPHAL_RENDER_CHK_NULL(pAvsParams->piYCoefsY);
1148     VPHAL_RENDER_CHK_NULL(pAvsParams->piYCoefsX);
1149     VPHAL_RENDER_CHK_NULL(pAvsParams->piUVCoefsY);
1150     VPHAL_RENDER_CHK_NULL(pAvsParams->piUVCoefsX);
1151 
1152     pMhwSamplerAvsTableParam = pSamplerStateParams->Avs.pMhwSamplerAvsTableParam;
1153 
1154     pMhwSamplerAvsTableParam->bIsCoeffExtraEnabled = m_bAvsTableCoeffExtraEnabled;
1155     pMhwSamplerAvsTableParam->b8TapAdaptiveEnable  = pSamplerStateParams->Avs.b8TapAdaptiveEnable;
1156     bBalancedFilter                                = m_bAvsTableBalancedFilter;
1157 
1158     pMhwSamplerAvsTableParam->byteTransitionArea8Pixels = MEDIASTATE_AVS_TRANSITION_AREA_8_PIXELS;
1159     pMhwSamplerAvsTableParam->byteTransitionArea4Pixels = MEDIASTATE_AVS_TRANSITION_AREA_4_PIXELS;
1160     pMhwSamplerAvsTableParam->byteMaxDerivative8Pixels  = MEDIASTATE_AVS_MAX_DERIVATIVE_8_PIXELS;
1161     pMhwSamplerAvsTableParam->byteMaxDerivative4Pixels  = MEDIASTATE_AVS_MAX_DERIVATIVE_4_PIXELS;
1162     pMhwSamplerAvsTableParam->byteDefaultSharpnessLevel = MEDIASTATE_AVS_SHARPNESS_LEVEL_SHARP;
1163 
1164     bIsUpScaleAndYuvFormat = ((fScaleX > 1.0F || fScaleY > 1.0F) && IS_YUV_FORMAT(SrcFormat));
1165     if (SrcFormat == Format_Y410 ||
1166         SrcFormat == Format_AYUV ||
1167         SrcFormat == Format_Y416)
1168     {
1169         bIsUpScaleAndYuvFormat = false;
1170     }
1171 
1172     if (pMhwSamplerAvsTableParam->b8TapAdaptiveEnable)
1173     {
1174         pMhwSamplerAvsTableParam->bBypassXAdaptiveFiltering  = false;
1175         pMhwSamplerAvsTableParam->bBypassYAdaptiveFiltering  = false;
1176         pMhwSamplerAvsTableParam->bAdaptiveFilterAllChannels = true;
1177         pMhwSamplerAvsTableParam->bEnableRGBAdaptive         = IS_RGB_FORMAT(SrcFormat);
1178     }
1179     else if (bIsUpScaleAndYuvFormat)
1180     {
1181         // enable adaptive filter if it's being upscaled in either direction. we check it before clamping the SF.
1182         pMhwSamplerAvsTableParam->bBypassXAdaptiveFiltering = false;
1183         pMhwSamplerAvsTableParam->bBypassYAdaptiveFiltering = false;
1184     }
1185     else
1186     {
1187         pMhwSamplerAvsTableParam->bBypassXAdaptiveFiltering = true;
1188         pMhwSamplerAvsTableParam->bBypassYAdaptiveFiltering = true;
1189     }
1190 
1191     // No changes to AVS parameters -> skip
1192     if (SrcFormat == pAvsParams->Format &&
1193         fScaleX == pAvsParams->fScaleX &&
1194         fScaleY == pAvsParams->fScaleY)
1195     {
1196         goto finish;
1197     }
1198 
1199     // not change AVS coefficients if upscaling, to avoid recalculation
1200     if (fScaleX > 1.0F && pAvsParams->fScaleX > 1.0F)
1201     {
1202         pAvsParams->fScaleX = fScaleX;
1203     }
1204 
1205     // not change AVS coefficients if upscaling, to avoid recalculation
1206     if (fScaleY > 1.0F && pAvsParams->fScaleY > 1.0F)
1207     {
1208         pAvsParams->fScaleY = fScaleY;
1209     }
1210 
1211     AvsCoeffsCacheTag tag;
1212     tag.m_format              = SrcFormat;
1213     tag.m_8TapAdaptiveEnable  = pMhwSamplerAvsTableParam->b8TapAdaptiveEnable ? true : false;
1214     tag.m_balancedFilter      = bBalancedFilter;
1215     tag.m_forcePolyPhaseCoefs = pAvsParams->bForcePolyPhaseCoefs ? true : false;
1216     tag.m_chromaSiting        = dwChromaSiting;
1217     tag.m_scaleX              = fScaleX;
1218     tag.m_scaleY              = fScaleY;
1219 
1220     const MHW_AVS_PARAMS *cachedAvsParams;
1221     cachedAvsParams = m_AvsCoeffsCache.Find(tag);
1222 
1223     if (cachedAvsParams)
1224     {
1225         m_AvsCoeffsCache.Clone(*cachedAvsParams, *pAvsParams);
1226     }
1227     else
1228     {
1229         // Recalculate Horizontal scaling table
1230         VPHAL_RENDER_CHK_STATUS(SamplerAvsCalcScalingTable(
1231             SrcFormat,
1232             fScaleX,
1233             false,
1234             dwChromaSiting,
1235             bBalancedFilter,
1236             pMhwSamplerAvsTableParam->b8TapAdaptiveEnable ? true : false,
1237             pAvsParams));
1238 
1239         // Recalculate Vertical scaling table
1240         VPHAL_RENDER_CHK_STATUS(SamplerAvsCalcScalingTable(
1241             SrcFormat,
1242             fScaleY,
1243             true,
1244             dwChromaSiting,
1245             bBalancedFilter,
1246             pMhwSamplerAvsTableParam->b8TapAdaptiveEnable ? true : false,
1247             pAvsParams));
1248 
1249         // Save format used to calculate AVS parameters
1250         pAvsParams->Format = SrcFormat;
1251 
1252         m_AvsCoeffsCache.Insert(tag, *pAvsParams);
1253     }
1254 
1255     pMhwSamplerAvsTableParam->b4TapGY   = ((IS_RGB32_FORMAT(SrcFormat) || SrcFormat == Format_Y410 || SrcFormat == Format_AYUV || SrcFormat == Format_Y416) && !pMhwSamplerAvsTableParam->b8TapAdaptiveEnable);
1256     pMhwSamplerAvsTableParam->b4TapRBUV = (!pMhwSamplerAvsTableParam->b8TapAdaptiveEnable);
1257 
1258     VPHAL_RENDER_CHK_STATUS(VpHal_RenderCommonSetAVSTableParam(pAvsParams, pMhwSamplerAvsTableParam));
1259 
1260 finish:
1261     return eStatus;
1262 }
1263 
1264 //!
1265 //! \brief    Prepare phases for composite and determine intermediate colorspace
1266 //! \param    [in] pcRenderParams
1267 //!           Pointer to Render parameters
1268 //! \param    [in] ppSources
1269 //!           Pointer to the address of Source Surfaces
1270 //! \param    [in] iSources
1271 //!           Count of Source Surfaces
1272 //! \return   VPHAL_CSPACE
1273 //!           Return intermediate colorspace
1274 //!
PrepareCSC(PCVPHAL_RENDER_PARAMS pcRenderParams,PVPHAL_SURFACE * ppSources,int32_t iSources)1275 VPHAL_CSPACE CompositeState::PrepareCSC(
1276     PCVPHAL_RENDER_PARAMS   pcRenderParams,
1277     PVPHAL_SURFACE          *ppSources,
1278     int32_t                 iSources)
1279 {
1280     PVPHAL_SURFACE                  pTarget;
1281     PVPHAL_SURFACE                  pSrc;
1282     int32_t                         i, j;
1283     int32_t                         csc_count = 0;
1284     int32_t                         csc_min = iSources + 1;
1285     int32_t                         cspace_in_use[CSpace_Count];
1286     bool                            bYUVTarget;
1287     VPHAL_CSPACE                    cs;
1288     VPHAL_CSPACE                    Temp_ColorSpace = CSpace_Any;
1289     VPHAL_CSPACE                    Main_ColorSpace = CSpace_None;
1290 
1291     // Check if target is YUV
1292     pTarget    = pcRenderParams->pTarget[0];
1293     bYUVTarget = IS_RGB_FORMAT(pTarget->Format) ? false : true;
1294 
1295     // Gets primary video cspace
1296     // Implements xvYCC passthrough mode
1297     // Set Color Spaces in use
1298     MOS_ZeroMemory(cspace_in_use, sizeof(cspace_in_use));
1299     for (i = 0; i < iSources; i++)
1300     {
1301         // Get current source
1302         pSrc = ppSources[i];
1303 
1304         // Save Main Video color space
1305         if (pSrc->SurfType == SURF_IN_PRIMARY &&
1306             Main_ColorSpace == CSpace_None)
1307         {
1308             Main_ColorSpace = pSrc->ColorSpace;
1309         }
1310 
1311         // Set xvYCC pass through mode
1312         if (bYUVTarget &&
1313             (pSrc->ColorSpace == CSpace_xvYCC709 ||
1314              pSrc->ColorSpace == CSpace_xvYCC601))
1315         {
1316             Temp_ColorSpace = pSrc->ColorSpace;
1317             goto finish;
1318         }
1319 
1320         // Don't take PAL formats into consideration
1321         if ((!IS_PAL_FORMAT(pSrc->Format)) &&
1322              pSrc->ColorSpace > CSpace_Any &&
1323              pSrc->ColorSpace < CSpace_Count)
1324         {
1325             cs = KernelDll_TranslateCspace(pSrc->ColorSpace);
1326             if (cs >= CSpace_Any)
1327             {
1328                 cspace_in_use[cs]++;
1329             }
1330         }
1331     }
1332 
1333     // For every CS in use, iterate through source CS and keep a
1334     // count of number of CSC operation needed. Determine the Temporary
1335     // color space as the one requiring min. # of CSC ops.
1336     for (j = (CSpace_Any + 1); j < CSpace_Count; j++)
1337     {
1338         // Skip color spaces not in use
1339         if (!cspace_in_use[j])
1340         {
1341             continue;
1342         }
1343 
1344         // Count # of CS conversions
1345         cs = (VPHAL_CSPACE) j;
1346         csc_count = 0;
1347         for (i = 0; i < iSources; i++)
1348         {
1349             // Get current source
1350             pSrc = ppSources[i];
1351 
1352             // Ignore palletized layers
1353             if (IS_PAL_FORMAT(pSrc->Format) ||
1354                 pSrc->ColorSpace == CSpace_Any)
1355             {
1356                 continue;
1357             }
1358 
1359             // Check if CSC/PA is required
1360             if (KernelDll_TranslateCspace(pSrc->ColorSpace) != cs ||
1361                 (pSrc->pProcampParams != nullptr &&
1362                  pSrc->pProcampParams->bEnabled))
1363             {
1364                 csc_count++;
1365             }
1366         }
1367 
1368         // Save best choice as requiring minimum number of CSC operations
1369         // Use main cspace as default if same CSC count
1370         if ((csc_count <  csc_min) ||
1371             (csc_count == csc_min && cs == Main_ColorSpace) )
1372         {
1373             Temp_ColorSpace = cs;
1374             csc_min = csc_count;
1375         }
1376     }
1377 
1378     // If all layers are palletized, use the CS from first layer (as good as any other)
1379     if (Temp_ColorSpace == CSpace_Any && iSources > 0)
1380     {
1381         Temp_ColorSpace = ppSources[0]->ColorSpace;
1382     }
1383 
1384 finish:
1385 
1386     VPHAL_RENDER_NORMALMESSAGE("Main_ColorSpace %d, Temp_ColorSpace %d, csc_count %d.",
1387         Main_ColorSpace,
1388         Temp_ColorSpace,
1389         csc_count);
1390 
1391     return Temp_ColorSpace;
1392 }
1393 
1394 //!
1395 //! \brief    Prepare phases for composite and allocate intermediate buffer for rendering
1396 //! \param    [in] pcRenderParams
1397 //!           Pointer to Render parameters
1398 //! \param    [in] ppSources
1399 //!           Pointer to the address of Source Surfaces
1400 //! \param    [in] iSources
1401 //!           Count of Source Surfaces
1402 //! \return   bool
1403 //!           Return true if multiple phases, otherwise false
1404 //!
PreparePhases(PCVPHAL_RENDER_PARAMS pcRenderParams,PVPHAL_SURFACE * ppSources,int32_t iSources)1405 bool CompositeState::PreparePhases(
1406     PCVPHAL_RENDER_PARAMS       pcRenderParams,
1407     PVPHAL_SURFACE              *ppSources,
1408     int32_t                     iSources)
1409 {
1410     PMOS_INTERFACE          pOsInterface;
1411     VPHAL_COMPOSITE_PARAMS  Composite;
1412     MOS_RESOURCE            OsResource;
1413     uint32_t                dwTempWidth;    // Temporary surface width
1414     uint32_t                dwTempHeight;   // Temporary surface height
1415     PVPHAL_SURFACE          pTarget;
1416     PVPHAL_SURFACE          pIntermediate;
1417     int32_t                 i;
1418     bool                    bMultiplePhases;
1419     MOS_ALLOC_GFXRES_PARAMS AllocParams;
1420     VPHAL_GET_SURFACE_INFO  Info;
1421 
1422     pTarget = pcRenderParams->pTarget[0];
1423 
1424     // Constriction support
1425     dwTempWidth = dwTempHeight = 0;
1426     if (pcRenderParams->pConstriction)
1427     {
1428         // Force multiple phases
1429         bMultiplePhases = true;
1430 
1431         // Temporary surface size = constriction rectangle
1432         dwTempWidth  = pcRenderParams->pConstriction->right;
1433         dwTempHeight = pcRenderParams->pConstriction->bottom;
1434     }
1435     else
1436     {
1437         // Reset multiple phase support
1438         bMultiplePhases = false;
1439 
1440         // Temporary surface has the same size as render target
1441         dwTempWidth  = pTarget->dwWidth;
1442         dwTempHeight = pTarget->dwHeight;
1443 
1444         // Check if multiple phases by building filter for first phase
1445         ResetCompParams(&Composite);
1446         for (i = 0; i < iSources; i++)
1447         {
1448             if (!AddCompLayer(&Composite, ppSources[i]))
1449             {
1450                 bMultiplePhases = true;
1451                 break;
1452             }
1453         }
1454 
1455         // Add render target
1456         if (!AddCompTarget(&Composite, pTarget))
1457         {
1458             bMultiplePhases = true;
1459         }
1460     }
1461 
1462     // Reallocate Intermediate surface
1463     if (bMultiplePhases)
1464     {
1465         pOsInterface  = m_pOsInterface;
1466         pIntermediate = &m_Intermediate;
1467 
1468         // Allocate/Reallocate temporary output
1469         if (dwTempWidth  > pIntermediate->dwWidth ||
1470             dwTempHeight > pIntermediate->dwHeight)
1471         {
1472             // Get max values
1473             dwTempWidth  = MOS_MAX(dwTempWidth , pIntermediate->dwWidth);
1474             dwTempHeight = MOS_MAX(dwTempHeight, pIntermediate->dwHeight);
1475 
1476             // Allocate buffer in fixed increments
1477             dwTempWidth  = MOS_ALIGN_CEIL(dwTempWidth , VPHAL_BUFFER_SIZE_INCREMENT);
1478             dwTempHeight = MOS_ALIGN_CEIL(dwTempHeight, VPHAL_BUFFER_SIZE_INCREMENT);
1479 
1480             MOS_ZeroMemory(&AllocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
1481             MOS_ZeroMemory(&OsResource, sizeof(MOS_RESOURCE));
1482 
1483             AllocParams.Type     = MOS_GFXRES_2D;
1484             AllocParams.TileType = MOS_TILE_Y;
1485             AllocParams.dwWidth  = dwTempWidth;
1486             AllocParams.dwHeight = dwTempHeight;
1487             AllocParams.Format   = Format_A8R8G8B8;
1488 
1489             pOsInterface->pfnAllocateResource(
1490                 pOsInterface,
1491                 &AllocParams,
1492                 &OsResource);
1493 
1494             // Get Allocation index of source for rendering
1495             pOsInterface->pfnRegisterResource(
1496                 pOsInterface,
1497                 &OsResource,
1498                 false,
1499                 true);
1500 
1501             if (!Mos_ResourceIsNull(&OsResource))
1502             {
1503                 // Deallocate old resource
1504                 pOsInterface->pfnFreeResource(pOsInterface,
1505                                               &pIntermediate->OsResource);
1506 
1507                 // Set new resource
1508                 pIntermediate->OsResource = OsResource;
1509 
1510                 // Get resource info (width, height, pitch, tiling, etc)
1511                 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
1512 
1513                 VpHal_GetSurfaceInfo(
1514                     pOsInterface,
1515                     &Info,
1516                     pIntermediate);
1517             }
1518         }
1519 
1520         // Set output parameters
1521         pIntermediate->SurfType          = SURF_IN_PRIMARY;
1522         pIntermediate->SampleType        = SAMPLE_PROGRESSIVE;
1523         pIntermediate->ColorSpace        = pTarget->ColorSpace;
1524         pIntermediate->ExtendedGamut     = pTarget->ExtendedGamut;
1525         pIntermediate->rcSrc             = pTarget->rcSrc;
1526         pIntermediate->rcDst             = pTarget->rcDst;
1527         pIntermediate->ScalingMode       = VPHAL_SCALING_BILINEAR;
1528         pIntermediate->bIEF              = false;
1529 
1530         pIntermediate = &m_Intermediate2;
1531 
1532         // Allocate/Reallocate temporary output
1533         if (dwTempWidth  > pIntermediate->dwWidth ||
1534             dwTempHeight > pIntermediate->dwHeight)
1535         {
1536             // Get max values
1537             dwTempWidth  = MOS_MAX(dwTempWidth , pIntermediate->dwWidth);
1538             dwTempHeight = MOS_MAX(dwTempHeight, pIntermediate->dwHeight);
1539 
1540             // Allocate buffer in fixed increments
1541             dwTempWidth  = MOS_ALIGN_CEIL(dwTempWidth , VPHAL_BUFFER_SIZE_INCREMENT);
1542             dwTempHeight = MOS_ALIGN_CEIL(dwTempHeight, VPHAL_BUFFER_SIZE_INCREMENT);
1543 
1544             MOS_ZeroMemory(&AllocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
1545 
1546             AllocParams.Type     = MOS_GFXRES_2D;
1547             AllocParams.TileType = MOS_TILE_Y;
1548             AllocParams.dwWidth  = dwTempWidth;
1549             AllocParams.dwHeight = dwTempHeight;
1550             AllocParams.Format   = Format_A8R8G8B8;
1551 
1552             pOsInterface->pfnAllocateResource(
1553                 pOsInterface,
1554                 &AllocParams,
1555                 &OsResource);
1556 
1557             if (!Mos_ResourceIsNull(&OsResource))
1558             {
1559                 // Deallocate old resource
1560                 pOsInterface->pfnFreeResource(pOsInterface,
1561                                               &pIntermediate->OsResource);
1562 
1563                 // Set new resource
1564                 pIntermediate->OsResource = OsResource;
1565 
1566                 // Get resource info (width, height, pitch, tiling, etc)
1567                 MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
1568 
1569                 VpHal_GetSurfaceInfo(
1570                     pOsInterface,
1571                     &Info,
1572                     pIntermediate);
1573             }
1574         }
1575 
1576         // Set output parameters
1577         pIntermediate->SurfType          = SURF_IN_PRIMARY;
1578         pIntermediate->SampleType        = SAMPLE_PROGRESSIVE;
1579         pIntermediate->ColorSpace        = pTarget->ColorSpace;
1580         pIntermediate->ExtendedGamut     = pTarget->ExtendedGamut;
1581         pIntermediate->rcSrc             = pTarget->rcSrc;
1582         pIntermediate->rcDst             = pTarget->rcDst;
1583         pIntermediate->ScalingMode       = VPHAL_SCALING_BILINEAR;
1584         pIntermediate->bIEF              = false;
1585     }
1586 
1587     return bMultiplePhases;
1588 }
1589 
1590 //!
1591 //! \brief    Reset composite rendering parameters for the current phase
1592 //! \param    [in,out] pComposite
1593 //!           Pointer to Composite parameters
1594 //! \return   void
1595 //!
ResetCompParams(PVPHAL_COMPOSITE_PARAMS pComposite)1596 void CompositeState::ResetCompParams(
1597     PVPHAL_COMPOSITE_PARAMS     pComposite)
1598 {
1599     MOS_ZeroMemory(pComposite, sizeof(*pComposite));
1600 
1601     pComposite->nLayers   = VPHAL_COMP_MAX_LAYERS;
1602     pComposite->nPalettes = VPHAL_COMP_MAX_PALETTES;
1603     pComposite->nProcamp  = VPHAL_COMP_MAX_PROCAMP;
1604     pComposite->nLumaKeys = VPHAL_COMP_MAX_LUMA_KEY;
1605     pComposite->nAVS      = VPHAL_COMP_MAX_AVS;
1606     pComposite->nSampler  = VPHAL_COMP_MAX_SAMPLER;
1607 
1608     // reset render target count to 1
1609     pComposite->uTargetCount = 1;
1610 
1611     pComposite->bAlphaCalculateEnable = false;
1612 }
1613 
1614 //!
1615 //! \brief    Adds a source layer for composite
1616 //! \param    [in,out] pComposite
1617 //!           Pointer to Composite parameters
1618 //! \param    [in] pSource
1619 //!           Pointer to Source Surface
1620 //! \return   bool
1621 //!           Return TURE if source may be processed in the same phase, otherwise false
1622 //!
AddCompLayer(PVPHAL_COMPOSITE_PARAMS pComposite,PVPHAL_SURFACE pSource)1623 bool CompositeState::AddCompLayer(
1624     PVPHAL_COMPOSITE_PARAMS     pComposite,
1625     PVPHAL_SURFACE              pSource)
1626 {
1627     bool                bResult;
1628     PVPHAL_SURFACE      pPrevSource;
1629     bool                bSinglePhaseRotate;
1630     VPHAL_SCALING_MODE  scalingMode;
1631 
1632     bResult            = false;
1633     pPrevSource        = nullptr;
1634     bSinglePhaseRotate = false;
1635 
1636     if (pComposite == nullptr || pSource == nullptr)
1637     {
1638         goto finish;
1639     }
1640 
1641     scalingMode           = pSource->ScalingMode;
1642 
1643     // On Gen9+, Rotation is done in sampler. Multiple phases are not required.
1644     if (!m_bSamplerSupportRotation)
1645     {
1646         if (pComposite->uSourceCount == 0)
1647         {
1648             // Set Layer 0 rotation info
1649             pComposite->Rotation = pSource->Rotation;
1650             bSinglePhaseRotate = true;
1651         }
1652         else if (pComposite->uSourceCount == 1)
1653         {
1654             // Single phase if: L0 (angle) + L1 (no rotation) OR L1 angle == L0 angle
1655             bSinglePhaseRotate = (pSource->Rotation == VPHAL_ROTATION_IDENTITY ||
1656                                   pSource->Rotation == pComposite->Rotation) ? true : false;
1657         }
1658         else
1659         {
1660             // Get pointer to previous source
1661             pPrevSource = pComposite->pSource[pComposite->uSourceCount - 1];
1662 
1663             // Single phase if:L2 angle == L1 angle
1664             bSinglePhaseRotate = (pSource->Rotation == pPrevSource->Rotation) ? true : false;
1665         }
1666     }
1667     else
1668     {
1669         bSinglePhaseRotate = true;
1670     }
1671 
1672     // Number of layers
1673     pComposite->nLayers--;
1674 
1675     // Number of palettes
1676     if (pSource->Palette.PaletteType != VPHAL_PALETTE_NONE)
1677     {
1678         pComposite->nPalettes--;
1679     }
1680 
1681     // Number of procamp parameters
1682     if (pSource->pProcampParams)
1683     {
1684         pComposite->nProcamp--;
1685     }
1686 
1687     // Number of luma keys
1688     if (pSource->pLumaKeyParams)
1689     {
1690         pComposite->nLumaKeys--;
1691         if (pComposite->nLumaKeys < 0 || pComposite->uSourceCount > 1)
1692         {
1693             bResult = false;
1694             goto finish;
1695         }
1696         if (pComposite->uSourceCount == 1)
1697         {
1698             // This layer requires 3d sampler to perform luma key.
1699             // So set previous layer's scaling mode to AVS and reset the nSampler.
1700             // Disable AVS scaling mode in cases AVS is not available
1701             if (pComposite->pSource[0]->ScalingMode != VPHAL_SCALING_AVS && !m_need3DSampler)
1702             {
1703                 pComposite->pSource[0]->ScalingMode = VPHAL_SCALING_AVS;
1704                 pComposite->nAVS--;
1705             }
1706             pComposite->nSampler = VPHAL_COMP_MAX_SAMPLER;
1707         }
1708     }
1709 
1710     // Number of AVS, but lumaKey and BOB DI needs 3D sampler instead of AVS sampler.
1711     if (pSource->ScalingMode == VPHAL_SCALING_AVS  && !pSource->pLumaKeyParams && !IsBobDiEnabled(pSource))
1712     {
1713         pComposite->nAVS--;
1714     }
1715     // Number of Sampler filter mode, we had better only support Nearest or Bilinear filter in one phase
1716     // If two filters are used together, the later filter overwrite the first and cause output quality issue.
1717     else if ((pSource->rcDst.right - pSource->rcDst.left) == (pSource->rcSrc.right - pSource->rcSrc.left) &&
1718              (pSource->rcDst.bottom - pSource->rcDst.top) == (pSource->rcSrc.bottom - pSource->rcSrc.top) &&
1719              !IS_PL3_FORMAT(pSource->Format))
1720     {
1721         // Use sampler luma key feature only if this is not the bottom most layer
1722         if (pSource->pLumaKeyParams && pComposite->uSourceCount)
1723         {
1724             scalingMode           = VPHAL_SCALING_NEAREST;
1725             pComposite->nSampler &= VPHAL_COMP_SAMPLER_LUMAKEY;
1726         }
1727         else if (pComposite->nSampler & VPHAL_COMP_SAMPLER_NEAREST)
1728         {
1729             scalingMode           = VPHAL_SCALING_NEAREST;
1730             pComposite->nSampler &= VPHAL_COMP_SAMPLER_NEAREST;
1731         }
1732         else
1733         {
1734             // switch to AVS if AVS sampler is not used, decrease the count of comp phase
1735             scalingMode = VPHAL_SCALING_AVS;
1736             pComposite->nAVS--;
1737         }
1738     }
1739     else if (!IS_PL3_FORMAT(pSource->Format))
1740     {
1741         // Use sampler luma key feature only if this is not the bottom most layer
1742         if (pSource->pLumaKeyParams && pComposite->uSourceCount)
1743         {
1744             scalingMode           = VPHAL_SCALING_BILINEAR;
1745             pComposite->nSampler &= VPHAL_COMP_SAMPLER_LUMAKEY;
1746         }
1747         else if (pComposite->nSampler & VPHAL_COMP_SAMPLER_BILINEAR)
1748         {
1749             scalingMode           = VPHAL_SCALING_BILINEAR;
1750             pComposite->nSampler &= VPHAL_COMP_SAMPLER_BILINEAR;
1751         }
1752         else
1753         {
1754             // switch to AVS if AVS sampler is not used, decrease the count of comp phase
1755             scalingMode = VPHAL_SCALING_AVS;
1756             pComposite->nAVS--;
1757         }
1758     }
1759 
1760     // Fails if any of the limits are reached
1761     // Output structure has reason why failed :-)
1762     // multi-passes if rotation is not the same as Layer 0 rotation
1763     // single pass if Primary layer needs rotation and remaining layer does not need rotation
1764     if (pComposite->nLayers   < 0 ||
1765         pComposite->nPalettes < 0 ||
1766         pComposite->nProcamp  < 0 ||
1767         pComposite->nLumaKeys < 0 ||
1768         pComposite->nAVS      < 0 ||
1769         pComposite->nSampler == 0 ||
1770         bSinglePhaseRotate   == false)
1771     {
1772         //Multipass
1773         goto finish;
1774     }
1775 
1776     // Append source to compositing operation
1777     pSource->ScalingMode = scalingMode;
1778     pComposite->pSource[pComposite->uSourceCount] = pSource;
1779     pComposite->uSourceCount++;
1780     bResult = true;
1781 
1782     VPHAL_RENDER_NORMALMESSAGE("ScalingMode %d, nSampler %d", pSource->ScalingMode, pComposite->nSampler);
1783 
1784 finish:
1785     return bResult;
1786 }
1787 
1788 //!
1789 //! \brief    Adds render target layer for composite
1790 //! \param    [in,out] pComposite
1791 //!           Pointer to Composite parameters
1792 //! \param    [in] pTarget
1793 //!           Pointer to target surface
1794 //! \return   bool
1795 //!           Return TURE if target may be processed in the same phase, otherwise false
1796 //!
AddCompTarget(PVPHAL_COMPOSITE_PARAMS pComposite,PVPHAL_SURFACE pTarget)1797 bool CompositeState::AddCompTarget(
1798     PVPHAL_COMPOSITE_PARAMS     pComposite,
1799     PVPHAL_SURFACE              pTarget)
1800 {
1801     bool    bResult;
1802 
1803     // Set render target
1804     pComposite->Target[0] = *pTarget;
1805 
1806     // Number of procamp parameters
1807     if (pTarget->pProcampParams)
1808     {
1809         pComposite->nProcamp--;
1810     }
1811 
1812     // Fails if max procamp already reached
1813     // Procamp needs to be performed in a different phase
1814     if (pComposite->nProcamp  < 0)
1815     {
1816         bResult = false;
1817         pComposite->Target[0].pProcampParams = nullptr;
1818     }
1819     else
1820     {
1821         bResult = true;
1822     }
1823 
1824     return bResult;
1825 }
1826 
1827 //!
1828 //! \brief    Composite multiple phase rendering
1829 //! \details  Composite render with multiple phases. In some cases we cannot process composition just in one phase
1830 //!           for example, if the input streams count is 9 (1 primary + 8 substreams), we need to postpone the
1831 //!           9th stream to next second phase due to the input count limitation of current composition kernel.
1832 //! \param    [in] pcRenderParams
1833 //!           Pointer to VPHAL_RENDER_PARAMS
1834 //! \param    [in] ppSources
1835 //!           Pointer to PVPHAL_SURFACE, array of input surfaces
1836 //! \param    [in] iSources
1837 //!           constant int iSource indicating the size of ppSources
1838 //! \param    [in] pOutput
1839 //!           Pointer to VPHAL_SURFACE, output surface for the overall composition process
1840 //! \return   MOS_STATUS
1841 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
1842 //!
RenderMultiPhase(PCVPHAL_RENDER_PARAMS pcRenderParams,PVPHAL_SURFACE * ppSources,const int32_t iSources,PVPHAL_SURFACE pOutput)1843 MOS_STATUS CompositeState::RenderMultiPhase(
1844     PCVPHAL_RENDER_PARAMS   pcRenderParams,
1845     PVPHAL_SURFACE          *ppSources,
1846     const int32_t           iSources,
1847     PVPHAL_SURFACE          pOutput)
1848 {
1849     MOS_STATUS           eStatus;
1850     int32_t              phase;                         // Current phase
1851     int32_t              i;                             // Auxiliary integer
1852     uint32_t             index;                         // Current source index
1853     PVPHAL_SURFACE       pSrc                = nullptr; // Current source surface
1854     PRENDERHAL_INTERFACE pRenderHal          = m_pRenderHal;
1855     PMOS_INTERFACE       pOsInterface        = m_pOsInterface;
1856     bool                 bLastPhase          = false;
1857     bool                 bExtraRotationPhase = false;
1858 
1859     // Perf related
1860     bool                 bPrimary, bRotation;
1861     VPHAL_PERFTAG        PerfTag;
1862 
1863     for (index = 0, phase = 0; (!bLastPhase); phase++)
1864     {
1865         VPHAL_COMPOSITE_PARAMS  CompositeParams;
1866         // Prepare compositing structure
1867         ResetCompParams(&CompositeParams);
1868 
1869 //        VPHAL_DBG_STATE_DUMPPER_SET_CURRENT_PHASE(phase);
1870 
1871         //Set the alpha for composited surface
1872         CompositeParams.pCompAlpha = pcRenderParams->pCompAlpha;
1873 
1874         // First phase - set colorfill + render all blocks
1875         if (phase == 0)
1876         {
1877             CompositeParams.pColorFillParams = pcRenderParams->pColorFillParams;
1878             CompositeParams.bSkipBlocks      = false;
1879         }
1880         else
1881         // Other phases - skip blocks by default (modified if RT has Procamp)
1882         {
1883             CompositeParams.bSkipBlocks      = true;
1884         }
1885 
1886         // Constricted output - affects coordinate calculations
1887         CompositeParams.pConstriction = pcRenderParams->pConstriction;
1888 
1889         // Validate samples and number of samples for each layer
1890         bLastPhase = true;
1891         bPrimary   = false;
1892         bRotation  = false;
1893         for (i = 0; index < (uint32_t)iSources || bExtraRotationPhase; i++)
1894         {
1895             // Set previous output as the first layer
1896             if (i == 0 && phase != 0)
1897             {
1898                 // Optimization for 2 layers composition (with sub-layer rotation) usage case , in the second phase, the first layer should be layer0
1899                 if (!m_bApplyTwoLayersCompOptimize || (iSources != 2) || (ppSources[1]->Rotation == VPHAL_ROTATION_IDENTITY))
1900                 {
1901                     pSrc = pOutput;
1902                 }
1903                 else
1904                 {
1905                     CompositeParams.pColorFillParams = pcRenderParams->pColorFillParams;
1906                     CompositeParams.bSkipBlocks      = false;
1907                     pSrc = ppSources[0];
1908                 }
1909             }
1910             else if (i == 1 && bExtraRotationPhase)
1911             {
1912                 // bExtraRotationPhase == true means that Intermediate2 was used as a
1913                 // temp output resource in the previous phase and now is to be
1914                 // used as an input
1915                 pSrc = &m_Intermediate2;
1916                 pSrc->SurfType = SURF_IN_SUBSTREAM; // set the surface type to substream
1917                 bExtraRotationPhase = false;        // reset rotation phase
1918             }
1919             else
1920             {
1921                 pSrc = ppSources[index];
1922                 index++;
1923             }
1924 
1925             // Set if primary is present
1926             if (pSrc->SurfType == SURF_IN_PRIMARY)
1927             {
1928                 bPrimary = true;
1929             }
1930 
1931             // Add layer to the compositing - breaks at end of phase
1932             pSrc->iLayerID = i;
1933 
1934             if (!AddCompLayer(&CompositeParams, pSrc))
1935             {
1936                 bLastPhase = false;
1937                 index--;
1938                 break;
1939             }
1940 
1941             if (pSrc->Rotation != VPHAL_ROTATION_IDENTITY)
1942             {
1943                 bRotation = true;
1944             }
1945         }
1946 
1947         // Setup render target
1948         bLastPhase &= AddCompTarget(&CompositeParams, pOutput);
1949 
1950         // Last phase
1951         if (bLastPhase && pcRenderParams->pConstriction == nullptr)
1952         {
1953             // Set the actual render target(s), process all blocks
1954             i = 0;
1955             do
1956             {
1957                 CompositeParams.Target[i] = *pcRenderParams->pTarget[i];
1958                 i++;
1959                 CompositeParams.uTargetCount  = i;
1960             } while (i < (int32_t)pcRenderParams->uDstCount);
1961 
1962             CompositeParams.bSkipBlocks = false;
1963 
1964             // Force the output rectangles to be the final render target rectangles.
1965             // pTarget could be used as an input as well because it could be used
1966             // as a temp output in the previous render phase.
1967             CompositeParams.Target[0].rcSrc = pcRenderParams->pTarget[0]->rcSrc;
1968             CompositeParams.Target[0].rcDst = pcRenderParams->pTarget[0]->rcDst;
1969         }
1970 
1971         // Force output as "render target" surface type
1972         CompositeParams.Target[0].SurfType = SURF_OUT_RENDERTARGET;
1973 
1974         // Reset states before rendering (clear allocations, get GSH allocation index
1975         //                                + any additional housekeeping)
1976         pOsInterface->pfnResetOsStates(pOsInterface);
1977         VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnReset(pRenderHal));
1978 
1979         // Set Slice Shutdown Mode
1980         if (m_bSingleSlice)
1981         {
1982             pRenderHal->pfnSetSliceShutdownMode(pRenderHal, true);
1983         }
1984 
1985         // Set performance tag for current phase
1986         // Set rotation perftag if there is a layer that needs to be rotated in
1987         // the current phase, regardless of primary or non-primary.
1988         if (bRotation)
1989         {
1990             PerfTag = (VPHAL_PERFTAG)((int)VPHAL_ROT + i - 1);
1991         }
1992         else if (bPrimary)
1993         {
1994             PerfTag = (VPHAL_PERFTAG)((int)VPHAL_PRI + i - 1);
1995         }
1996         else
1997         {
1998             PerfTag = (VPHAL_PERFTAG)((int)VPHAL_NONE + i);
1999         }
2000         pOsInterface->pfnSetPerfTag(pOsInterface, PerfTag);
2001 
2002         // Flag to indicate to do the alpha calculate
2003         CompositeParams.bAlphaCalculateEnable = pcRenderParams->bCalculatingAlpha;
2004 
2005         // Perform compositing operation
2006         // Optimization for 2 layers composition (with sub-layer rotation) usage case , skip the first phase composition (layer0 -> RT)
2007         if (!m_bApplyTwoLayersCompOptimize || bLastPhase || (iSources != 2) || (ppSources[1]->Rotation == VPHAL_ROTATION_IDENTITY))
2008         {
2009             m_bLastPhase = bLastPhase && (pcRenderParams->pConstriction == nullptr);
2010             VPHAL_RENDER_CHK_STATUS(RenderPhase(&CompositeParams));
2011         }
2012 
2013         // do an extra rotation if needed
2014         bExtraRotationPhase = false;
2015 
2016         // If rotation is done in sampler. Multiple phases are not required.
2017         if (!m_bSamplerSupportRotation)
2018         {
2019             if ((!bLastPhase) && pSrc && (pSrc->Rotation != VPHAL_ROTATION_IDENTITY))
2020             {
2021                 bExtraRotationPhase = true;
2022 
2023                 // Prepare compositing structure
2024                 ResetCompParams(&CompositeParams);
2025 
2026                 // Optimization for 2 layers composition (with sub-layer rotation) usage case, This is the first phase
2027                 if ((iSources != 2) || (ppSources[1]->Rotation == VPHAL_ROTATION_IDENTITY))
2028                 {
2029                     CompositeParams.bSkipBlocks   = true;
2030                 }
2031                 else
2032                 {
2033                     // set colorfill + render all blocks
2034                     CompositeParams.pColorFillParams = pcRenderParams->pColorFillParams;
2035                     CompositeParams.bSkipBlocks      = false;
2036                 }
2037 
2038                 // Set the alpha for composited surface
2039                 CompositeParams.pCompAlpha = pcRenderParams->pCompAlpha;
2040 
2041                 // When building filter description, if the first layer is translucent,
2042                 // colorfill will always be used. But in this rotation phase, if the
2043                 // src rectangle can cover dest, there is no need to do colorfill.
2044                 // Force skip it here to avoid performance drop.
2045                 CompositeParams.bForceSkipColorFill = true;
2046 
2047                 CompositeParams.pConstriction   = nullptr;
2048                 // process the next sample, cannot group more samples here because
2049                 // the temporary output will be the input of next phase and we need
2050                 // new kernel to deal with the transparent area of the bigger rectangle
2051                 // of the temporary output.
2052                 pSrc = ppSources[index];
2053                 index++;
2054                 pSrc->iLayerID = 0;
2055                 AddCompLayer(&CompositeParams, pSrc);
2056 
2057                 // using pTarget as a temp resource
2058                 if (pSrc->pBlendingParams)
2059                 {
2060                     if (m_Intermediate2.pBlendingParams == nullptr)
2061                     {
2062                         m_Intermediate2.pBlendingParams = (PVPHAL_BLENDING_PARAMS)
2063                             MOS_AllocAndZeroMemory(sizeof(VPHAL_BLENDING_PARAMS));
2064                     }
2065                     if (m_Intermediate2.pBlendingParams)
2066                     {
2067                         m_Intermediate2.pBlendingParams->BlendType = pSrc->pBlendingParams->BlendType;
2068                         m_Intermediate2.pBlendingParams->fAlpha = pSrc->pBlendingParams->fAlpha;
2069                     }
2070                 }
2071                 else
2072                 {
2073                     // clear the blending params if it was set from the previous phase
2074                     if (m_Intermediate2.pBlendingParams)
2075                     {
2076                         MOS_FreeMemory(m_Intermediate2.pBlendingParams);
2077                         m_Intermediate2.pBlendingParams = nullptr;
2078                     }
2079                 }
2080 
2081                 // update the output rectangles with the input rectangles
2082                 m_Intermediate2.rcDst = m_Intermediate2.rcSrc = pSrc->rcDst;
2083 
2084                 AddCompTarget(&CompositeParams, &m_Intermediate2);
2085                 // Force output as "render target" surface type
2086                 CompositeParams.Target[0].SurfType = SURF_OUT_RENDERTARGET;
2087 
2088                 // Reset states before rendering (clear allocations, get GSH allocation index
2089                 //                                + any additional housekeeping)
2090                 pOsInterface->pfnResetOsStates(pOsInterface);
2091                 VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnReset(pRenderHal));
2092 
2093                 // Set performance tag for current rotation phase
2094                 PerfTag = (VPHAL_PERFTAG)((int)VPHAL_ROT);
2095                 pOsInterface->pfnSetPerfTag(pOsInterface, PerfTag);
2096 
2097                 // Perform compositing operation
2098                 VPHAL_RENDER_CHK_STATUS(RenderPhase(&CompositeParams));
2099             }
2100         }
2101     }
2102     eStatus = MOS_STATUS_SUCCESS;
2103 finish:
2104     return eStatus;
2105 }
2106 
2107 //!
2108 //! \brief    Composite Rendering
2109 //! \details  VPHal Composite Render entry, this render handles Procamp/CSC/ColorFill/
2110 //!           Scaling/BOBDI
2111 //! \param    [in,out] pcRenderParams
2112 //!           Pointer to Render parameters
2113 //! \return   MOS_STATUS
2114 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
2115 //!
Render(PCVPHAL_RENDER_PARAMS pcRenderParams,RenderpassData * pRenderPassData)2116 MOS_STATUS CompositeState::Render(
2117     PCVPHAL_RENDER_PARAMS  pcRenderParams,
2118     RenderpassData         *pRenderPassData)
2119 {
2120     MOS_STATUS              eStatus;
2121 
2122     PRENDERHAL_INTERFACE    pRenderHal = nullptr;
2123     PMOS_INTERFACE          pOsInterface;
2124 
2125     // Sorted sources for compositing
2126     int32_t                 iProcamp;                    // Procamp Index
2127     int32_t                 iSources;                    // Number of sources
2128     PVPHAL_SURFACE          pSources[VPHAL_MAX_SOURCES]; // Array of sources
2129 
2130     Kdll_Procamp            Procamp;
2131     Kdll_Procamp            *pProcamp;
2132     PVPHAL_PROCAMP_PARAMS   pProcampParams;
2133 
2134     PRENDERHAL_L3_CACHE_SETTINGS pCacheSettings = nullptr;
2135 
2136     VPHAL_CSPACE            ColorSpace;     // Temporary colorspace
2137     PVPHAL_SURFACE          pTarget;        // Render target
2138     PVPHAL_SURFACE          pOutput;        // Compositing output
2139     int32_t                 index;          // Current source index
2140     bool                    bMultiplePhases;
2141     PVPHAL_RNDR_PERF_DATA   pPerfData;
2142 
2143     eStatus = MOS_STATUS_UNKNOWN;
2144 
2145     VPHAL_RENDER_FUNCTION_ENTER;
2146 
2147     VPHAL_RENDER_CHK_NULL(pcRenderParams);
2148     VPHAL_RENDER_CHK_NULL(m_pOsInterface);
2149     VPHAL_RENDER_CHK_NULL(m_pRenderHal);
2150     VPHAL_RENDER_ASSERT(m_pKernelDllState);
2151 
2152     // Increment Call ID (regardless of failure)
2153     m_iCallID++;
2154 
2155     pOsInterface = m_pOsInterface;
2156     pRenderHal   = m_pRenderHal;
2157     pPerfData    = GetPerfData();
2158 
2159     // Reset compositing sources
2160     iSources  = 0;
2161     iProcamp  = 0;
2162     pTarget   = pcRenderParams->pTarget[0];
2163     MOS_ZeroMemory(pSources, sizeof(pSources));
2164 
2165     // Reset reporting
2166     m_reporting->InitReportValue();
2167 
2168     // Reset states before rendering (clear allocations, get GSH allocation index
2169     //                                + any additional housekeeping)
2170     pOsInterface->pfnResetOsStates(pOsInterface);
2171     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnReset(pRenderHal));
2172     pOsInterface->pfnResetPerfBufferID(pOsInterface);   // reset once per frame
2173 
2174     // Configure cache settings for this render operation
2175     pCacheSettings      = &pRenderHal->L3CacheSettings;
2176     MOS_ZeroMemory(pCacheSettings, sizeof(*pCacheSettings));
2177     pCacheSettings->bOverride                  = true;
2178     pCacheSettings->bL3CachingEnabled          = m_SurfMemObjCtl.bL3CachingEnabled;
2179     if (pPerfData->L3SQCReg1Override.bEnabled)
2180     {
2181         pCacheSettings->bSqcReg1Override       = true;
2182         pCacheSettings->dwSqcReg1              = pPerfData->L3SQCReg1Override.uiVal;
2183     }
2184 
2185     if (pPerfData->L3CntlReg2Override.bEnabled)
2186     {
2187         pCacheSettings->bCntlReg2Override      = true;
2188         pCacheSettings->dwCntlReg2             = pPerfData->L3CntlReg2Override.uiVal;
2189     }
2190 
2191     if (pPerfData->L3CntlReg3Override.bEnabled)
2192     {
2193         pCacheSettings->bCntlReg3Override      = true;
2194         pCacheSettings->dwCntlReg3             = pPerfData->L3CntlReg3Override.uiVal;
2195     }
2196 
2197     if (pPerfData->L3LRA1RegOverride.bEnabled)
2198     {
2199         pCacheSettings->bLra1RegOverride       = true;
2200         pCacheSettings->dwLra1Reg              = pPerfData->L3LRA1RegOverride.uiVal;
2201     }
2202 
2203     if (pPerfData->L3CntlRegOverride.bEnabled)
2204     {
2205         pCacheSettings->bCntlRegOverride       = true;
2206         pCacheSettings->dwCntlReg              = pPerfData->L3CntlRegOverride.uiVal;
2207     }
2208 
2209     index = 0;
2210     while (iSources < (int)pcRenderParams->uSrcCount)
2211     {
2212         VPHAL_GET_SURFACE_INFO Info;
2213         PVPHAL_SURFACE         pSrc;    // Current source surface
2214 
2215         pSrc = pcRenderParams->pSrc[index++];
2216         if (pSrc == nullptr)
2217         {
2218             continue;
2219         }
2220 
2221         VPHAL_RENDER_ASSERT(!Mos_ResourceIsNull(&pSrc->OsResource));
2222 
2223         // Get resource information
2224         MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
2225 
2226         VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
2227             pOsInterface,
2228             &Info,
2229             pSrc));
2230 
2231         // Ensure the input is ready to be read
2232         pOsInterface->pfnSyncOnResource(
2233             pOsInterface,
2234             &pSrc->OsResource,
2235             pOsInterface->CurrentGpuContextOrdinal,
2236             false);
2237 
2238         // Field Weaving needs ref sample
2239         if (pSrc->bFieldWeaving && pSrc->pBwdRef)
2240         {
2241             MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
2242 
2243             VPHAL_RENDER_CHK_STATUS(VpHal_GetSurfaceInfo(
2244                 pOsInterface,
2245                 &Info,
2246                 pSrc->pBwdRef));
2247 
2248             // Ensure the input is ready to be read
2249             pOsInterface->pfnSyncOnResource(
2250                 pOsInterface,
2251                 &pSrc->pBwdRef->OsResource,
2252                 pOsInterface->CurrentGpuContextOrdinal,
2253                 false);
2254         }
2255 
2256         // Procamp
2257         pProcampParams = pSrc->pProcampParams;
2258         if (pProcampParams && pProcampParams->bEnabled)
2259         {
2260             pProcamp = &m_Procamp[iProcamp];
2261             Procamp.iProcampVersion = pProcamp->iProcampVersion;
2262             Procamp.bEnabled    =  true;
2263             Procamp.fBrightness =  pProcampParams->fBrightness;
2264             Procamp.fContrast   =  pProcampParams->fContrast  ;
2265             Procamp.fHue        =  pProcampParams->fHue       ;
2266             Procamp.fSaturation =  pProcampParams->fSaturation;
2267 
2268             // Update procamp version and values only if changed
2269             if (memcmp(pProcamp, &Procamp, sizeof(Procamp)))
2270             {
2271                 Procamp.iProcampVersion = m_iProcampVersion++;
2272                 *pProcamp = Procamp;
2273             }
2274 
2275             iProcamp++;
2276         }
2277 
2278         // Set sources for rendering
2279         pSources[iSources] = pSrc;
2280         iSources++;
2281     }
2282 
2283     // Sync on Render Target(s)
2284     index = 0;
2285     do
2286     {
2287         pOsInterface->pfnSyncOnResource(
2288             pOsInterface,
2289             &pcRenderParams->pTarget[index]->OsResource,
2290             pOsInterface->CurrentGpuContextOrdinal,
2291             true);
2292         index++;
2293     } while (index < (int32_t)pcRenderParams->uDstCount);
2294 
2295     // Sync Render Target with Overlay Context
2296     if (pTarget->bOverlay)
2297     {
2298         pOsInterface->pfnSyncOnOverlayResource(
2299             pOsInterface,
2300             &pTarget->OsResource,
2301             pOsInterface->CurrentGpuContextOrdinal);
2302     }
2303 
2304     // Check max number sources
2305     if (iSources > VPHAL_MAX_SOURCES)
2306     {
2307         VPHAL_RENDER_ASSERTMESSAGE("Invalid number of samples.");
2308         goto finish;
2309     }
2310 
2311     // Determine cspace for compositing
2312     ColorSpace = PrepareCSC(pcRenderParams,
2313                             pSources,
2314                             iSources);
2315 
2316     bMultiplePhases = PreparePhases(pcRenderParams,
2317                                     pSources,
2318                                     iSources);
2319     if (!bMultiplePhases)
2320     {
2321         pOutput = pTarget;
2322     }
2323     else
2324     {
2325         pOutput = &m_Intermediate;
2326         pOutput->ColorSpace = ColorSpace;
2327         m_Intermediate2.ColorSpace = ColorSpace;
2328 
2329         // Set AYUV or ARGB output depending on intermediate cspace
2330         if (KernelDll_IsCspace(ColorSpace, CSpace_RGB))
2331         {
2332             pOutput->Format = Format_A8R8G8B8;
2333             m_Intermediate2.Format = Format_A8R8G8B8;
2334         }
2335         else
2336         {
2337             pOutput->Format = Format_AYUV;
2338             m_Intermediate2.Format = Format_AYUV;
2339         }
2340     }
2341 
2342     VPHAL_RENDER_CHK_STATUS(RenderMultiPhase(pcRenderParams, pSources, iSources, pOutput));
2343 
2344     // Last constriction phase
2345     if (pcRenderParams->pConstriction)
2346     {
2347         VPHAL_COMPOSITE_PARAMS  CompositeParams;
2348 
2349         // Prepare compositing structure
2350         ResetCompParams(&CompositeParams);
2351 
2352         // set additional render target
2353         if (pcRenderParams->uDstCount == 2)
2354         {
2355             CompositeParams.uTargetCount    = pcRenderParams->uDstCount;
2356             CompositeParams.Target[1]       = *pcRenderParams->pTarget[1];
2357         }
2358 
2359         pTarget->SurfType = SURF_OUT_RENDERTARGET;
2360 
2361         // Prepare temporary output for final upscaling
2362         pOutput->ScalingMode = VPHAL_SCALING_BILINEAR;
2363         pOutput->rcSrc       = *(pcRenderParams->pConstriction);
2364         pOutput->rcDst       = pTarget->rcDst;
2365 
2366         AddCompLayer(&CompositeParams, pOutput);
2367 
2368         AddCompTarget(&CompositeParams, pTarget);
2369 
2370         // Reset states before rendering (clear allocations, get GSH allocation index
2371         //                                + any additional housekeeping)
2372         pOsInterface->pfnResetOsStates(pOsInterface);
2373         VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnReset(pRenderHal));
2374 
2375         // Raise the flag to indicate the last comp render phase
2376         m_bLastPhase = true;
2377 
2378         // Perform compositing operation
2379         VPHAL_RENDER_CHK_STATUS(RenderPhase(&CompositeParams));
2380     }
2381 
2382 finish:
2383     if (pCacheSettings)
2384     {
2385         MOS_ZeroMemory(pCacheSettings, sizeof(*pCacheSettings));
2386     }
2387     // Reset Slice Shutdown Mode
2388     if (pRenderHal)
2389     {
2390         pRenderHal->pfnSetSliceShutdownMode(pRenderHal, false);
2391     }
2392 
2393     VPHAL_RENDER_EXITMESSAGE("eStatus %d", eStatus);
2394 
2395     return eStatus;
2396 }
2397 
2398 //!
2399 //! \brief    Set Composite Scaling mode
2400 //! \param    [in,out] pSource
2401 //!           Pointer to Source Surface
2402 //! \param    [in] uSourceCount
2403 //!           Count of Source Surfaces
2404 //! \return   void
2405 //!
SetScalingMode(PVPHAL_SURFACE pSource,uint32_t uSourceCount)2406 void CompositeState::SetScalingMode(
2407     PVPHAL_SURFACE          pSource,
2408     uint32_t                uSourceCount)
2409 {
2410     float   fScaleX, fScaleY;
2411 
2412     VPHAL_RENDER_ASSERT(pSource);
2413 
2414     // Default mode
2415     pSource->bIEF = false;
2416 
2417     // Source rectangle is pre-rotated, destination rectangle is post-rotated.
2418     if (pSource->Rotation == VPHAL_ROTATION_IDENTITY    ||
2419         pSource->Rotation == VPHAL_ROTATION_180         ||
2420         pSource->Rotation == VPHAL_MIRROR_HORIZONTAL    ||
2421         pSource->Rotation == VPHAL_MIRROR_VERTICAL)
2422     {
2423         fScaleX      = (float)(pSource->rcDst.right  - pSource->rcDst.left) /
2424                        (float)(pSource->rcSrc.right  - pSource->rcSrc.left);
2425         fScaleY      = (float)(pSource->rcDst.bottom - pSource->rcDst.top) /
2426                        (float)(pSource->rcSrc.bottom - pSource->rcSrc.top);
2427     }
2428     else
2429     {
2430         // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 ||
2431         // VPHAL_ROTATE_90_MIRROR_HORIZONTAL || VPHAL_ROTATE_90_MIRROR_VERTICAL
2432         fScaleX      = (float)(pSource->rcDst.right  - pSource->rcDst.left) /
2433                        (float)(pSource->rcSrc.bottom  - pSource->rcSrc.top);
2434         fScaleY      = (float)(pSource->rcDst.bottom - pSource->rcDst.top) /
2435                        (float)(pSource->rcSrc.right - pSource->rcSrc.left);
2436     }
2437 
2438     // Enable AVS/IEF for primary video only
2439     // AVS is supported only for y-scaling ratios > 0.0625
2440     // Starting from IVB, AVS is supported only for x-scaling ratios > 0.0625
2441     if (pSource->ScalingMode == VPHAL_SCALING_AVS   &&
2442         fScaleX > 0.0625f                           &&
2443         fScaleY > 0.0625f)
2444     {
2445         // Interlaced content - Disable AVS for BOB implementation
2446         if (IsBobDiEnabled(pSource))
2447         {
2448             pSource->ScalingMode = VPHAL_SCALING_BILINEAR;
2449         }
2450         // Enable IEF
2451         else if (pSource->pIEFParams             &&
2452                  pSource->pIEFParams->bEnabled   &&
2453                  pSource->pIEFParams->fIEFFactor > 0.0f)
2454         {
2455             pSource->bIEF = true;
2456         }
2457         // If IEF is disabled and Scaling Ratios are 1x, use 3D Nearest
2458         // for better performance (applicable for Primary-only case)
2459         // Don't fall back to bilinear scaling if Chroma up sampling is needed
2460         else if (fScaleX == 1.0F   &&
2461                  fScaleY == 1.0F   &&
2462                  uSourceCount == 1 &&
2463                  !m_bChromaUpSampling)
2464         {
2465             pSource->ScalingMode = VPHAL_SCALING_BILINEAR;
2466         }
2467     }
2468     else
2469     {
2470         pSource->ScalingMode = VPHAL_SCALING_BILINEAR;
2471     }
2472 
2473     // Fix Interlace Scaling Hang issue, switch avs to bilinear scaling because kernels
2474     // are using 3d samplers for unaligned cases
2475     if (pSource->bInterlacedScaling                                                 &&
2476         (!MOS_IS_ALIGNED(MOS_MIN(pSource->dwWidth, (uint32_t)pSource->rcSrc.right), 4) ||
2477          !MOS_IS_ALIGNED(pSource->dwHeight, 4)))
2478     {
2479         pSource->ScalingMode = VPHAL_SCALING_BILINEAR;
2480     }
2481 
2482     // Fix GPU Hang on EHL, since EHL has no AVS sampler
2483     if (MEDIA_IS_SKU(m_pSkuTable, FtrDisableVEBoxFeatures))
2484     {
2485         pSource->ScalingMode = VPHAL_SCALING_BILINEAR;
2486     }
2487 
2488     // WA for multilayer P010 AVS+3D one single pass corruption hw issue
2489     if (uSourceCount > 1 &&
2490         pSource->Format == Format_P010)
2491     {
2492         pSource->ScalingMode = VPHAL_SCALING_BILINEAR;
2493     }
2494 
2495 }
2496 
2497 //!
2498 //! \brief    Initialize Composite Rendering data
2499 //! \details  Initialize Composite Rendering data, set output area, number of blocks,
2500 //!           Sources, constriction parameters, rendering states, etc.
2501 //! \param    [in] pCompParams
2502 //!           Pointer to Composite parameters
2503 //! \param    [out] pRenderingData
2504 //!           Pointer to Composite Rendering data
2505 //! \return   MOS_STATUS
2506 //!
RenderInit(PVPHAL_COMPOSITE_PARAMS pCompParams,PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)2507 MOS_STATUS CompositeState::RenderInit(
2508     PVPHAL_COMPOSITE_PARAMS         pCompParams,
2509     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)
2510 {
2511     PRENDERHAL_INTERFACE    pRenderHal;
2512     RECT                    AlignedRect;
2513     uint32_t                uiMediaWalkerBlockSize;
2514     PRECT                   pDst;
2515     MOS_STATUS              eStatus = MOS_STATUS_SUCCESS;
2516 
2517     VPHAL_RENDER_CHK_NULL(m_pRenderHal);
2518     VPHAL_RENDER_CHK_NULL(pCompParams);
2519     VPHAL_RENDER_CHK_NULL(pRenderingData);
2520 
2521     pRenderHal   = m_pRenderHal;
2522 
2523     //============================
2524     // Set rendering data
2525     //============================
2526     MOS_ZeroMemory(pRenderingData, sizeof(VPHAL_RENDERING_DATA_COMPOSITE));
2527 
2528     // Set output area
2529     if (pCompParams->uTargetCount == 2)
2530     {
2531         // Output rectangle based on non-rotated target in case of dual output
2532         pRenderingData->BbArgs.rcOutput = pCompParams->Target[1].rcDst;
2533         pRenderingData->pTarget[1]      = &pCompParams->Target[1];
2534     }
2535     else
2536     {
2537         pRenderingData->BbArgs.rcOutput = pCompParams->Target[0].rcDst;
2538     }
2539 
2540     pDst = &(pRenderingData->BbArgs.rcOutput);
2541 
2542     if (m_bFtrMediaWalker)
2543     {
2544         uiMediaWalkerBlockSize = pRenderHal->pHwSizes->dwSizeMediaWalkerBlock;
2545     }
2546     else
2547     {
2548         uiMediaWalkerBlockSize = VPHAL_COMP_BLOCK_WIDTH;
2549     }
2550 
2551     // Calculate aligned output area in order to determine the total # blocks to process
2552     // in case of non-16x16 aligned target
2553     AlignedRect         = *pDst;
2554     AlignedRect.right  += uiMediaWalkerBlockSize  - 1;
2555     AlignedRect.bottom += uiMediaWalkerBlockSize - 1;
2556     AlignedRect.left   -= AlignedRect.left   % uiMediaWalkerBlockSize;
2557     AlignedRect.top    -= AlignedRect.top    % uiMediaWalkerBlockSize;
2558     AlignedRect.right  -= AlignedRect.right  % uiMediaWalkerBlockSize;
2559     AlignedRect.bottom -= AlignedRect.bottom % uiMediaWalkerBlockSize;
2560 
2561     // Set number of blocks
2562     pRenderingData->iBlocksX =
2563         (AlignedRect.right  - AlignedRect.left) / uiMediaWalkerBlockSize;
2564     pRenderingData->iBlocksY =
2565         (AlignedRect.bottom - AlignedRect.top ) / uiMediaWalkerBlockSize;
2566 
2567     // Set sources
2568     pRenderingData->iLayers                = 0;
2569     pRenderingData->pTarget[0]             = &pCompParams->Target[0];
2570     pRenderingData->pColorFill             = pCompParams->pColorFillParams;
2571     pRenderingData->pCompAlpha             = pCompParams->pCompAlpha;
2572 
2573     // Set constriction parameters
2574     pRenderingData->pConstriction = pCompParams->pConstriction;
2575     if (pCompParams->pConstriction)
2576     {
2577         pRenderingData->ConstrictionOriginX = pDst->left;
2578         pRenderingData->ConstrictionOriginY = pDst->top;
2579         pRenderingData->fConstrictionStepX  = (pDst->right - pDst->left) * 1.0f /
2580                                                pCompParams->pConstriction->right;
2581         pRenderingData->fConstrictionStepY  = (pDst->bottom - pDst->top) * 1.0f /
2582                                                pCompParams->pConstriction->bottom;
2583     }
2584     else
2585     {
2586         pRenderingData->ConstrictionOriginX = 0;
2587         pRenderingData->ConstrictionOriginY = 0;
2588         pRenderingData->fConstrictionStepX  = 1.0f;
2589         pRenderingData->fConstrictionStepY  = 1.0f;
2590     }
2591 
2592     // Set AVS and 8x8 table from renderer
2593     pRenderingData->pAvsParams             = &m_AvsParameters;
2594 
2595     // Init extension data to nullptr
2596     pRenderingData->pExtensionData         = nullptr;
2597 
2598     // Initialize rendering states
2599     pRenderingData->Static                 = g_cInit_MEDIA_OBJECT_KA2_STATIC_DATA;
2600     pRenderingData->Inline                 = g_cInit_MEDIA_OBJECT_KA2_INLINE_DATA;
2601     pRenderingData->WalkerStatic           = g_cInit_MEDIA_WALKER_KA2_STATIC_DATA;
2602     pRenderingData->DPFCStatic             = {0};
2603     // By default, alpha is calculated in PartBlend kernel
2604     pRenderingData->bAlphaCalculateEnable = false;
2605 
2606     // Reset Sampler Params
2607     MOS_ZeroMemory(
2608         pRenderingData->SamplerStateParams,
2609         sizeof(pRenderingData->SamplerStateParams));
2610 
2611 finish:
2612     return eStatus;
2613 }
2614 
2615 //!
2616 //! \brief    Clean Composite Rendering data
2617 //! \param    [in] pRenderingData
2618 //!           Pointer to Composite Rendering data
2619 //! \return   MOS_STATUS
2620 //!
CleanRenderingData(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)2621 void CompositeState::CleanRenderingData(
2622     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)
2623 {
2624     MOS_UNUSED(pRenderingData);
2625 }
2626 
2627 //!
2628 //! \brief    Get Binding Table Index associated with a given source for composite
2629 //! \param    [in] pSource
2630 //!           Pointer to Source Surface
2631 //! \param    [out] pBindingIndex
2632 //!           Pointer to Binding table index
2633 //! \return   MOS_STATUS
2634 //!           Return MOS_STATUS_SUCCESS if successful, otherwise MOS_STATUS_UNKNOWN
2635 //!
GetBindingIndex(PVPHAL_SURFACE pSource,int32_t * pBindingIndex)2636 static MOS_STATUS GetBindingIndex(
2637     PVPHAL_SURFACE          pSource,
2638     int32_t*                pBindingIndex)
2639 {
2640     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2641 
2642     if (pSource != nullptr && pBindingIndex != nullptr)
2643     {
2644         if (pSource->SurfType == SURF_OUT_RENDERTARGET)
2645         {
2646             *pBindingIndex = g_cBindingTableIndex[0];
2647         }
2648         else if (pSource->iLayerID >= 0 &&
2649                  pSource->iLayerID < VPHAL_COMP_MAX_LAYERS)
2650         {
2651             *pBindingIndex = g_cBindingTableIndex[pSource->iLayerID + 1];
2652         }
2653         else
2654         {
2655             eStatus = MOS_STATUS_UNKNOWN;
2656         }
2657     }
2658     else
2659     {
2660         eStatus = MOS_STATUS_UNKNOWN;
2661     }
2662 
2663     return eStatus;
2664 }
2665 
2666 //!
2667 //! \brief    Get Sampler Index associated with a surface state for composite
2668 //! \param    [in] pSurface
2669 //!           point to input Surface
2670 //! \param    [in] pEntry
2671 //!           Pointer to Surface state
2672 //! \param    [out] pSamplerIndex
2673 //!           Pointer to Sampler Index
2674 //! \param    [out] pSamplerType
2675 //!           Pointer to Sampler Type
2676 //! \return   MOS_STATUS
2677 //!           Return MOS_STATUS_SUCCESS if successful, otherwise MOS_STATUS_UNKNOWN
2678 //!
GetSamplerIndex(PVPHAL_SURFACE pSurface,PRENDERHAL_SURFACE_STATE_ENTRY pEntry,int32_t * pSamplerIndex,PMHW_SAMPLER_TYPE pSamplerType)2679 MOS_STATUS CompositeState::GetSamplerIndex(
2680     PVPHAL_SURFACE                      pSurface,
2681     PRENDERHAL_SURFACE_STATE_ENTRY      pEntry,
2682     int32_t*                            pSamplerIndex,
2683     PMHW_SAMPLER_TYPE                   pSamplerType)
2684 {
2685     MOS_UNUSED(pSurface);
2686 
2687     if (pSamplerIndex == nullptr || pSamplerType == nullptr || pEntry == nullptr)
2688     {
2689         VPHAL_RENDER_ASSERTMESSAGE(" Null pointer.");
2690         return MOS_STATUS_NULL_POINTER;
2691     }
2692 
2693     // AVS
2694     if (pEntry->bAVS)
2695     {
2696         *pSamplerType = MHW_SAMPLER_TYPE_AVS;
2697 
2698         if (pEntry->YUVPlane == MHW_U_PLANE)
2699         {
2700             *pSamplerIndex = VPHAL_SAMPLER_8x8_AVS_U;
2701         }
2702         else if (pEntry->YUVPlane == MHW_V_PLANE)
2703         {
2704             *pSamplerIndex = VPHAL_SAMPLER_8x8_AVS_V;
2705         }
2706         else
2707         {
2708             *pSamplerIndex = VPHAL_SAMPLER_8x8_AVS_Y;
2709         }
2710     }
2711     // Non-AVS
2712     else
2713     {
2714         *pSamplerType  = MHW_SAMPLER_TYPE_3D;
2715 
2716         if (pEntry->YUVPlane == MHW_U_PLANE)
2717         {
2718             *pSamplerIndex = VPHAL_SAMPLER_U;
2719         }
2720         else if (pEntry->YUVPlane == MHW_V_PLANE)
2721         {
2722             *pSamplerIndex = VPHAL_SAMPLER_V;
2723         }
2724         else
2725         {
2726             *pSamplerIndex = VPHAL_SAMPLER_Y;
2727         }
2728     }
2729 
2730     return MOS_STATUS_SUCCESS;
2731 }
2732 
2733 //!
2734 //! \brief    Set Surface Parameters
2735 //! \details  Set Surface Parameters, set flags for RT, set surface type based on scaling
2736 //!           mode, set interlacing flags, etc.
2737 //! \param    [in,out] pSource
2738 //!           Pointer to Source Surface
2739 //! \param    [out] pSurfaceParams
2740 //!           Pointer to Surface Parameters
2741 //! \return   void
2742 //!
SetSurfaceParams(PVPHAL_SURFACE pSource,PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams)2743 void CompositeState::SetSurfaceParams(
2744     PVPHAL_SURFACE                  pSource,
2745     PRENDERHAL_SURFACE_STATE_PARAMS pSurfaceParams)
2746 {
2747     // Render target or private surface
2748     if (pSource->SurfType == SURF_OUT_RENDERTARGET)
2749     {
2750         // Disable AVS, IEF
2751         pSource->ScalingMode = VPHAL_SCALING_BILINEAR;
2752         pSource->bIEF        = false;
2753 
2754         // Set flags for RT
2755         pSurfaceParams->bRenderTarget    = true;
2756         pSurfaceParams->bWidthInDword_Y  = true;
2757         pSurfaceParams->bWidthInDword_UV = true;
2758         pSurfaceParams->Boundary         = RENDERHAL_SS_BOUNDARY_DSTRECT;
2759     }
2760     // other surfaces
2761     else
2762     {
2763         pSurfaceParams->bRenderTarget    = false;
2764         pSurfaceParams->bWidthInDword_Y  = false;
2765         pSurfaceParams->bWidthInDword_UV = false;
2766         pSurfaceParams->Boundary         = RENDERHAL_SS_BOUNDARY_SRCRECT;
2767     }
2768 
2769     // Set surface type based on scaling mode
2770     if (pSource->ScalingMode == VPHAL_SCALING_AVS)
2771     {
2772         pSurfaceParams->Type = m_pRenderHal->SurfaceTypeAdvanced;
2773         pSurfaceParams->bAVS = true;
2774     }
2775     else
2776     {
2777         pSurfaceParams->Type = m_pRenderHal->SurfaceTypeDefault;
2778         pSurfaceParams->bAVS = false;
2779     }
2780 
2781     // Set interlacing flags
2782     switch (pSource->SampleType)
2783     {
2784         case SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD:
2785         case SAMPLE_INTERLEAVED_ODD_FIRST_TOP_FIELD:
2786             pSurfaceParams->bVertStride     = true;
2787             pSurfaceParams->bVertStrideOffs = 0;
2788             break;
2789         case SAMPLE_INTERLEAVED_EVEN_FIRST_BOTTOM_FIELD:
2790         case SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD:
2791             pSurfaceParams->bVertStride     = true;
2792             pSurfaceParams->bVertStrideOffs = 1;
2793             break;
2794         default:
2795             pSurfaceParams->bVertStride     = false;
2796             pSurfaceParams->bVertStrideOffs = 0;
2797             break;
2798     }
2799 
2800     if (pSource->iLayerID && IsNV12SamplerLumakeyNeeded(pSource, m_pRenderHal))
2801     {
2802         pSurfaceParams->b2PlaneNV12NeededByKernel = true;
2803     }
2804 
2805      VPHAL_RENDER_NORMALMESSAGE("SurfaceTYpe %d, bAVS %d, b2PlaneNV12NeededByKernel %d",
2806         pSurfaceParams->Type,
2807         pSurfaceParams->bAVS,
2808         pSurfaceParams->b2PlaneNV12NeededByKernel);
2809 }
2810 
2811 //!
2812 //! \brief    calculate the Horiz Gap and Vert Gap with different sample location
2813 //! \param    [in] pTarget
2814 //!           Pointer to Source Surface
2815 //! \Param    [in] pHorzGap
2816 //!           Pointer to Horzontal Gap
2817 //! \Param    [in] pVertGap
2818 //!           Pointer to Vertital Gap
2819 //!
GetOffsetChromasiting(PVPHAL_SURFACE pSource,float * pHorizGap,float * pVertGap)2820 static void GetOffsetChromasiting(
2821     PVPHAL_SURFACE                      pSource,
2822     float*                              pHorizGap,
2823     float*                              pVertGap
2824     )
2825 {
2826     float  HorizGap = 0.0f;
2827     float  VertGap  = 0.0f;
2828 
2829     VPHAL_RENDER_CHK_NULL_NO_STATUS(pSource);
2830 
2831     // If there is no DDI setting, we use the Horizontal Left Vertical Center as default for PL2 surface.
2832     if (pSource->ChromaSiting == CHROMA_SITING_NONE)
2833     {
2834         // PL2 default to Horizontal Left, Vertical Center
2835         if (IS_PL2_FORMAT(pSource->Format) || IS_PL2_FORMAT_UnAligned(pSource->Format))
2836         {
2837             VertGap = (float)(0.5f / pSource->dwHeight);
2838         }
2839     }
2840     else
2841     {
2842         // PL2, 6 positions are available
2843         if (IS_PL2_FORMAT(pSource->Format) || IS_PL2_FORMAT_UnAligned(pSource->Format))
2844         {
2845             // Horizontal Left
2846             if (pSource->ChromaSiting & CHROMA_SITING_HORZ_LEFT)
2847             {
2848                 if (pSource->ChromaSiting & CHROMA_SITING_VERT_CENTER)
2849                 {
2850                     VertGap = (float)(0.5f / pSource->dwHeight);
2851                 }
2852                 else if (pSource->ChromaSiting & CHROMA_SITING_VERT_BOTTOM)
2853                 {
2854                     VertGap = (float)(1.0f / pSource->dwHeight);
2855                 }
2856             }
2857             // Horizontal Center
2858             else if (pSource->ChromaSiting & CHROMA_SITING_HORZ_CENTER)
2859             {
2860                 HorizGap = (float)(0.5f / pSource->dwWidth);
2861                 if (pSource->ChromaSiting & CHROMA_SITING_VERT_CENTER)
2862                 {
2863                     VertGap = (float)(0.5f / pSource->dwHeight);
2864                 }
2865                 else if (pSource->ChromaSiting & CHROMA_SITING_VERT_BOTTOM)
2866                 {
2867                     VertGap = (float)(1.0f / pSource->dwHeight);
2868                 }
2869             }
2870         }
2871         else if (IS_PA_FORMAT(pSource->Format))
2872         {
2873             // For PA surface, only (H Left, V Top) and (H Center, V top) are needed.
2874             if (pSource->ChromaSiting & (CHROMA_SITING_HORZ_CENTER))
2875             {
2876                 HorizGap = (float)(0.5f / pSource->dwWidth);
2877             }
2878         }
2879     }
2880     *pVertGap = VertGap;
2881     *pHorizGap = HorizGap;
2882 finish:
2883     return;
2884 }
2885 
2886 //!
2887 //! \brief    Set Sampler AVS parameters
2888 //! \param    [in] pRenderingData
2889 //!           pointer to render data
2890 //! \param    [in] pSource
2891 //!           pointer to source surface
2892 //! \param    [in] pSurfaceEntry
2893 //!           pointer to source state entry
2894 //! \param    [out] pSamplerStateParams
2895 //!           pointer to Sampler state params
2896 //! \param    [in] fScaleX
2897 //!           width scaling ratio
2898 //! \param    [in] fScaleY
2899 //!           height scaling ratio
2900 //! \return   MOS_STATUS
2901 //!
SetSamplerAvsParams(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,PVPHAL_SURFACE pSource,PRENDERHAL_SURFACE_STATE_ENTRY pSurfaceEntry,PMHW_SAMPLER_STATE_PARAM pSamplerStateParams,float fScaleX,float fScaleY)2902 MOS_STATUS CompositeState::SetSamplerAvsParams(
2903     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,
2904     PVPHAL_SURFACE                  pSource,
2905     PRENDERHAL_SURFACE_STATE_ENTRY  pSurfaceEntry,
2906     PMHW_SAMPLER_STATE_PARAM        pSamplerStateParams,
2907     float                           fScaleX,
2908     float                           fScaleY)
2909 {
2910     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2911 
2912     pSamplerStateParams->Avs.bEnableAVS     = true;
2913     // Default values from g_cInit_SAMPLER_STATE_8x8_GX
2914     pSamplerStateParams->Avs.WeakEdgeThr    = DETAIL_WEAK_EDGE_THRESHOLD;
2915     pSamplerStateParams->Avs.StrongEdgeThr  = DETAIL_STRONG_EDGE_THRESHOLD;
2916     pSamplerStateParams->Avs.StrongEdgeWght = DETAIL_STRONG_EDGE_WEIGHT;
2917     pSamplerStateParams->Avs.RegularWght    = DETAIL_REGULAR_EDGE_WEIGHT;
2918     pSamplerStateParams->Avs.NonEdgeWght    = DETAIL_NON_EDGE_WEIGHT;
2919 
2920     pSamplerStateParams->Avs.pMhwSamplerAvsTableParam = &m_mhwSamplerAvsTableParam;
2921 
2922     // When primary surface needs chroma upsampling,
2923     // force to use polyphase coefficients for 1x scaling for better quality
2924     pRenderingData->pAvsParams->bForcePolyPhaseCoefs =
2925         m_bChromaUpSampling;
2926 
2927     // Setup IEF parameters for generic or luma planes (no need to setup chroma planes)
2928     if (pSource->pIEFParams &&
2929         pSource->bIEF &&
2930         pSurfaceEntry->YUVPlane != MHW_U_PLANE &&
2931         pSurfaceEntry->YUVPlane != MHW_V_PLANE &&
2932         (!m_bFallbackIefPatch))                                 // if m_bFallbackIefPatch is on, fallback IEF patch from AVS to SFC
2933     {
2934         Ief ief(pSource);
2935 
2936         eStatus = ief.SetHwState(pSamplerStateParams);
2937         if (eStatus != MOS_STATUS_SUCCESS)
2938         {
2939             VPHAL_RENDER_ASSERTMESSAGE("set Sampler IEF parameter failed.");
2940         }
2941     }
2942 
2943     eStatus = SetSamplerAvsTableParam(
2944         m_pRenderHal,
2945         pSamplerStateParams,
2946         pRenderingData->pAvsParams,
2947         pSource->Format,
2948         fScaleX,
2949         fScaleY,
2950         MHW_CHROMA_SITING_HORZ_LEFT | MHW_CHROMA_SITING_VERT_TOP);
2951 
2952     return eStatus;
2953 }
2954 
2955 //!
2956 //! \brief    Calculate crop factor
2957 //! \param    [in] iLayer
2958 //!           layer index
2959 //! \param    [in] pRenderingData
2960 //!           pointer to render data
2961 //! \param    [out] pfCropX
2962 //!           crop factor
2963 //! \param    [out] pfCropY
2964 //!           crop factor
2965 //! \return   MOS_STATUS
2966 //!
CalculateCropParams(int32_t iLayer,PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,float * pfCropX,float * pfCropY)2967 MOS_STATUS CompositeState::CalculateCropParams(
2968     int32_t                         iLayer,
2969     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,
2970     float*                          pfCropX,
2971     float*                          pfCropY)
2972 {
2973     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2974 
2975     MOS_UNUSED(iLayer);
2976     MOS_UNUSED(pRenderingData);
2977 
2978     VPHAL_RENDER_CHK_NULL_RETURN(pfCropX);
2979     VPHAL_RENDER_CHK_NULL_RETURN(pfCropY);
2980 
2981     *pfCropX = 0.0;
2982     *pfCropY = 0.0;
2983 
2984     return eStatus;
2985 }
2986 
2987 //!
2988 //! \brief    Set Composite Layer
2989 //! \details  Set Composite Layer, including setup surface state and binding table, setup
2990 //!           lumakey parameters, setup samplers, setup alpha blending parameters, adjust
2991 //!           geometry for BOB DI, normalize source co-ordinates, set curbe and inline
2992 //!           data, and etc
2993 //! \param    [in] pRenderingData
2994 //!           Pointer to Composite Rendering data
2995 //! \param    [in] pSource
2996 //!           Pointer to Source Surface
2997 //! \param    [in] iLayerIdInCompParams
2998 //!           Index of pSource in pCompParams
2999 //! \param    [in,out] pCompParams
3000 //!           Pointer to Composite parameters
3001 //! \return   int32_t
3002 //!           Return 1 if set layer successful, otherwise -1
3003 //!
SetLayer(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,PVPHAL_SURFACE pSource,int iLayerIdInCompParams,PVPHAL_COMPOSITE_PARAMS pCompParams)3004 int32_t CompositeState::SetLayer(
3005     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,
3006     PVPHAL_SURFACE                  pSource,
3007     int                             iLayerIdInCompParams,
3008     PVPHAL_COMPOSITE_PARAMS         pCompParams)
3009 {
3010     // Result
3011     MOS_STATUS                          eStatus;
3012     PRENDERHAL_SURFACE                  pRenderHalSurfaceSrc = nullptr;         // Pointer to Source RenderHal Surface related to VPHAL Surface
3013     PRENDERHAL_SURFACE                  pRenderHalSurfaceSrcField = nullptr;    // Pointer to Source RenderHal Surface (FieldWeaving) related to VPHAL Surface
3014 
3015     // States
3016     PRENDERHAL_INTERFACE                pRenderHal;
3017     int32_t                             iLayer; // The index of pSource in pRenderingData->pLayers.
3018     MEDIA_OBJECT_KA2_STATIC_DATA        *pStatic;
3019     MEDIA_OBJECT_KA2_INLINE_DATA        *pInline;
3020     MEDIA_DP_FC_STATIC_DATA             *pDPStatic;
3021     // Surface states
3022     int32_t                             iSurfaceEntries, i, iSurfaceEntries2;
3023     PRENDERHAL_SURFACE_STATE_ENTRY      pSurfaceEntries[MHW_MAX_SURFACE_PLANES];
3024     PRENDERHAL_SURFACE_STATE_ENTRY      pSurfaceEntries2[MHW_MAX_SURFACE_PLANES];
3025     PRENDERHAL_SURFACE_STATE_ENTRY      pSurfaceEntry;
3026     RENDERHAL_SURFACE_STATE_PARAMS      SurfaceParams, SurfaceParams2;
3027     int32_t                             iBTentry;
3028 
3029     // Sampler states
3030     int32_t                             iSamplerID;     // Sampler ID
3031     MHW_SAMPLER_TYPE                    SamplerType;    // Sampler Type
3032     PMHW_SAMPLER_STATE_PARAM            pSamplerStateParams;
3033     VPHAL_SCALING_MODE                  ScalingMode;
3034 
3035     // Constant alpha
3036     uint16_t                            wAlpha;         // Constant Alpha (8.8)
3037 
3038     // Geometry related parameters
3039     uint32_t    dwSurfStateWd, dwSurfStateHt;       // Surface Width Height as programmed in SS
3040     uint32_t    dwDestRectWidth, dwDestRectHeight;  // Target rectangle Width Height
3041     float       fOffsetY, fOffsetX;                 // x,y Sr offset
3042     float       fShiftX , fShiftY;                  // x,y Dst shift + Sampler BOB adj
3043     float       fDiScaleY;                          // BOB scaling factor for Y
3044     float       fScaleX, fScaleY;                   // x,y scaling factor
3045     float       fStepX , fStepY;                    // x,y scaling steps
3046     float       fOriginX, fOriginY;                 // x,y layer origin
3047     PRECT       pTargetRect;                        // Clipping rectangle (RT)
3048     RECT        DestRect;                           // Clipped dest rectangle
3049     int32_t     iResult = 0;                        // Default result = 0 (don't render the current plane)
3050     float       fHorizgap, fVertgap;                // horizontal gap and vertical gap: based on Sampler need
3051     uint32_t    dwLow, dwHigh;
3052     bool        bForceNearestForUV = false;
3053 
3054     // cropping
3055     float       fCropX, fCropY;
3056 
3057     // Temp variable for iScaling/Field Weaving
3058     PVPHAL_SURFACE               pTempSurf;
3059 
3060     if (nullptr == pRenderingData || nullptr == pSource || nullptr == pCompParams ||
3061         iLayerIdInCompParams < 0 || iLayerIdInCompParams >= (int)pCompParams->uSourceCount)
3062     {
3063         VPHAL_RENDER_ASSERTMESSAGE("invalid input parameters");
3064         iResult = -1;
3065         goto finish;
3066     }
3067 
3068     pRenderHalSurfaceSrc        = &pCompParams->RenderHalSurfaceSrc[iLayerIdInCompParams];
3069     pRenderHalSurfaceSrcField   = &pCompParams->RenderHalSurfaceSrcField[iLayerIdInCompParams];
3070 
3071     ScalingMode = pSource->ScalingMode;
3072 
3073     // init surface parameters
3074     MOS_ZeroMemory(&SurfaceParams, sizeof(SurfaceParams));
3075     MOS_ZeroMemory(&SurfaceParams2, sizeof(SurfaceParams2));
3076     pTempSurf   = nullptr;
3077 
3078     // Init x,y Sr offset/Dst shift.
3079     fOffsetX = 0;
3080     fOffsetY = 0;
3081     fShiftX  = 0;
3082     fShiftY  = 0;
3083 
3084     // Initialize States
3085     pRenderHal   = m_pRenderHal;
3086     iLayer       = pRenderingData->iLayers;
3087     if(m_bFtrMediaWalker)
3088     {
3089         pStatic      = (MEDIA_OBJECT_KA2_STATIC_DATA*)&pRenderingData->WalkerStatic;
3090     }
3091     else
3092     {
3093         pStatic      = &pRenderingData->Static;
3094     }
3095     pDPStatic = &pRenderingData->DPFCStatic;
3096 
3097     pInline      = &pRenderingData->Inline;
3098 
3099     // Set the default alpha value to 0 for Android platform
3100     // According to the Partial Blending algorithm, if the default colorfill_a is set to 255, the output alpha value will be 0xFE or 0xFF.
3101     // It means the padding area of top layer always be opaqued. To reduce the code change risk, modify it only for Android platform.
3102     // Need follow-up on formal solution.
3103 #if ANDROID
3104     wAlpha = 0;
3105 #else
3106     wAlpha = 255;
3107 #endif
3108 
3109     // set destination width and height
3110     if (pRenderingData->pTarget[1] == nullptr)
3111     {
3112         dwDestRectWidth  = pRenderingData->pTarget[0]->dwWidth;
3113         dwDestRectHeight = pRenderingData->pTarget[0]->dwHeight;
3114     }
3115     else
3116     {
3117         // destination width and height base on non-rotated
3118         dwDestRectWidth  = pRenderingData->pTarget[1]->dwWidth;
3119         dwDestRectHeight = pRenderingData->pTarget[1]->dwHeight;
3120     }
3121 
3122     // Source rectangle is pre-rotated, destination rectangle is post-rotated.
3123     if (pSource->Rotation == VPHAL_ROTATION_IDENTITY    ||
3124         pSource->Rotation == VPHAL_ROTATION_180         ||
3125         pSource->Rotation == VPHAL_MIRROR_HORIZONTAL    ||
3126         pSource->Rotation == VPHAL_MIRROR_VERTICAL)
3127     {
3128         fScaleX      = (float)(pSource->rcDst.right  - pSource->rcDst.left) /
3129                        (float)(pSource->rcSrc.right  - pSource->rcSrc.left);
3130         fScaleY      = (float)(pSource->rcDst.bottom - pSource->rcDst.top) /
3131                        (float)(pSource->rcSrc.bottom - pSource->rcSrc.top);
3132     }
3133     else
3134     {
3135         // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 ||
3136         // VPHAL_ROTATE_90_MIRROR_HORIZONTAL || VPHAL_ROTATE_90_MIRROR_VERTICAL
3137         fScaleX      = (float)(pSource->rcDst.right  - pSource->rcDst.left) /
3138                        (float)(pSource->rcSrc.bottom  - pSource->rcSrc.top);
3139         fScaleY      = (float)(pSource->rcDst.bottom - pSource->rcDst.top) /
3140                        (float)(pSource->rcSrc.right - pSource->rcSrc.left);
3141     }
3142     fDiScaleY    = 1.0f;
3143 
3144     CalculateCropParams(iLayer, pRenderingData, &fCropX, &fCropY);
3145 
3146     pTargetRect = &pRenderingData->BbArgs.rcOutput;
3147 
3148     if (pRenderingData->pConstriction)
3149     {
3150         fScaleX /= pRenderingData->fConstrictionStepX;
3151         fScaleY /= pRenderingData->fConstrictionStepY;
3152     }
3153 
3154     //-------------------------------------------
3155     // Set layer ID - necessary to bind surface states
3156     //-------------------------------------------
3157     pSource->iLayerID = iLayer;
3158 
3159     pSource->bUseSampleUnorm = IsUsingSampleUnorm(pCompParams, pSource);
3160     // Check whether sampler lumakey is needed. It will be used in SetSurfaceParams
3161     // when IsNV12SamplerLumakeyNeeded being called.
3162     pSource->bUseSamplerLumakey = IsSamplerLumakeySupported(pSource);
3163     //-------------------------------------------
3164     // Setup surface states
3165     //-------------------------------------------
3166     SetSurfaceParams(pSource, &SurfaceParams);
3167 
3168     if (m_bChromaUpSampling || m_bChromaDownSampling)
3169     {
3170         if (!MEDIA_IS_WA(m_pWaTable, WaEnableDscale)                      ||
3171             (MEDIA_IS_WA(m_pWaTable, WaEnableDscale)                      &&
3172              pSource->ScalingMode == VPHAL_SCALING_BILINEAR  &&
3173              fScaleX >= (float)(1.0/3.0)                     &&
3174              fScaleY >= (float)(1.0/3.0)))
3175         {
3176             SurfaceParams.bChromasiting      = true;
3177             pSource->bChromaSiting           = true;
3178         }
3179         else
3180         {
3181             SurfaceParams.bChromasiting = false;
3182             pSource->bChromaSiting      = false;
3183         }
3184     }
3185     else
3186     {
3187             SurfaceParams.bChromasiting      = false;
3188             pSource->bChromaSiting           = false;
3189     }
3190 
3191     if (pSource->bInterlacedScaling)
3192     {
3193         // Top Input Field
3194         SurfaceParams.bVertStrideOffs   = false;
3195         SurfaceParams.bVertStride       = true;
3196 
3197         // Bottom Input Field
3198         SurfaceParams2 = SurfaceParams;
3199         SurfaceParams2.bVertStrideOffs  = true;
3200     }
3201     else if (pSource->bFieldWeaving)
3202     {
3203         // Top Input Field
3204         SurfaceParams.bVertStrideOffs   = false;
3205         SurfaceParams.bVertStride       = false;
3206 
3207         // Bottom Input Field
3208         SurfaceParams2 = SurfaceParams;
3209     }
3210 
3211     // Allocate palette ID for surface (do not load palette)
3212     if (IS_PAL_FORMAT(pSource->Format))
3213     {
3214         eStatus = pRenderHal->pfnAllocatePaletteID(pRenderHal, &pSource->iPalette);
3215         if (eStatus != MOS_STATUS_SUCCESS)
3216         {
3217             iResult = -1;
3218             goto finish;
3219         }
3220     }
3221 
3222     SurfaceParams.MemObjCtl = (pSource->SurfType == SURF_IN_PRIMARY) ?
3223                                 m_SurfMemObjCtl.PrimaryInputSurfMemObjCtl :
3224                                 m_SurfMemObjCtl.InputSurfMemObjCtl ;
3225 
3226     eStatus = VpHal_RndrCommonInitRenderHalSurface(pSource, pRenderHalSurfaceSrc);
3227     if (MOS_FAILED(eStatus))
3228     {
3229         iResult = -1;
3230         goto finish;
3231     }
3232     // Setup surface states
3233     eStatus = pRenderHal->pfnSetupSurfaceState(
3234             pRenderHal,
3235             pRenderHalSurfaceSrc,
3236             &SurfaceParams,
3237             &iSurfaceEntries,
3238             pSurfaceEntries,
3239             nullptr);
3240     if (MOS_FAILED(eStatus))
3241     {
3242         iResult = -1;
3243         goto finish;
3244     }
3245 
3246     if ((pDPStatic != nullptr) && (pSurfaceEntries[0] != nullptr))
3247     {
3248         pDPStatic->DW6.InputPictureWidth  = pSurfaceEntries[0]->dwWidth -1;
3249         pDPStatic->DW6.InputPictureHeight = pSurfaceEntries[0]->dwHeight -1;
3250     }
3251 
3252     eStatus = VpHal_RndrCommonGetBackVpSurfaceParams(
3253         pRenderHalSurfaceSrc,
3254         pSource);
3255     if (MOS_FAILED(eStatus))
3256     {
3257         iResult = -1;
3258         goto finish;
3259     }
3260 
3261     if (ScalingMode != pSource->ScalingMode)
3262     {
3263         // The AVS may be modified to Bilinear in RenderHal_SetupSurfaceState->RenderHal_GetSurfaceStateEntries if AVS
3264         // is not supported by the format of source.
3265         // Both bUseSampleUnorm and bUseSamplerLumakey need be updated.
3266         pSource->bUseSampleUnorm = IsUsingSampleUnorm(pCompParams, pSource);
3267         pSource->bUseSamplerLumakey = IsSamplerLumakeySupported(pSource);
3268     }
3269 
3270     //--------------------------------------------------------
3271     // iScaling & Field Weaving needs 2 sets of input surfaces
3272     //--------------------------------------------------------
3273     iSurfaceEntries2 = 0;
3274     if (pSource->bInterlacedScaling || pSource->bFieldWeaving)
3275     {
3276         SurfaceParams2.MemObjCtl = (pSource->SurfType == SURF_IN_PRIMARY) ?
3277                                     m_SurfMemObjCtl.PrimaryInputSurfMemObjCtl :
3278                                     m_SurfMemObjCtl.InputSurfMemObjCtl ;
3279 
3280         // For Interlaced scaling 2nd field is part of the same frame
3281         // For Field weaving 2nd field is passed in as a ref. surface
3282         pTempSurf = pSource->bFieldWeaving ? pSource->pBwdRef : pSource;
3283         eStatus = VpHal_RndrCommonInitRenderHalSurface(pTempSurf, pRenderHalSurfaceSrcField);
3284         if (MOS_FAILED(eStatus))
3285         {
3286             iResult = -1;
3287             goto finish;
3288         }
3289         eStatus = pRenderHal->pfnSetupSurfaceState(
3290             pRenderHal,
3291             pRenderHalSurfaceSrcField,
3292             &SurfaceParams2,
3293             &iSurfaceEntries2,
3294             pSurfaceEntries2,
3295             nullptr);
3296         if (MOS_FAILED(eStatus))
3297         {
3298             iResult = -1;
3299             goto finish;
3300         }
3301         eStatus = VpHal_RndrCommonGetBackVpSurfaceParams(
3302             pRenderHalSurfaceSrcField,
3303             pTempSurf);
3304         if (MOS_FAILED(eStatus))
3305         {
3306             iResult = -1;
3307             goto finish;
3308         }
3309     }
3310 
3311     if (iSurfaceEntries <= 0         ||
3312         (pSource->bInterlacedScaling &&
3313          pSource->bFieldWeaving      &&
3314          iSurfaceEntries2            != iSurfaceEntries))
3315     {
3316         VPHAL_RENDER_ASSERTMESSAGE("Failed to setup surface state.");
3317         iResult = -1;
3318         goto finish;
3319     }
3320 
3321     //-------------------------------------------
3322     // Bind surface states
3323     //-------------------------------------------
3324     eStatus = GetBindingIndex(pSource, &iBTentry);
3325     if (MOS_FAILED(eStatus))
3326     {
3327         goto finish;
3328     }
3329 
3330     for (i = 0; i < iSurfaceEntries; i++, iBTentry++)
3331     {
3332         eStatus = pRenderHal->pfnBindSurfaceState(pRenderHal,
3333                                         pRenderingData->iBindingTable,
3334                                         iBTentry,
3335                                         pSurfaceEntries[i]);
3336         if (MOS_FAILED(eStatus))
3337         {
3338             iResult = -1;
3339             goto finish;
3340         }
3341 
3342         // Interlaced scaling & Field Weaving case
3343         if (pSource->bInterlacedScaling || pSource->bFieldWeaving)
3344         {
3345             eStatus = pRenderHal->pfnBindSurfaceState(
3346                 pRenderHal,
3347                 pRenderingData->iBindingTable,
3348                 VPHAL_COMP_BTINDEX_L0_FIELD1_DUAL + i,
3349                 pSurfaceEntries2[i]);
3350 
3351             if (MOS_FAILED(eStatus))
3352             {
3353                 iResult = -1;
3354                 goto finish;
3355             }
3356         }
3357     }
3358 
3359     //-----------------------------------
3360     // Setup Luma keying parameters
3361     //-----------------------------------
3362     if (pSource->pLumaKeyParams != nullptr)
3363     {
3364         VPHAL_RENDER_NORMALMESSAGE("LumaLow %d, LumaHigh %d",
3365             pSource->pLumaKeyParams->LumaLow,
3366             pSource->pLumaKeyParams->LumaHigh);
3367 
3368         pStatic->DW14.LumakeyLowThreshold  = pSource->pLumaKeyParams->LumaLow;
3369         pStatic->DW14.LumakeyHighThreshold = pSource->pLumaKeyParams->LumaHigh;
3370     }
3371 
3372     //-----------------------------------
3373     // Setup Samplers
3374     //-----------------------------------
3375     for (i = 0; i < iSurfaceEntries; i++, iBTentry++)
3376     {
3377         if (pSurfaceEntries[i] == nullptr)
3378         {
3379             continue;
3380         }
3381 
3382         // Obtain Sampler ID and Type
3383         eStatus = GetSamplerIndex(pSource,
3384                                   pSurfaceEntries[i],
3385                                   &iSamplerID,
3386                                   &SamplerType);
3387 
3388         // Point to the current SamplerStateParam
3389         pSamplerStateParams = &pRenderingData->SamplerStateParams[iSamplerID];
3390 
3391         // No need to setup a sampler
3392         if (MOS_FAILED(eStatus))
3393         {
3394             continue;
3395         }
3396 
3397         pSamplerStateParams->SamplerType = SamplerType;
3398 
3399         if (SamplerType == MHW_SAMPLER_TYPE_3D)
3400         {
3401             fOffsetX = m_fSamplerLinearBiasX;
3402             fOffsetY = m_fSamplerLinearBiasY;
3403 
3404             // Use 3D Nearest Mode only for 1x Scaling in both directions and only if the input is Progressive or interlaced scaling is used
3405             // In case of two or more layers, set Sampler State to Bilinear if any layer requires Bilinear
3406             // When primary surface needs chroma upsampling,
3407             // force to use 3D Bilinear Mode for 1x scaling for better quality
3408             if (fScaleX == 1.0F &&
3409                 fScaleY == 1.0F &&
3410                 !m_bChromaUpSampling &&
3411                 !m_bChromaDownSampling &&
3412                 (pSource->SampleType == SAMPLE_PROGRESSIVE || pSource->bInterlacedScaling || pSource->bFieldWeaving) &&
3413                 (!pSamplerStateParams->bInUse ||
3414                 (pSamplerStateParams->bInUse && pSamplerStateParams->Unorm.SamplerFilterMode == MHW_SAMPLER_FILTER_NEAREST)))
3415             {
3416                 fShiftX  = 0.0f;
3417                 fShiftY  = 0.0f;
3418                 pSamplerStateParams->Unorm.SamplerFilterMode = MHW_SAMPLER_FILTER_NEAREST;
3419             }
3420             else
3421             {
3422                 //For Y210/Y216 with AVS(Y)+3D(U/V) sampler, the shift is not needed.
3423                 if ((pSource->Format == Format_Y210 ||
3424                     pSource->Format == Format_Y216)
3425                     && pSurfaceEntries[0]->bAVS)
3426                 {
3427                     fShiftX = 0.0f;
3428                     fShiftY = 0.0f;
3429                 }
3430                 else
3431                 {
3432                     fShiftX = VPHAL_HW_LINEAR_SHIFT;  // Bilinear scaling shift
3433                     fShiftY = VPHAL_HW_LINEAR_SHIFT;
3434                 }
3435 
3436                 pSamplerStateParams->Unorm.SamplerFilterMode = MHW_SAMPLER_FILTER_BILINEAR;
3437             }
3438             pSamplerStateParams->Unorm.AddressU = MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP;
3439             pSamplerStateParams->Unorm.AddressV = MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP;
3440             pSamplerStateParams->Unorm.AddressW = MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP;
3441 
3442             if (IsSamplerIDForY(iSamplerID) && pSource->bUseSamplerLumakey)
3443             {
3444                 //From Gen10,HW support 1 plane LumaKey process on NV12 format, Gen9 only support 2 plane LumaKey process
3445                 //if go to 1 plane, MHW_GFX3DSTATE_SURFACEFORMAT_PLANAR_420_8 format will be used, LumaKey value need to be set on Y channel, the corresponding bit range is 15:8
3446                 //if go to 2 plane, MHW_GFX3DSTATE_SURFACEFORMAT_R8_UNORM     format will be used, LumaKey value need to be set on R channel, the corresponding bit range is 23:16
3447                 if (IsNV12SamplerLumakeyNeeded(pSource, pRenderHal) || (pSurfaceEntries[i]->dwFormat == MHW_GFX3DSTATE_SURFACEFORMAT_R8_UNORM))
3448                 {
3449                     dwLow  = pSource->pLumaKeyParams->LumaLow << 16;
3450                     dwHigh = (pSource->pLumaKeyParams->LumaHigh << 16) | 0xFF00FFFF;
3451                     bForceNearestForUV = true;
3452                 }
3453                 else
3454                 {
3455                     dwLow  = pSource->pLumaKeyParams->LumaLow << 8;
3456                     dwHigh = (pSource->pLumaKeyParams->LumaHigh << 8) | 0xFFFF00FF;
3457                 }
3458 
3459                 pSamplerStateParams->Unorm.bChromaKeyEnable = true;
3460                 pSamplerStateParams->Unorm.ChromaKeyMode    = MHW_CHROMAKEY_MODE_KILL_ON_ANY_MATCH;
3461                 pSamplerStateParams->Unorm.ChromaKeyIndex   = pRenderHal->pfnAllocateChromaKey(pRenderHal, dwLow, dwHigh);
3462             }
3463 
3464             if ((!IsSamplerIDForY(iSamplerID)) && bForceNearestForUV)
3465             {
3466                 pSamplerStateParams->Unorm.SamplerFilterMode = MHW_SAMPLER_FILTER_NEAREST;
3467             }
3468         }
3469         else if (SamplerType == MHW_SAMPLER_TYPE_AVS)
3470         {
3471             // Disable sampler bias
3472             fOffsetX = 0.0f;
3473             fOffsetY = 0.0f;
3474 
3475             // Disable linear shift
3476             fShiftX = 0.0f;
3477             fShiftY = 0.0f;
3478 
3479             pSamplerStateParams->Avs.b8TapAdaptiveEnable = Is8TapAdaptiveEnabled(pSource, fScaleX, fScaleY);
3480 
3481             // Set HDC Direct Write Flag
3482             pSamplerStateParams->Avs.bHdcDwEnable = pRenderingData->bHdcDwEnable;
3483         }
3484 
3485         pSamplerStateParams->bInUse        = true;
3486 
3487         // Set AVS Scaling Table
3488         if (pSurfaceEntries[i] && pSurfaceEntries[i]->bAVS)
3489         {
3490             VPHAL_RENDER_ASSERT(SamplerType == MHW_SAMPLER_TYPE_AVS);
3491 
3492             eStatus = SetSamplerAvsParams(
3493                 pRenderingData,
3494                 pSource,
3495                 pSurfaceEntries[i],
3496                 pSamplerStateParams,
3497                 fScaleX,
3498                 fScaleY);
3499 
3500             if (MOS_FAILED(eStatus))
3501             {
3502                 iResult = -1;
3503                 goto finish;
3504             }
3505         }
3506     }
3507 
3508     //-----------------------------------
3509     // Alpha blending optimization.
3510     // If Constant blending and one of the following is true, disable blending.
3511     // If Src+Constant blending and one of the following is true, fall back to Src blending.
3512     // Condition; alpha <= 0. Layer is 100% transparent.
3513     // Condition; alpha >= 1. Layer is 100% opaque.
3514     //-----------------------------------
3515     if (pSource->pBlendingParams &&
3516         ((pSource->pBlendingParams->BlendType == BLEND_CONSTANT) ||
3517          (pSource->pBlendingParams->BlendType == BLEND_CONSTANT_SOURCE) ||
3518          (pSource->pBlendingParams->BlendType == BLEND_CONSTANT_PARTIAL)))
3519     {
3520         float fAlpha = pSource->pBlendingParams->fAlpha;
3521 
3522         VPHAL_RENDER_NORMALMESSAGE("BlendType %d, fAlpha %d",
3523             pSource->pBlendingParams->BlendType,
3524             pSource->pBlendingParams->fAlpha);
3525 
3526         // Don't render layer with alpha <= 0.0f
3527         if (fAlpha <= 0.0f)
3528         {
3529             // layer is not visible - disable layer
3530             pSource->iLayerID = -1;
3531             goto finish;
3532         }
3533         else
3534         {
3535             wAlpha  = (uint16_t) (255.0f * fAlpha);
3536         }
3537 
3538         if (fAlpha >= 1.0f || wAlpha >= 255)
3539         {
3540             if (pSource->pBlendingParams->BlendType == BLEND_CONSTANT)
3541             {
3542                 pSource->pBlendingParams->BlendType = BLEND_NONE;
3543             }
3544             else // for BlendType == BLEND_CONSTANT_SOURCE
3545             {
3546                 pSource->pBlendingParams->BlendType = BLEND_SOURCE;
3547             }
3548 
3549             pSource->pBlendingParams->fAlpha    = 1.0f;
3550             wAlpha = 255;
3551         }
3552     }
3553 
3554     //-----------------------------------
3555     // Geometry adjustments for BOB DI
3556     //-----------------------------------
3557     // Use width and height that were used to setup surface state for plane 0
3558     pSurfaceEntry = pSurfaceEntries[0];
3559     dwSurfStateHt = pSurfaceEntry->dwHeight;
3560     dwSurfStateWd = pSurfaceEntry->dwWidth;
3561 
3562     // if 1:1 scaling and interlaced scaling or field weaving
3563     // do not adjust offsets since it uses Nearest sampling
3564     if (fScaleX == 1.0F &&
3565         fScaleY == 1.0F &&
3566         (pSource->bInterlacedScaling || pSource->bFieldWeaving))
3567     {
3568         fDiScaleY = 0.5f;
3569     }
3570     else
3571     {
3572         switch (pSource->SampleType)
3573         {
3574             case SAMPLE_INTERLEAVED_EVEN_FIRST_TOP_FIELD:
3575             case SAMPLE_INTERLEAVED_ODD_FIRST_TOP_FIELD:
3576                 fDiScaleY = 0.5f;
3577                 // don't break
3578             case SAMPLE_SINGLE_TOP_FIELD:
3579                 fOffsetY += 0.25f;
3580                 break;
3581 
3582             case SAMPLE_INTERLEAVED_EVEN_FIRST_BOTTOM_FIELD:
3583             case SAMPLE_INTERLEAVED_ODD_FIRST_BOTTOM_FIELD:
3584                 fDiScaleY = 0.5f;
3585                 // don't break
3586             case SAMPLE_SINGLE_BOTTOM_FIELD:
3587                 fOffsetY -= 0.25f;
3588                 break;
3589 
3590             case SAMPLE_PROGRESSIVE:
3591             default:
3592                 fDiScaleY = 1.0f;
3593                 break;
3594         }
3595     }
3596 
3597     // Normalize source co-ordinates using the width and height programmed
3598     // in surface state. step X, Y pre-rotated
3599     // Source rectangle is pre-rotated, destination rectangle is post-rotated.
3600     if (pSource->Rotation == VPHAL_ROTATION_IDENTITY    ||
3601         pSource->Rotation == VPHAL_ROTATION_180         ||
3602         pSource->Rotation == VPHAL_MIRROR_HORIZONTAL    ||
3603         pSource->Rotation == VPHAL_MIRROR_VERTICAL)
3604     {
3605         fStepX = ((pSource->rcSrc.right - pSource->rcSrc.left - fCropX) * 1.0f) /
3606                   ((pSource->rcDst.right - pSource->rcDst.left) > 0 ?
3607                    (pSource->rcDst.right - pSource->rcDst.left) : 1);
3608         fStepY = ((pSource->rcSrc.bottom - pSource->rcSrc.top - fCropY) * fDiScaleY) /
3609                   ((pSource->rcDst.bottom - pSource->rcDst.top) > 0 ?
3610                    (pSource->rcDst.bottom - pSource->rcDst.top) : 1);
3611     }
3612     else
3613     {
3614         // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 ||
3615         // VPHAL_ROTATE_90_MIRROR_HORIZONTAL || VPHAL_ROTATE_90_MIRROR_VERTICAL
3616         fStepX = ((pSource->rcSrc.right - pSource->rcSrc.left - fCropX) * 1.0f) /
3617                   ((pSource->rcDst.bottom - pSource->rcDst.top) > 0 ?
3618                    (pSource->rcDst.bottom - pSource->rcDst.top) : 1);
3619         fStepY = ((pSource->rcSrc.bottom - pSource->rcSrc.top - fCropY) * fDiScaleY) /
3620                   ((pSource->rcDst.right - pSource->rcDst.left) > 0 ?
3621                    (pSource->rcDst.right - pSource->rcDst.left) : 1);
3622     }
3623 
3624     // Source sampling coordinates based on rcSrc
3625     fOffsetX += (pSource->rcSrc.left + fCropX / 2);
3626     fOffsetY += (pSource->rcSrc.top + fCropY / 2) * fDiScaleY;
3627 
3628     DestRect = pSource->rcDst;
3629     if (pRenderingData->pTarget[1] != nullptr)
3630     {
3631         // Calculate non-rotated rectangle based on rotated rcDst in source surface
3632         switch (pSource->Rotation)
3633         {
3634             case VPHAL_ROTATION_90:
3635                 DestRect.left     = pSource->rcDst.top;
3636                 DestRect.top      = dwDestRectHeight - pSource->rcDst.right;
3637                 DestRect.right    = pSource->rcDst.bottom;
3638                 DestRect.bottom   = dwDestRectHeight - pSource->rcDst.left;
3639                 break;
3640             case VPHAL_ROTATION_180:
3641                 DestRect.left     = dwDestRectWidth - pSource->rcDst.right;
3642                 DestRect.top      = dwDestRectHeight - pSource->rcDst.bottom;
3643                 DestRect.right    = dwDestRectWidth - pSource->rcDst.left;
3644                 DestRect.bottom   = dwDestRectHeight - pSource->rcDst.top;
3645                 break;
3646             case VPHAL_ROTATION_270:
3647                 DestRect.left     = dwDestRectWidth - pSource->rcDst.bottom;
3648                 DestRect.top      = pSource->rcDst.left;
3649                 DestRect.right    = dwDestRectWidth - pSource->rcDst.top;
3650                 DestRect.bottom   = pSource->rcDst.right;
3651                 break;
3652             case VPHAL_MIRROR_HORIZONTAL:
3653                 DestRect.left     = dwDestRectWidth - pSource->rcDst.right;
3654                 DestRect.top      = pSource->rcDst.top;
3655                 DestRect.right    = dwDestRectWidth - pSource->rcDst.left;
3656                 DestRect.bottom   = pSource->rcDst.bottom;
3657                 break;
3658             case VPHAL_MIRROR_VERTICAL:
3659                 DestRect.left     = pSource->rcDst.left;
3660                 DestRect.top      = dwDestRectHeight - pSource->rcDst.bottom;
3661                 DestRect.right    = pSource->rcDst.right;
3662                 DestRect.bottom   = dwDestRectHeight - pSource->rcDst.top;
3663                 break;
3664             case VPHAL_ROTATE_90_MIRROR_HORIZONTAL:
3665                 DestRect.left     = pSource->rcDst.top;
3666                 DestRect.top      = pSource->rcDst.left;
3667                 DestRect.right    = pSource->rcDst.bottom;
3668                 DestRect.bottom   = pSource->rcDst.right;
3669                 break;
3670             case VPHAL_ROTATE_90_MIRROR_VERTICAL:
3671                 DestRect.left     = dwDestRectWidth - pSource->rcDst.bottom;
3672                 DestRect.top      = dwDestRectHeight - pSource->rcDst.right;
3673                 DestRect.right    = dwDestRectWidth - pSource->rcDst.top;
3674                 DestRect.bottom   = dwDestRectHeight - pSource->rcDst.left;
3675                 break;
3676             case VPHAL_ROTATION_IDENTITY:
3677             default:
3678                 break;
3679         } // switch
3680 
3681         fShiftX  -= DestRect.left - pRenderingData->ConstrictionOriginX;
3682         fShiftY  -= DestRect.top  - pRenderingData->ConstrictionOriginY;
3683     }
3684     else
3685     {
3686         switch (pSource->Rotation)
3687         {
3688             case VPHAL_ROTATION_IDENTITY:
3689                 // Coordinate adjustment for render target coordinates (0,0)
3690                 fShiftX  -= pSource->rcDst.left - pRenderingData->ConstrictionOriginX;
3691                 fShiftY  -= pSource->rcDst.top  - pRenderingData->ConstrictionOriginY;
3692                 break;
3693             case VPHAL_ROTATION_90:
3694                 // Coordinate adjustment for 90 degree rotation
3695                 fShiftX  -= (float)pSource->rcDst.top  - (float)pRenderingData->ConstrictionOriginY;
3696                 fShiftY  -= (float)dwDestRectWidth -
3697                             (float)(pSource->rcSrc.bottom - pSource->rcSrc.top) * fScaleX -
3698                             (float)pSource->rcDst.left - (float)pRenderingData->ConstrictionOriginX;
3699                 break;
3700             case VPHAL_ROTATION_180:
3701                 // Coordinate adjustment for 180 degree rotation
3702                 fShiftX  -= (float)dwDestRectWidth -
3703                             (float)(pSource->rcSrc.right - pSource->rcSrc.left) * fScaleX -
3704                             (float)pSource->rcDst.left - (float)pRenderingData->ConstrictionOriginX;
3705                 fShiftY  -= (float)dwDestRectHeight -
3706                             (float)(pSource->rcSrc.bottom - pSource->rcSrc.top) * fScaleY -
3707                             (float)pSource->rcDst.top  - (float)pRenderingData->ConstrictionOriginY;
3708                 break;
3709             case VPHAL_ROTATION_270:
3710                 // Coordinate adjustment for 270 degree rotation
3711                 fShiftX  -= (float)dwDestRectHeight -
3712                             (float)(pSource->rcSrc.right - pSource->rcSrc.left) * fScaleY -
3713                             (float)pSource->rcDst.top - (float)pRenderingData->ConstrictionOriginY;
3714                 fShiftY  -= (float)pSource->rcDst.left  - (float)pRenderingData->ConstrictionOriginX;
3715                 break;
3716             case VPHAL_MIRROR_HORIZONTAL:
3717                 // Coordinate adjustment for horizontal mirroring
3718                 fShiftX  -= (float)dwDestRectWidth -
3719                             (float)(pSource->rcSrc.right - pSource->rcSrc.left) * fScaleX -
3720                             (float)pSource->rcDst.left - (float)pRenderingData->ConstrictionOriginX;
3721                 fShiftY  -= pSource->rcDst.top  - pRenderingData->ConstrictionOriginY;
3722                 break;
3723             case VPHAL_MIRROR_VERTICAL:
3724                 // Coordinate adjustment for vertical mirroring
3725                 fShiftX  -= pSource->rcDst.left - pRenderingData->ConstrictionOriginX;
3726                 fShiftY  -= (float)dwDestRectHeight -
3727                             (float)(pSource->rcSrc.bottom - pSource->rcSrc.top) * fScaleY -
3728                             (float)pSource->rcDst.top  - (float)pRenderingData->ConstrictionOriginY;
3729                 break;
3730             case VPHAL_ROTATE_90_MIRROR_HORIZONTAL:
3731                 // Coordinate adjustment for rotating 90 and horizontal mirroring
3732                 fShiftX  -= (float)pSource->rcDst.top  - (float)pRenderingData->ConstrictionOriginY;
3733                 fShiftY  -= (float)pSource->rcDst.left  - (float)pRenderingData->ConstrictionOriginX;
3734                 break;
3735             case VPHAL_ROTATE_90_MIRROR_VERTICAL:
3736             default:
3737                 // Coordinate adjustment for rotating 90 and vertical mirroring
3738                 fShiftX  -= (float)dwDestRectHeight -
3739                             (float)(pSource->rcSrc.right - pSource->rcSrc.left) * fScaleY -
3740                             (float)pSource->rcDst.top - (float)pRenderingData->ConstrictionOriginY;
3741                 fShiftY  -= (float)dwDestRectWidth -
3742                             (float)(pSource->rcSrc.bottom - pSource->rcSrc.top) * fScaleX -
3743                             (float)pSource->rcDst.left - (float)pRenderingData->ConstrictionOriginX;
3744                 break;
3745         } // switch
3746     }
3747 
3748     // Frame origins for the current layer
3749     fOriginX = (fOffsetX + fShiftX * fStepX) / dwSurfStateWd;
3750     fOriginY = (fOffsetY + fShiftY * fStepY) / dwSurfStateHt;
3751 
3752     // Adjust step
3753     if (pRenderingData->pConstriction)
3754     {
3755         fStepX *= pRenderingData->fConstrictionStepX;
3756         fStepY *= pRenderingData->fConstrictionStepY;
3757     }
3758 
3759     // Normalized block step for the current layer (block increment)
3760     fStepX /= dwSurfStateWd;
3761     fStepY /= dwSurfStateHt;
3762 
3763     // Clip source rectangle
3764     DestRect.left   = MOS_MIN(MOS_MAX(pTargetRect->left, DestRect.left  ),
3765                             pTargetRect->right);
3766     DestRect.right  = MOS_MIN(MOS_MAX(pTargetRect->left, DestRect.right ),
3767                             pTargetRect->right);
3768     DestRect.top    = MOS_MIN(MOS_MAX(pTargetRect->top , DestRect.top   ),
3769                             pTargetRect->bottom);
3770     DestRect.bottom = MOS_MIN(MOS_MAX(pTargetRect->top , DestRect.bottom),
3771                             pTargetRect->bottom);
3772 
3773     if (pRenderingData->pConstriction)
3774     {
3775         DestRect.left =
3776                 (int)((DestRect.left   - pRenderingData->ConstrictionOriginX) /
3777                                          pRenderingData->fConstrictionStepX);
3778         DestRect.right =
3779                 (int)((DestRect.right  - pRenderingData->ConstrictionOriginX) /
3780                                          pRenderingData->fConstrictionStepX);
3781         DestRect.top =
3782                 (int)((DestRect.top    - pRenderingData->ConstrictionOriginY) /
3783                                          pRenderingData->fConstrictionStepY);
3784         DestRect.bottom =
3785                 (int)((DestRect.bottom - pRenderingData->ConstrictionOriginY) /
3786                                          pRenderingData->fConstrictionStepY);
3787     }
3788 
3789     // Layer is outside the render target area
3790     if (DestRect.left == DestRect.right ||
3791         DestRect.top  == DestRect.bottom)
3792     {
3793         // layer is not visible - disable layer
3794         pSource->iLayerID = -1;
3795         goto finish;
3796     }
3797 
3798     // Set CURBE and INLINE data
3799     pStatic->DW08.DestinationRectangleWidth  = dwDestRectWidth;
3800     pStatic->DW08.DestinationRectangleHeight = dwDestRectHeight;
3801 
3802     pDPStatic->DW7.DestinationRectangleWidth = dwDestRectWidth;
3803     pDPStatic->DW7.DestinationRectangleHeight = dwDestRectHeight;
3804 
3805     switch (iLayer)
3806     {
3807         case 0:
3808             // Gen9+ uses HW based Rotation
3809             if (m_bSamplerSupportRotation)
3810             {
3811                 pStatic->DW10.ObjKa2Gen9.RotationAngleofLayer0 = pSource->Rotation;
3812             }
3813             else
3814             {
3815                 pStatic->DW09.RotationMirrorMode    = pSource->Rotation;
3816             }
3817             pStatic->DW13.ColorFill_A                       = wAlpha;
3818             pStatic->DW16.HorizontalScalingStepRatioLayer0  = fStepX;
3819             pStatic->DW24.VerticalScalingStepRatioLayer0    = fStepY;
3820             pStatic->DW40.HorizontalFrameOriginLayer0       = fOriginX;
3821             pStatic->DW32.VerticalFrameOriginLayer0         = fOriginY;
3822             pInline->DW04.VideoXScalingStep                 = fStepX;
3823 
3824             pDPStatic->DW9.HorizontalScalingStepRatioLayer0 = fStepX;
3825             pDPStatic->DW10.VerticalScalingStepRatioLayer0 = fStepY;
3826             pDPStatic->DW11.HorizontalFrameOriginLayer0 = fOriginX;
3827             pDPStatic->DW12.VerticalFrameOriginLayer0 = fOriginY;
3828 
3829             // ChromasitingUOffset and ChromasitingVOffset are only for 3D Sampler use case
3830             if (m_need3DSampler)
3831             {
3832                 fHorizgap = 0;
3833                 fVertgap = 0;
3834                 GetOffsetChromasiting(pSource,
3835                                       &fHorizgap,
3836                                       &fVertgap);
3837                 if (IS_PL2_FORMAT(pSource->Format))
3838                 {
3839 
3840                     pStatic->DW11.ChromasitingUOffset = (float)((0.5f / (pSource->dwWidth)) - fHorizgap);
3841                     pStatic->DW12.ChromasitingVOffset = (float)((1.0f / (pSource->dwHeight)) - fVertgap);
3842                 }
3843                 else if (pSource->Format == Format_YUY2)
3844                 {
3845                     pStatic->DW11.ChromasitingUOffset = (float)((1.0f / (pSource->dwWidth)) - fHorizgap);
3846                     pStatic->DW12.ChromasitingVOffset = (float)((0.5f / (pSource->dwHeight)) - fVertgap);
3847                 }
3848             }
3849             break;
3850         case 1:
3851             // if L0 and L1 have the same rotation, set for all layers.
3852             // L1 onwards must have the same rotation in a single rendering phase.
3853             // pStatic->DW09.RotationMirrorAllLayer is initialized to 0 by default
3854             // through RenderData init outside this function.
3855             if (!m_bSamplerSupportRotation)
3856             {
3857                 if (pRenderingData->pLayers[0]->Rotation == pSource->Rotation)
3858                 {
3859                     pStatic->DW09.RotationMirrorAllLayer    = 1;
3860                 }
3861             }
3862             else // Gen9+ uses HW based Rotation
3863             {
3864                 pStatic->DW10.ObjKa2Gen9.RotationAngleofLayer1 = pSource->Rotation;
3865             }
3866             pStatic->DW06.ConstantBlendingAlphaLayer1       = wAlpha;
3867             pStatic->DW17.HorizontalScalingStepRatioLayer1  = fStepX;
3868             pStatic->DW25.VerticalScalingStepRatioLayer1    = fStepY;
3869             pStatic->DW41.HorizontalFrameOriginLayer1       = fOriginX;
3870             pStatic->DW33.VerticalFrameOriginLayer1         = fOriginY;
3871             break;
3872         case 2:
3873             // Gen9+ uses HW based Rotation
3874             if (m_bSamplerSupportRotation)
3875             {
3876                 pStatic->DW10.ObjKa2Gen9.RotationAngleofLayer2 = pSource->Rotation;
3877             }
3878             pStatic->DW06.ConstantBlendingAlphaLayer2       = wAlpha;
3879             pStatic->DW18.HorizontalScalingStepRatioLayer2  = fStepX;
3880             pStatic->DW26.VerticalScalingStepRatioLayer2    = fStepY;
3881             pStatic->DW42.HorizontalFrameOriginLayer2       = fOriginX;
3882             pStatic->DW34.VerticalFrameOriginLayer2         = fOriginY;
3883             break;
3884         case 3:
3885             // Gen9+ uses HW based Rotation
3886             if (m_bSamplerSupportRotation)
3887             {
3888                 pStatic->DW10.ObjKa2Gen9.RotationAngleofLayer3 = pSource->Rotation;
3889             }
3890             pStatic->DW06.ConstantBlendingAlphaLayer3       = wAlpha;
3891             pStatic->DW19.HorizontalScalingStepRatioLayer3  = fStepX;
3892             pStatic->DW27.VerticalScalingStepRatioLayer3    = fStepY;
3893             pStatic->DW43.HorizontalFrameOriginLayer3       = fOriginX;
3894             pStatic->DW35.VerticalFrameOriginLayer3         = fOriginY;
3895             break;
3896         case 4:
3897             // Gen9+ uses HW based Rotation
3898             if (m_bSamplerSupportRotation)
3899             {
3900                 pStatic->DW10.ObjKa2Gen9.RotationAngleofLayer4 = pSource->Rotation;
3901             }
3902             pStatic->DW06.ConstantBlendingAlphaLayer4       = wAlpha;
3903             pStatic->DW20.HorizontalScalingStepRatioLayer4  = fStepX;
3904             pStatic->DW28.VerticalScalingStepRatioLayer4    = fStepY;
3905             pStatic->DW44.HorizontalFrameOriginLayer4       = fOriginX;
3906             pStatic->DW36.VerticalFrameOriginLayer4         = fOriginY;
3907             break;
3908         case 5:
3909             // Gen9+ uses HW based Rotation
3910             if (m_bSamplerSupportRotation)
3911             {
3912                 pStatic->DW10.ObjKa2Gen9.RotationAngleofLayer5 = pSource->Rotation;
3913             }
3914             pStatic->DW07.ConstantBlendingAlphaLayer5       = wAlpha;
3915             pStatic->DW21.HorizontalScalingStepRatioLayer5  = fStepX;
3916             pStatic->DW29.VerticalScalingStepRatioLayer5    = fStepY;
3917             pStatic->DW45.HorizontalFrameOriginLayer5       = fOriginX;
3918             pStatic->DW37.VerticalFrameOriginLayer5         = fOriginY;
3919             break;
3920         case 6:
3921             // Gen9+ uses HW based Rotation
3922             if (m_bSamplerSupportRotation)
3923             {
3924                 pStatic->DW10.ObjKa2Gen9.RotationAngleofLayer6 = pSource->Rotation;
3925             }
3926             pStatic->DW07.ConstantBlendingAlphaLayer6       = wAlpha;
3927             pStatic->DW22.HorizontalScalingStepRatioLayer6  = fStepX;
3928             pStatic->DW30.VerticalScalingStepRatioLayer6    = fStepY;
3929             pStatic->DW46.HorizontalFrameOriginLayer6       = fOriginX;
3930             pStatic->DW38.VerticalFrameOriginLayer6         = fOriginY;
3931             break;
3932         case 7:
3933             // Gen9+ uses HW based Rotation
3934             if (m_bSamplerSupportRotation)
3935             {
3936                 pStatic->DW10.ObjKa2Gen9.RotationAngleofLayer7 = pSource->Rotation;
3937             }
3938             pStatic->DW07.ConstantBlendingAlphaLayer7       = wAlpha;
3939             pStatic->DW23.HorizontalScalingStepRatioLayer7  = fStepX;
3940             pStatic->DW31.VerticalScalingStepRatioLayer7    = fStepY;
3941             pStatic->DW47.HorizontalFrameOriginLayer7       = fOriginX;
3942             pStatic->DW39.VerticalFrameOriginLayer7         = fOriginY;
3943             break;
3944         default:
3945             VPHAL_RENDER_ASSERTMESSAGE("Invalid layer.");
3946             iResult = -1;
3947             goto finish;
3948     }
3949 
3950     Set3DSamplerStatus(pSource, (uint8_t)iLayer, pStatic);
3951 
3952     // Save rendering parameters, increment number of layers
3953     pRenderingData->pLayers[iLayer] = pSource;
3954     pRenderingData->iLayers++;
3955 
3956     pRenderingData->BbArgs.rcDst[iLayer] = DestRect;
3957     pRenderingData->BbArgs.Rotation[iLayer] = pSource->Rotation;
3958     pRenderingData->BbArgs.iLayers++;
3959 
3960     VPHAL_RENDER_NORMALMESSAGE("Layer %d, SamplerType:%d, Scaling Model %d,  SamplerIndex %d",
3961                                iLayer, SamplerType, pSource->ScalingMode, iSamplerID);
3962     iResult = 1;
3963 
3964 finish:
3965     return iResult;
3966 }
3967 
3968 //!
3969 //! \brief    Set Composite Render Target Layer
3970 //! \details  Set Composite Render Target Layer, setup surface state and binding table
3971 //! \param    [in] pRenderingData
3972 //!           Pointer to Composite Rendering data
3973 //! \param    [in] pCompParams
3974 //!           Pointer to Composite parameters
3975 //! \return   int32_t
3976 //!           Return number of Surface State entries if successful, otherwise -1
3977 //!
SetLayerRT(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,PVPHAL_COMPOSITE_PARAMS pCompParams)3978 int32_t CompositeState::SetLayerRT(
3979     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,
3980     PVPHAL_COMPOSITE_PARAMS         pCompParams)
3981 {
3982     MOS_STATUS                          eStatus;
3983     PRENDERHAL_INTERFACE                pRenderHal;
3984     PRENDERHAL_SURFACE                  pRenderHalSurface;
3985     RENDERHAL_SURFACE_STATE_PARAMS      SurfaceParams;
3986     PRENDERHAL_SURFACE_STATE_ENTRY      pSurfaceEntries[MHW_MAX_SURFACE_PLANES];
3987     int32_t                             iSurfaceEntries, i;
3988     int32_t                             iBTentry = 0;
3989     uint32_t                            uTargetIndex;
3990     RENDERHAL_OFFSET_OVERRIDE           PlaneOffsetOverride;
3991     PRENDERHAL_OFFSET_OVERRIDE          pPlaneOffsetOverride;
3992 
3993     iSurfaceEntries = -1;
3994 
3995     VPHAL_RENDER_CHK_NULL(m_pRenderHal);
3996     VPHAL_RENDER_CHK_NULL(pRenderingData);
3997     VPHAL_RENDER_CHK_NULL(pCompParams);
3998     VPHAL_RENDER_ASSERT(pRenderingData->pTarget[0]->SurfType == SURF_OUT_RENDERTARGET);
3999 
4000     pRenderHal   = m_pRenderHal;
4001 
4002     // init surface parameters
4003     MOS_ZeroMemory(&SurfaceParams, sizeof(SurfaceParams));
4004 
4005     SurfaceParams.MemObjCtl = m_SurfMemObjCtl.TargetSurfMemObjCtl;
4006 
4007     // Used for 32x32 Media walker kernel + Color fill kernel
4008     if (m_bFtrMediaWalker)
4009     {
4010         if (pRenderingData->pColorFill != nullptr &&
4011             pRenderingData->iLayers == 0 &&
4012             pRenderHal->pHwSizes->dwSizeMediaWalkerBlock == 32)
4013         {
4014             SurfaceParams.b32MWColorFillKern = true;
4015         }
4016     }
4017 
4018     uTargetIndex = 0;
4019     do
4020     {
4021         SetSurfaceCompressionParams(pRenderingData->pTarget[uTargetIndex], true);
4022         // Get surface state allocation parameters for RT (scaling mode, stride)
4023         SetSurfaceParams(
4024             pRenderingData->pTarget[uTargetIndex],
4025             &SurfaceParams);
4026         pRenderHalSurface = &pCompParams->RenderHalSurfaceTarget[uTargetIndex];
4027         VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonInitRenderHalSurface(pRenderingData->pTarget[uTargetIndex],
4028                                                                  pRenderHalSurface));
4029         pPlaneOffsetOverride = GetPlaneOffsetOverrideParam(
4030             pRenderHalSurface,
4031             &SurfaceParams,
4032             &PlaneOffsetOverride);
4033 
4034         // Setup surface state
4035         VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSetupSurfaceState(
4036                                                pRenderHal,
4037                                                pRenderHalSurface,
4038                                                &SurfaceParams,
4039                                                &iSurfaceEntries,
4040                                                pSurfaceEntries,
4041                                                pPlaneOffsetOverride));
4042         VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonGetBackVpSurfaceParams(
4043             pRenderHalSurface,
4044             pRenderingData->pTarget[uTargetIndex]));
4045 
4046         // Setup Binding table entries
4047         if (pRenderingData->pTarget[1] == nullptr)
4048         {
4049             GetBindingIndex(pRenderingData->pTarget[0], &iBTentry);
4050         }
4051         else
4052         {
4053             // pTarget[0] will be secondary render target in dual output mode
4054             if (uTargetIndex == 0)
4055             {
4056                 iBTentry = VPHAL_COMP_BTINDEX_RT_SECOND;
4057             }
4058             else
4059             {
4060                 // pTarget[1] will be primary render target
4061                 iBTentry = VPHAL_COMP_BTINDEX_RENDERTARGET;
4062                 // set dual output mode
4063                 if(m_bFtrMediaWalker)
4064                 {
4065                     ((MEDIA_OBJECT_KA2_STATIC_DATA*)
4066                         &pRenderingData->WalkerStatic)->DW09.DualOutputMode = 1;
4067                 }
4068                 else
4069                 {
4070                     pRenderingData->Static.DW09.DualOutputMode = 1;
4071                 }
4072             }
4073         }
4074         for (i = 0; i < iSurfaceEntries; i++, iBTentry++)
4075         {
4076             VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnBindSurfaceState(
4077                                             pRenderHal,
4078                                             pRenderingData->iBindingTable,
4079                                             iBTentry,
4080                                             pSurfaceEntries[i]));
4081         }
4082 
4083         if (pRenderingData->iLayers == 0 &&
4084             pRenderingData->pColorFill == nullptr )
4085         {
4086             VPHAL_RENDER_ASSERTMESSAGE("Only Render Target is present, colorfill must be enabled.");
4087             goto finish;
4088         }
4089 
4090         uTargetIndex++;
4091     } while (uTargetIndex < VPHAL_MAX_TARGETS && pRenderingData->pTarget[uTargetIndex]);
4092 
4093 finish:
4094     if (eStatus != MOS_STATUS_SUCCESS)
4095     {
4096         iSurfaceEntries = -1;
4097     }
4098     return iSurfaceEntries;
4099 }
4100 
4101 //!
4102 //! \brief    Get Output Surface Chroma sitting position for kernel
4103 //! \param    [in] pTarget
4104 //!           Pointer to Target Surface
4105 //! \return   uint32_t
4106 //!           Return chroma sitting position
4107 //!
GetOutputChromaSitting(PVPHAL_SURFACE pTarget)4108 uint32_t CompositeState::GetOutputChromaSitting(
4109     PVPHAL_SURFACE                      pTarget)
4110 {
4111     uint32_t dwChromaSitingLocation = CHROMA_SUBSAMPLING_TOP_LEFT;
4112 
4113     VPHAL_RENDER_CHK_NULL_NO_STATUS(pTarget);
4114 
4115     // If there is no DDI setting, we use the Horizontal Left Vertical Center as default for PL2 surface.
4116     if (pTarget->ChromaSiting == CHROMA_SITING_NONE)
4117     {
4118         // PL2 default to Horizontal Left, Vertical Center
4119         if (IS_PL2_FORMAT(pTarget->Format) || IS_PL2_FORMAT_UnAligned(pTarget->Format))
4120         {
4121             dwChromaSitingLocation = CHROMA_SUBSAMPLING_CENTER_LEFT;
4122         }
4123     }
4124     else
4125     {
4126         // PL2, 6 positions are avalibale
4127         if (IS_PL2_FORMAT(pTarget->Format) || IS_PL2_FORMAT_UnAligned(pTarget->Format))
4128         {
4129             // Horizontal Left
4130             if (pTarget->ChromaSiting & CHROMA_SITING_HORZ_LEFT)
4131             {
4132                 if (pTarget->ChromaSiting & CHROMA_SITING_VERT_TOP)
4133                 {
4134                     dwChromaSitingLocation = CHROMA_SUBSAMPLING_TOP_LEFT;
4135                 }
4136                 else if (pTarget->ChromaSiting & CHROMA_SITING_VERT_CENTER)
4137                 {
4138                     dwChromaSitingLocation = CHROMA_SUBSAMPLING_CENTER_LEFT;
4139                 }
4140                 else if (pTarget->ChromaSiting & CHROMA_SITING_VERT_BOTTOM)
4141                 {
4142                     dwChromaSitingLocation = CHROMA_SUBSAMPLING_BOTTOM_LEFT;
4143                 }
4144             }
4145             // Horizontal Center
4146             else if (pTarget->ChromaSiting & CHROMA_SITING_HORZ_CENTER)
4147             {
4148                 if (pTarget->ChromaSiting & CHROMA_SITING_VERT_TOP)
4149                 {
4150                     dwChromaSitingLocation = CHROMA_SUBSAMPLING_TOP_CENTER;
4151                 }
4152                 else if (pTarget->ChromaSiting & CHROMA_SITING_VERT_CENTER)
4153                 {
4154                     dwChromaSitingLocation = CHROMA_SUBSAMPLING_CENTER_CENTER;
4155                 }
4156                 else if (pTarget->ChromaSiting & CHROMA_SITING_VERT_BOTTOM)
4157                 {
4158                     dwChromaSitingLocation = CHROMA_SUBSAMPLING_BOTTOM_CENTER;
4159                 }
4160             }
4161         }
4162         else if (IS_PA_FORMAT(pTarget->Format))
4163         {
4164             // For PA surface, only (H Left, V Top) and (H Center, V top) are needed.
4165             if (pTarget->ChromaSiting & (CHROMA_SITING_HORZ_CENTER))
4166             {
4167                 dwChromaSitingLocation = CHROMA_SUBSAMPLING_TOP_CENTER;
4168             }
4169         }
4170     }
4171 finish:
4172     return dwChromaSitingLocation;
4173 }
4174 
4175 //!
4176 //! \brief    Set Surface Compressed Parameters
4177 //! \details  Set Surface Compressed Parameters, and compression mode
4178 //! \param    [in,out] pSource
4179 //!           Pointer to Source Surface
4180 //! \param    [in] isRenderTarget
4181 //!           Render Target or not
4182 //! \return   void
4183 //!
SetSurfaceCompressionParams(PVPHAL_SURFACE pSource,bool isRenderTarget)4184 void CompositeState::SetSurfaceCompressionParams(
4185     PVPHAL_SURFACE                  pSource,
4186     bool                            isRenderTarget)
4187 {
4188     if (!MEDIA_IS_SKU(GetSkuTable(), FtrCompsitionMemoryCompressedOut) &&
4189         isRenderTarget)
4190     {
4191         if (pSource                                             &&
4192             pSource->bCompressible                              &&
4193             // For platforms support MC/RC, only enable Render engine MC write.
4194             (pSource->CompressionMode == MOS_MMC_RC             ||
4195             // For legacy platforms, no compression supported for composite RT.
4196             pSource->CompressionMode == MOS_MMC_HORIZONTAL      ||
4197             pSource->CompressionMode == MOS_MMC_VERTICAL))
4198         {
4199             VPHAL_RENDER_NORMALMESSAGE("MMC DISABLED for RT due to CompsitionMemoryCompressedOut no supported");
4200             pSource->bIsCompressed   = false;
4201             pSource->CompressionMode = MOS_MMC_DISABLED;
4202             m_pOsInterface->pfnSetMemoryCompressionMode(m_pOsInterface, &pSource->OsResource, MOS_MEMCOMP_STATE(MOS_MEMCOMP_DISABLED));
4203         }
4204     }
4205 }
4206 
4207 //!
4208 //! \brief    Check whether parameters for composition valid or not.
4209 //! \param    [in] CompositeParams
4210 //!           Parameters for composition
4211 //! \return   MOS_STATUS
4212 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
4213 //!
IsCompositeParamsValid(const VPHAL_COMPOSITE_PARAMS & CompositeParams)4214 MOS_STATUS CompositeState::IsCompositeParamsValid(
4215     const VPHAL_COMPOSITE_PARAMS& CompositeParams)
4216 {
4217     if (CompositeParams.uSourceCount > VPHAL_COMP_MAX_LAYERS)
4218     {
4219         VPHAL_RENDER_ASSERTMESSAGE("Invalid number of sources.");
4220         return MOS_STATUS_INVALID_PARAMETER;
4221     }
4222     return MOS_STATUS_SUCCESS;
4223 }
4224 
4225 //!
4226 //! \brief    Calculate and set inline data size
4227 //! \param    [in] pRenderingData
4228 //!           pointer to render data
4229 //! \param    [out] pStatic
4230 //!           pointer to static data
4231 //! \return   void
4232 //!
CalculateInlineDataSize(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,MEDIA_OBJECT_KA2_STATIC_DATA * pStatic)4233 int32_t CompositeState::CalculateInlineDataSize(
4234     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,
4235     MEDIA_OBJECT_KA2_STATIC_DATA    *pStatic)
4236 {
4237     // Set inline pointer
4238     pStatic->DW07.PointerToInlineParameters = 7;
4239 
4240     // Set Inline Data Size
4241     switch (pRenderingData->iLayers)
4242     {
4243         case 0:
4244             // Case 0 is trued only for colorfill only cases.
4245             // Colorfill uses inverted layer 0 block mask to determine colorfill region.
4246         case 1:
4247         case 2:
4248         case 3:
4249             pRenderingData->iCmdInlineSize =  8 * sizeof(uint32_t);
4250             break;
4251         case 4:
4252             pRenderingData->iCmdInlineSize =  9 * sizeof(uint32_t);
4253             break;
4254         case 5:
4255             pRenderingData->iCmdInlineSize = 10 * sizeof(uint32_t);
4256             break;
4257         case 6:
4258             pRenderingData->iCmdInlineSize = 11 * sizeof(uint32_t);
4259             break;
4260         case 7:
4261             pRenderingData->iCmdInlineSize = 12 * sizeof(uint32_t);
4262             break;
4263         case 8:
4264             pRenderingData->iCmdInlineSize = 13 * sizeof(uint32_t);
4265             break;
4266         default:
4267             VPHAL_RENDER_ASSERTMESSAGE("%s, Invalid Number of Layers.");
4268             break;
4269     }
4270     return pRenderingData->iCmdInlineSize;
4271 }
4272 
4273 //!
4274 //! \brief    Submit Composite states
4275 //! \details  Submit Composite states, including load CSC matrix, set Inline data,
4276 //!           set background color, load Palettes, set output format, load kernel, load
4277 //!           curbe data, set sampler state, set VFE State params, and etc
4278 //! \param    [in] pRenderingData
4279 //!           Pointer to Composite state
4280 //! \return   bool
4281 //!           Return TURE if successful, otherwise false
4282 //!
SubmitStates(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)4283 bool CompositeState::SubmitStates(
4284     PVPHAL_RENDERING_DATA_COMPOSITE     pRenderingData)
4285 {
4286     // States and objects
4287     PRENDERHAL_INTERFACE                pRenderHal;
4288     Kdll_State                          *pKernelDllState;   // Kernel DLL state
4289     Kdll_CacheEntry                     *pKernelEntry;      // Media kernel entry
4290     float                               pfCscMatrix[12];    // CSC matrix in floating point format
4291     int32_t                             piCscMatrix[12];    // CSC matrix in fixed point format
4292 
4293     PRENDERHAL_MEDIA_STATE              pMediaState;    // Media states
4294     MEDIA_OBJECT_KA2_STATIC_DATA        *pStatic;        // Static parameters
4295     PVPHAL_SURFACE                      pSurface;       // Surface parameters
4296     PVPHAL_SURFACE                      pTarget;        // Render Target parameters
4297 
4298     RENDERHAL_SURFACE_STATE_PARAMS      SurfaceParams;
4299 
4300     // Media kernel parameters
4301     int32_t                             iFilterSize, i, j;
4302     int32_t                             iThreadCount;
4303     Kdll_FilterEntry                    *pFilter;
4304     Kdll_CSC_Params                     *pCscParams;
4305     Kdll_CSC_Matrix                     *pMatrix;
4306     Kdll_Procamp                        *pProcamp;
4307 
4308     int32_t                             iKrnAllocation;
4309     int32_t                             iCurbeOffset;
4310     int32_t                             iCurbeLength;
4311     int32_t                             iInlineLength;
4312     MHW_KERNEL_PARAM                    MhwKernelParam;
4313 
4314     // CSC parameters for ColorFill and Palettes
4315     VPHAL_CSPACE                        src_cspace, dst_cspace;
4316     uint8_t                             ColorFill_A;
4317     float                               fStepX;
4318     bool                                bResult = false;
4319     MOS_STATUS                          eStatus;
4320     int32_t                             iNumEntries;
4321     void*                               pPaletteData = nullptr;
4322 
4323     VPHAL_RENDER_ASSERT(m_pKernelDllState);
4324     VPHAL_RENDER_CHK_NULL(m_pRenderHal);
4325     VPHAL_RENDER_CHK_NULL(pRenderingData);
4326     VPHAL_RENDER_CHK_NULL(pRenderingData->pKernelEntry);
4327 
4328     ColorFill_A     = 0;
4329     pKernelDllState = m_pKernelDllState;
4330     pRenderHal      = m_pRenderHal;
4331     pKernelEntry    = pRenderingData->pKernelEntry;
4332 
4333     // Get Pointer to rendering data
4334     if(m_bFtrMediaWalker)
4335     {
4336         pStatic    = (MEDIA_OBJECT_KA2_STATIC_DATA*)&pRenderingData->WalkerStatic;
4337     }
4338     else
4339     {
4340         pStatic    = &pRenderingData->Static;
4341     }
4342 
4343     // Get Pointer to Render Target Surface
4344     pTarget        = pRenderingData->pTarget[0];
4345 
4346     // Get Kernel Filter description
4347     pFilter        = pKernelEntry->pFilter;
4348     iFilterSize    = pKernelEntry->iFilterSize;
4349 
4350     // Get Kernel CSC information
4351     pCscParams     = pKernelEntry->pCscParams;
4352 
4353     pMatrix        = nullptr;
4354     for (i = 0; i < DL_CSC_MAX; i++)
4355     {
4356         if (pCscParams->Matrix[i].iCoeffID == CoeffID_0)
4357         {
4358             pMatrix = &pCscParams->Matrix[i];
4359             break;
4360         }
4361     }
4362 
4363     // Load CSC matrix
4364     if (pMatrix && pMatrix->bInUse && !m_bFtrCSCCoeffPatchMode)
4365     {
4366         // Procamp is present
4367         if (pMatrix->iProcampID != DL_PROCAMP_DISABLED &&
4368             pMatrix->iProcampID < m_iMaxProcampEntries)
4369         {
4370             // Get Procamp parameter - update matrix only if Procamp is changed
4371             pProcamp = &pRenderingData->pProcamp[pMatrix->iProcampID];
4372             if (pMatrix->iProcampVersion != pProcamp->iProcampVersion)
4373             {
4374                 KernelDll_UpdateCscCoefficients(pKernelDllState, pMatrix);
4375             }
4376         }
4377 
4378         // CSC coeff from static parameter only applies to primary layer
4379         if (pMatrix->iCoeffID == CoeffID_0)
4380         {
4381             int16_t* pCoeff = pMatrix->Coeff;
4382 
4383             pStatic->DW00.CscConstantC0  = *(pCoeff++);
4384             pStatic->DW00.CscConstantC1  = *(pCoeff++);
4385             pStatic->DW01.CscConstantC2  = *(pCoeff++);
4386             pStatic->DW01.CscConstantC3  = *(pCoeff++);
4387             pStatic->DW02.CscConstantC4  = *(pCoeff++);
4388             pStatic->DW02.CscConstantC5  = *(pCoeff++);
4389             pStatic->DW03.CscConstantC6  = *(pCoeff++);
4390             pStatic->DW03.CscConstantC7  = *(pCoeff++);
4391             pStatic->DW04.CscConstantC8  = *(pCoeff++);
4392             pStatic->DW04.CscConstantC9  = *(pCoeff++);
4393             pStatic->DW05.CscConstantC10 = *(pCoeff++);
4394             pStatic->DW05.CscConstantC11 = *pCoeff;
4395         }
4396         else
4397         {
4398             VPHAL_RENDER_ASSERTMESSAGE("CSC matrix coefficient id is non-zero.");
4399             goto finish;
4400         }
4401     }
4402 
4403     if (pRenderingData->bCmFcEnable && m_bFtrCSCCoeffPatchMode)
4404     {
4405         MOS_ZeroMemory(&SurfaceParams, sizeof(SurfaceParams));
4406 
4407         SurfaceParams.Type          = pRenderHal->SurfaceTypeDefault;
4408         SurfaceParams.bRenderTarget = false;
4409         SurfaceParams.Boundary      = RENDERHAL_SS_BOUNDARY_ORIGINAL;
4410         SurfaceParams.bWidth16Align = false;
4411         SurfaceParams.MemObjCtl     = m_SurfMemObjCtl.InputSurfMemObjCtl;
4412 
4413         if (!Mos_ResourceIsNull(&m_CmfcCoeff.OsResource))
4414         {
4415             VPHAL_RENDER_CHK_STATUS(VpHal_CommonSetSurfaceForHwAccess(
4416                 m_pRenderHal,
4417                 &m_CmfcCoeff,
4418                 &m_RenderHalCmfcCoeff,
4419                 &SurfaceParams,
4420                 pRenderingData->iBindingTable,
4421                 VPHAL_COMP_BTINDEX_CSC_COEFF,
4422                 false));
4423         }
4424         else
4425         {
4426             VPHAL_RENDER_ASSERTMESSAGE("Null resource found");
4427             eStatus = MOS_STATUS_NULL_POINTER;
4428             goto finish;
4429         }
4430     }
4431 
4432     iInlineLength = CalculateInlineDataSize(pRenderingData, pStatic);
4433 
4434     // Set Background color (use cspace of first layer)
4435     if (pRenderingData->pColorFill)
4436     {
4437         VPHAL_COLOR_SAMPLE_8 Src;
4438 
4439         Src.dwValue = pRenderingData->pColorFill->Color;
4440 
4441         // get src and dst colorspaces
4442         src_cspace = pRenderingData->pColorFill->CSpace;
4443 
4444         // if iscale enabled, set colorspace to render target color space
4445         if ( pFilter->sampler == Sample_iScaling || pFilter->sampler == Sample_iScaling_034x || pFilter->sampler == Sample_iScaling_AVS )
4446         {
4447             dst_cspace = CSpace_None;
4448             // find the filter of render target and set dst_cspace to render target color space
4449             for (i = 0; i < iFilterSize; i++)
4450             {
4451                 if ((pFilter + i)->layer == Layer_RenderTarget)
4452                 {
4453                     dst_cspace = (pFilter + i)->cspace;
4454                 }
4455             }
4456 
4457             if (dst_cspace == CSpace_None) // if color space is invlaid return false
4458             {
4459                 VPHAL_RENDER_ASSERTMESSAGE("Failed to assign dst color spcae for iScale case.");
4460                 goto finish;
4461             }
4462         }
4463         else // use selected cspace by kdll
4464         {
4465             if (GFX_IS_GEN_9_OR_LATER(pRenderHal->Platform))
4466             {
4467                 dst_cspace = pKernelDllState->colorfill_cspace;
4468             }
4469             else
4470             {
4471                 dst_cspace = pFilter->cspace;
4472             }
4473         }
4474 
4475         // Convert BG color only if not done so before. CSC is expensive!
4476         if ((m_csSrc.dwValue != Src.dwValue) ||
4477             (m_CSpaceSrc     != src_cspace)  ||
4478             (m_CSpaceDst     != dst_cspace))
4479         {
4480             VpHal_CSC_8(&m_csDst, &Src, src_cspace, dst_cspace);
4481 
4482             // store the values for next iteration
4483             m_csSrc     = Src;
4484             m_CSpaceSrc = src_cspace;
4485             m_CSpaceDst = dst_cspace;
4486         }
4487 
4488         // Set BG color
4489         if (KernelDll_IsCspace(dst_cspace, CSpace_RGB))
4490         {
4491             ColorFill_A = m_csDst.A;
4492             pStatic->DW13.ColorFill_R = m_csDst.R;
4493             pStatic->DW13.ColorFill_G = m_csDst.G;
4494             pStatic->DW13.ColorFill_B = m_csDst.B;
4495         }
4496         else
4497         {
4498             ColorFill_A = m_csDst.a;
4499             pStatic->DW13.ColorFill_Y = m_csDst.Y;
4500             pStatic->DW13.ColorFill_U = m_csDst.U;
4501             pStatic->DW13.ColorFill_V = m_csDst.V;
4502         }
4503     }
4504 
4505     // Load Palettes (layer cspace determines the output cspace)
4506     // REMARK - Last filter entry is for Render Target
4507     pSurface    = nullptr;     // initialize it as it may not be set such as for colorfill only case
4508     for (i = 0; i < iFilterSize - 1; i++, pFilter++)
4509     {
4510         // Get current layer ID
4511         pSurface = pRenderingData->pLayers[i];
4512         if (nullptr == pSurface)
4513         {
4514             continue;
4515         }
4516         // Check for palette
4517         if (pSurface->Palette.iNumEntries <= 0)
4518         {
4519             continue;
4520         }
4521 
4522         // Get palette CSC mode based on filter description
4523         src_cspace = pSurface->Palette.ColorSpace;
4524         dst_cspace = pFilter->cspace;
4525 
4526         MOS_ZeroMemory(pfCscMatrix, sizeof(pfCscMatrix));
4527         KernelDll_GetCSCMatrix(src_cspace, dst_cspace, pfCscMatrix);
4528         // convert float to fixed point format
4529         for (j = 0; j < 12; j++)
4530         {
4531             // multiply by 2^20 and round up
4532             piCscMatrix[j] = (int32_t)((pfCscMatrix[j] * 1048576.0f) + 0.5f);
4533         }
4534 
4535         eStatus = pRenderHal->pfnGetPaletteEntry(pRenderHal,
4536                                                  pSurface->iPalette,
4537                                                  pSurface->Palette.iNumEntries,
4538                                                  &iNumEntries,
4539                                                  &pPaletteData);
4540         if (eStatus != MOS_STATUS_SUCCESS)
4541         {
4542             VPHAL_RENDER_ASSERTMESSAGE("Failed to Get Palette Entry.");
4543             goto finish;
4544         }
4545 
4546         eStatus = LoadPaletteData(&pSurface->Palette,
4547                                    src_cspace,
4548                                    dst_cspace,
4549                                    piCscMatrix,
4550                                    iNumEntries,
4551                                    pPaletteData);
4552         if (eStatus != MOS_STATUS_SUCCESS)
4553         {
4554             VPHAL_RENDER_ASSERTMESSAGE("Failed to Load Palette.");
4555             eStatus = pRenderHal->pfnFreePaletteID(
4556                             pRenderHal,
4557                             &pSurface->iPalette);
4558             if (eStatus != MOS_STATUS_SUCCESS)
4559             {
4560                 VPHAL_RENDER_ASSERTMESSAGE("Failed to Free Palette ID.");
4561             }
4562             goto finish;
4563         }
4564     }
4565 
4566 /*
4567 |    |---------------------------------------------------------------------|
4568 |    |                      Alpha fill mode table                          |
4569 |    |---------------------------------------------------------------------|
4570 |    |                      ALPHA_FILL_MODE_NONE                           |
4571 |    |---------------------------------------------------------------------|
4572 |    |        Input         |         Output       |     Kernel used       |
4573 |    |      Has Alpha       |        Has Alpha     |      Save_ARGB        |
4574 |    |      No Alpha        |        Has Alpha     |Save_RGB(ALpha frm app)|
4575 |    |      Has Alpha       |        No Alpha      |    Save_RGB(0xff)     |
4576 |    |      No Alpha        |        No Alpha      |    Save_RGB(0xff)     |
4577 |    |---------------------------------------------------------------------|
4578 |    |                    ALPHA_FILL_MODE_OPAQUE                           |
4579 |    |---------------------------------------------------------------------|
4580 |    |        Input         |         Output       |     Kernel used       |
4581 |    |      Has Alpha       |        Has Alpha     |    Save_RGB(0xff)     |
4582 |    |      No Alpha        |        Has Alpha     |    Save_RGB(0xff)     |
4583 |    |      Has Alpha       |        No Alpha      |    Save_RGB(0xff)     |
4584 |    |      No Alpha        |        No Alpha      |    Save_RGB(0xff)     |
4585 |    |---------------------------------------------------------------------|
4586 |    |                   ALPHA_FILL_MODE_BACKGROUND                        |
4587 |    |---------------------------------------------------------------------|
4588 |    |        Input         |         Output       |     Kernel used       |
4589 |    |      Has Alpha       |        Has Alpha     |  Save_RGB(BG Alpha)   |
4590 |    |      No Alpha        |        Has Alpha     |  Save_RGB(BG Alpha)   |
4591 |    |      Has Alpha       |        No Alpha      |    Save_RGB(0xff)     |
4592 |    |      No Alpha        |        No Alpha      |    Save_RGB(0xff)     |
4593 |    |---------------------------------------------------------------------|
4594 |    |                  ALPHA_FILL_MODE_SOURCE_STREAM                      |
4595 |    |---------------------------------------------------------------------|
4596 |    |        Input         |         Output       |     Kernel used       |
4597 |    |      Has Alpha       |        Has Alpha     |      Save_ARGB        |
4598 |    |      No Alpha        |        Has Alpha     |    Save_RGB(0xff)     |
4599 |    |      Has Alpha       |        No Alpha      |    Save_RGB(0xff)     |
4600 |    |      No Alpha        |        No Alpha      |    Save_RGB(0xff)     |
4601 |    |---------------------------------------------------------------------|
4602 */
4603 
4604     // Set output format
4605     if (IS_PA_FORMAT(pTarget->Format)  &&
4606         pTarget->Format != Format_Y410 &&
4607         pTarget->Format != Format_Y416)
4608     {
4609         VpHal_RndrSetYUVComponents(
4610             pTarget->Format,
4611             &(pStatic->DW15.DestinationPackedYOffset),
4612             &(pStatic->DW15.DestinationPackedUOffset),
4613             &(pStatic->DW15.DestinationPackedVOffset));
4614     }
4615     else if (pFilter->bFillOutputAlphaWithConstant && pRenderingData->pCompAlpha != nullptr)
4616     {
4617         switch (pRenderingData->pCompAlpha->AlphaMode)
4618         {
4619             case VPHAL_ALPHA_FILL_MODE_NONE:
4620                 if (pFilter->format == Format_A8R8G8B8    ||
4621                     pFilter->format == Format_A8B8G8R8    ||
4622                     pFilter->format == Format_R10G10B10A2 ||
4623                     pFilter->format == Format_B10G10R10A2 ||
4624                     pFilter->format == Format_AYUV        ||
4625                     pFilter->format == Format_Y410        ||
4626                     pFilter->format == Format_Y416)
4627                 {
4628                     pStatic->DW15.DestinationRGBFormat = (uint8_t)(0xff * pRenderingData->pCompAlpha->fAlpha);
4629                 }
4630                 else
4631                 {
4632                     pStatic->DW15.DestinationRGBFormat = 0xff;
4633                 }
4634                 // For color fill only case, pass through alpha value
4635                 if (pRenderingData->pColorFill && pRenderingData->iLayers == 0)
4636                 {
4637                     pStatic->DW15.DestinationRGBFormat = ColorFill_A;
4638                 }
4639                 break;
4640 
4641             case VPHAL_ALPHA_FILL_MODE_BACKGROUND:
4642                 pStatic->DW15.DestinationRGBFormat = ColorFill_A;
4643                 break;
4644 
4645             // VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM case is hit when the input does not have alpha
4646             // So we set Opaque alpha channel.
4647             case VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM:
4648             case VPHAL_ALPHA_FILL_MODE_OPAQUE:
4649             default:
4650                 pStatic->DW15.DestinationRGBFormat = 0xff;
4651                 break;
4652         }
4653     }
4654     else
4655     {
4656         pStatic->DW15.DestinationRGBFormat = 0xff;
4657     }
4658 
4659     // Set flag to swap R and B in Save_RGB/ARGB if target format is Format_A8B8G8R8/Format_X8B8G8R8/Format_B10G10R10A2.
4660     // No need for RGBP/BGRP, since they are 3 plane format, kenel change the RB channel by different plane order
4661     pStatic->DW09.ChannelSwap = ((pTarget->Format == Format_A8B8G8R8) ||
4662                                  (pTarget->Format == Format_X8B8G8R8) ||
4663                                  (pTarget->Format == Format_B10G10R10A2)) ? 1 : 0;
4664 
4665     // Set primary video scaling factor
4666     fStepX = pRenderingData->Inline.DW04.VideoXScalingStep;
4667     if (fStepX <= 0.0f)
4668     {
4669         fStepX = pRenderingData->Inline.DW04.VideoXScalingStep = 1.0f;
4670     }
4671 
4672     // Set 1st layer step X to the Batch Buffer selection logic
4673     pRenderingData->BbArgs.fStepX = fStepX;
4674 
4675     // Normalize scaling factors for all layers
4676     // Ratio of Horizontal Scaling Step to Video X Scaling Step
4677     // Since NLAS is ZBBed, CM FC kernels simplified scaling factor calculation, no need to normalize here
4678     if (!pRenderingData->bCmFcEnable)
4679     {
4680         pStatic->DW16.HorizontalScalingStepRatioLayer0 /= fStepX;
4681         pStatic->DW17.HorizontalScalingStepRatioLayer1 /= fStepX;
4682         pStatic->DW18.HorizontalScalingStepRatioLayer2 /= fStepX;
4683         pStatic->DW19.HorizontalScalingStepRatioLayer3 /= fStepX;
4684         pStatic->DW20.HorizontalScalingStepRatioLayer4 /= fStepX;
4685         pStatic->DW21.HorizontalScalingStepRatioLayer5 /= fStepX;
4686         pStatic->DW22.HorizontalScalingStepRatioLayer6 /= fStepX;
4687         pStatic->DW23.HorizontalScalingStepRatioLayer7 /= fStepX;
4688     }
4689 
4690     pMediaState = pRenderingData->pMediaState;
4691 
4692     // Load media kernel for compositing
4693     INIT_MHW_KERNEL_PARAM(MhwKernelParam, pKernelEntry);
4694     iKrnAllocation = pRenderHal->pfnLoadKernel(
4695                                 pRenderHal,
4696                                 &m_KernelParams,
4697                                 &MhwKernelParam,
4698                                 pKernelEntry);
4699 
4700     // Check if kernel is successfully loaded in GSH
4701     if (iKrnAllocation < 0)
4702     {
4703         VPHAL_RENDER_ASSERTMESSAGE("Failed to load kernel in GSH.");
4704         goto finish;
4705     }
4706 
4707     SubmitStatesFillGenSpecificStaticData(pRenderingData,
4708                                    pTarget,
4709                                    pStatic);
4710 
4711     if (m_bFtrMediaWalker)
4712     {
4713         iCurbeLength = sizeof(MEDIA_WALKER_KA2_STATIC_DATA);
4714     }
4715     else
4716     {
4717         // Set Static parameters
4718         iCurbeLength = pStatic->DW14.NLASEnable ?
4719             sizeof(MEDIA_OBJECT_KA2_STATIC_DATA) -
4720             sizeof(MEDIA_OBJECT_NLAS_INLINE_DATA) :
4721             sizeof(MEDIA_OBJECT_KA2_STATIC_DATA);
4722     }
4723 
4724     iCurbeOffset = pRenderHal->pfnLoadCurbeData(
4725         pRenderHal,
4726         pMediaState,
4727         pStatic,
4728         iCurbeLength);
4729     if (iCurbeOffset < 0)
4730     {
4731         VPHAL_RENDER_ASSERTMESSAGE("Failed to setup CURBE data.");
4732         goto finish;
4733     }
4734 
4735     // Allocate Media ID, link to kernel
4736     pRenderingData->iMediaID = pRenderHal->pfnAllocateMediaID(
4737         pRenderHal,
4738         iKrnAllocation,
4739         pRenderingData->iBindingTable,
4740         iCurbeOffset,
4741         iCurbeLength,
4742         0,
4743         nullptr);
4744     if (pRenderingData->iMediaID < 0)
4745     {
4746         VPHAL_RENDER_ASSERTMESSAGE("Failed to setup Media Interface Descriptor.");
4747         goto finish;
4748     }
4749 
4750     pRenderingData->iCurbeOffset = iCurbeOffset;
4751     pRenderingData->iCurbeLength = iCurbeLength;
4752 
4753     // Set Sampler states for this Media ID
4754     eStatus = pRenderHal->pfnSetSamplerStates(
4755         pRenderHal,
4756         pRenderingData->iMediaID,
4757         pRenderingData->SamplerStateParams,
4758         MHW_RENDER_ENGINE_SAMPLERS_MAX);
4759 
4760     if (MOS_FAILED(eStatus))
4761     {
4762         VPHAL_RENDER_ASSERTMESSAGE("Failed to setup sampler states.");
4763         goto finish;
4764     }
4765 
4766     iThreadCount = GetThreadCountForVfeState(pRenderingData, pTarget);
4767 
4768     //----------------------------------
4769     // Setup VFE State params. Each Renderer MUST call pfnSetVfeStateParams().
4770     //----------------------------------
4771     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnSetVfeStateParams(
4772         pRenderHal,
4773         MEDIASTATE_DEBUG_COUNTER_FREE_RUNNING,
4774         iThreadCount,
4775         iCurbeLength,
4776         iInlineLength,
4777         nullptr));
4778 
4779     bResult = true;
4780 
4781 finish:
4782     return bResult;
4783 }
4784 
4785 //!
4786 //! \brief    Search for the best match BB according to the Composition BB arguments
4787 //! \param    [in] pBatchBufferTable
4788 //!           Pointer to the BB table to be searched
4789 //! \param    [in] pInputBbParams
4790 //!           Pointer to the BB params required for the best match
4791 //! \param    [in] iBbSize
4792 //!           the BB size required for the best match
4793 //! \param    [out] ppBatchBuffer
4794 //!           Pointer to the addr of the best matched BB, pointer to nullptr if there's
4795 //!           no available matched BB
4796 //! \return   MOS_STATUS
4797 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
4798 //!
GetBestMatchBB(PVPHAL_BATCH_BUFFER_TABLE pBatchBufferTable,PVPHAL_BATCH_BUFFER_PARAMS pInputBbParams,int32_t iBbSize,PMHW_BATCH_BUFFER * ppBatchBuffer)4799 MOS_STATUS CompositeState::GetBestMatchBB(
4800     PVPHAL_BATCH_BUFFER_TABLE     pBatchBufferTable,
4801     PVPHAL_BATCH_BUFFER_PARAMS    pInputBbParams,
4802     int32_t                       iBbSize,
4803     PMHW_BATCH_BUFFER             *ppBatchBuffer)
4804 {
4805     PMHW_BATCH_BUFFER             pBbEntry;          // 2nd level BBs array entry
4806     PMHW_BATCH_BUFFER             pBestMatch;        // Best match for BB allocation
4807     PVPHAL_BATCH_BUFFER_PARAMS    pSearchBbParams;   // Search BB parameters
4808     PVPHAL_BB_COMP_ARGS           pCompBbArgs;       // 2nd level buffer rendering arguments
4809     PVPHAL_BB_COMP_ARGS           pSearchBbArgs;     // Search BB comp parameters
4810     int32_t                       i;
4811     int32_t                       iCallID;
4812     int32_t                       iBbCount;
4813     MOS_STATUS                    eStatus;
4814 
4815     pBestMatch  = nullptr;
4816     pCompBbArgs = &pInputBbParams->BbArgs.CompositeBB;
4817     iCallID     = pInputBbParams->iCallID;
4818     eStatus     = MOS_STATUS_UNKNOWN;
4819 
4820     iBbCount = *pBatchBufferTable->piBatchBufferCount;
4821     pBbEntry = pBatchBufferTable->pBatchBufferHeader;
4822 
4823     for (i = iBbCount; i > 0; i--, pBbEntry++)
4824     {
4825         // Must contain valid Compositing BB Argument set, must have adequate size,
4826         // cannot reuse buffers from same call ID
4827         pSearchBbParams = (PVPHAL_BATCH_BUFFER_PARAMS)pBbEntry->pPrivateData;
4828 
4829         if (!pSearchBbParams                                      ||
4830             pBbEntry->iSize           < iBbSize                   ||
4831             pSearchBbParams->iCallID == iCallID                   ||
4832             pSearchBbParams->iType   != VPHAL_BB_TYPE_COMPOSITING ||
4833             pSearchBbParams->iSize   != sizeof(VPHAL_BB_COMP_ARGS))
4834         {
4835             continue;
4836         }
4837 
4838         // Must match Media ID, StepX, full blocks, different Call ID
4839         pSearchBbArgs = &(pSearchBbParams->BbArgs.CompositeBB);
4840 
4841         if (pSearchBbArgs->iMediaID    != pCompBbArgs->iMediaID ||  // != Media ID
4842             pSearchBbArgs->fStepX      != pCompBbArgs->fStepX   ||  // != Step X
4843             pSearchBbArgs->bSkipBlocks != pCompBbArgs->bSkipBlocks) // != Skip Blocks
4844         {
4845             continue;
4846         }
4847 
4848         // Target rectangle must match
4849         if (memcmp(&pSearchBbArgs->rcOutput, &pCompBbArgs->rcOutput, sizeof(RECT)))
4850         {
4851             continue;
4852         }
4853 
4854         // BB must contain same or more layers than input BB
4855         if (pSearchBbArgs->iLayers < pCompBbArgs->iLayers)
4856         {
4857             continue;
4858         }
4859 
4860         // Compare each layer, ignore layers that are not present in the input
4861         if (memcmp(&pSearchBbArgs->rcDst, &pCompBbArgs->rcDst, pCompBbArgs->iLayers * sizeof(RECT)))
4862         {
4863             continue;
4864         }
4865 
4866         // Compare each layer rotation, ignore layers that are not present in the input
4867         if (memcmp(&pSearchBbArgs->Rotation, &pCompBbArgs->Rotation, pCompBbArgs->iLayers * sizeof(VPHAL_ROTATION)))
4868         {
4869             continue;
4870         }
4871 
4872         // for AVS/Bi-Linear Scaling, NLAS enable or not
4873         if (pSearchBbArgs->bEnableNLAS != pCompBbArgs->bEnableNLAS)
4874         {
4875             continue;
4876         }
4877 
4878         // NLAS parameters must match when it's enabled
4879         if (pCompBbArgs->bEnableNLAS &&
4880             memcmp(&pSearchBbArgs->NLASParams, &pCompBbArgs->NLASParams, sizeof(VPHAL_NLAS_PARAMS)))
4881         {
4882             continue;
4883         }
4884 
4885         // Match -> reuse the BB regardless of the running state
4886         pBestMatch = pBbEntry;
4887         ((PVPHAL_BATCH_BUFFER_PARAMS)pBestMatch->pPrivateData)->bMatch = true;
4888 
4889         break;
4890     }
4891 
4892     *ppBatchBuffer = pBestMatch;
4893     eStatus        = MOS_STATUS_SUCCESS;
4894     return eStatus;
4895 }
4896 
4897 //!
4898 //! \brief    Calculate Media Object size
4899 //! \param    [in] pRenderingData
4900 //!           Pointer to Rendering Data
4901 //! \return   int32_t
4902 //!           Return the size of Media Object
4903 //!
CalculateMediaObjectSize(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)4904 int32_t CompositeState::CalculateMediaObjectSize(
4905     PVPHAL_RENDERING_DATA_COMPOSITE     pRenderingData)
4906 {
4907     MOS_UNUSED(pRenderingData);
4908     int32_t size = 0;
4909 
4910     size += m_pRenderHal->pMhwRenderInterface->GetMediaObjectCmdSize();
4911     size += sizeof(MEDIA_OBJECT_KA2_INLINE_DATA);
4912 
4913     return size;
4914 }
4915 
4916 //!
4917 //! \brief    Allocate Composite BatchBuffer
4918 //! \details  Allocate Composite BatchBuffer, search from existing BBs for a match. If
4919 //!           none, allocate new BB
4920 //! \param    [in] PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData
4921 //!           Pointer to Rendering Data
4922 //! \param    [out] PMHW_BATCH_BUFFER * ppBatchBuffer
4923 //!           Pointer to the addr of the available BB. Pointer to nullptr if there's no
4924 //! \return   MOS_STATUS
4925 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
4926 //!
AllocateBuffer(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,PMHW_BATCH_BUFFER * ppBatchBuffer)4927 MOS_STATUS CompositeState::AllocateBuffer(
4928     PVPHAL_RENDERING_DATA_COMPOSITE     pRenderingData,
4929     PMHW_BATCH_BUFFER                   *ppBatchBuffer)
4930 {
4931     PRENDERHAL_INTERFACE                pRenderHal;
4932     VPHAL_BATCH_BUFFER_TABLE            BatchBufferTable;
4933     VPHAL_BATCH_BUFFER_PARAMS           InputBbParams;
4934     int32_t                             iBbSize;
4935     int32_t                             iMobjSize;
4936     MOS_STATUS                          eStatus;
4937 
4938     eStatus      = MOS_STATUS_SUCCESS;
4939     pRenderHal   = m_pRenderHal;
4940 
4941     iMobjSize = CalculateMediaObjectSize(pRenderingData);
4942     iBbSize   = iMobjSize * pRenderingData->iBlocksX * pRenderingData->iBlocksY;
4943 
4944     iBbSize = iBbSize + pRenderHal->pMhwMiInterface->GetMiBatchBufferEndCmdSize();;
4945 
4946     InputBbParams.iSize              = sizeof(VPHAL_BB_COMP_ARGS);
4947     InputBbParams.iType              = VPHAL_BB_TYPE_COMPOSITING;
4948     InputBbParams.iCallID            = m_iCallID;
4949     InputBbParams.BbArgs.CompositeBB = pRenderingData->BbArgs;
4950 
4951     BatchBufferTable.pBatchBufferHeader = m_BatchBuffer;
4952     BatchBufferTable.pBbParamsHeader    = m_BufferParam;
4953     BatchBufferTable.iBbCountMax        = VPHAL_COMP_BUFFERS_MAX;
4954     BatchBufferTable.piBatchBufferCount = &m_iBatchBufferCount;
4955 
4956     VPHAL_RENDER_CHK_STATUS(VpHal_RenderAllocateBB(
4957                   &BatchBufferTable,
4958                   &InputBbParams,
4959                   iBbSize,
4960                   pRenderHal,
4961                   ppBatchBuffer));
4962 
4963     // Some app had memory overrun when generating the AI44/IA44 sample contents.
4964     // As result, the batch buffer was trashed and causes hardware hang (TDR).
4965     // Adding this solution to always regenerate the media objects for AI44
4966     // and IA44.
4967     if (pRenderingData->iLayers == 1                         &&
4968         (pRenderingData->pLayers[0]->Format == Format_AI44   ||
4969          pRenderingData->pLayers[0]->Format == Format_IA44))
4970     {
4971         ((PVPHAL_BATCH_BUFFER_PARAMS)(*ppBatchBuffer)->pPrivateData)->bMatch = false;
4972         (*ppBatchBuffer)->iCurrent = 0;
4973     }
4974 
4975 finish:
4976     return eStatus;
4977 }
4978 
4979 //!
4980 //! \brief    Render Composite BatchBuffer
4981 //! \details  Render Composite BatchBuffer, setup Media Object header and inline data
4982 //! \param    [in] pBatchBuffer
4983 //!           Pointer to BatchBuffer
4984 //! \param    [in] pRenderingData
4985 //!           Pointer to Rendering Data
4986 //! \return   bool
4987 //!           Return true if successful, otherwise false
4988 //!
RenderBuffer(PMHW_BATCH_BUFFER pBatchBuffer,PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)4989 bool CompositeState::RenderBuffer(
4990     PMHW_BATCH_BUFFER               pBatchBuffer,
4991     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)
4992 {
4993     PRENDERHAL_INTERFACE                pRenderHal;
4994     PMHW_MI_INTERFACE                   pMhwMiInterface;
4995     MOS_STATUS                          eStatus;
4996     PVPHAL_BB_COMP_ARGS                 pBbArgs;
4997     MEDIA_OBJECT_KA2_STATIC_DATA        *pStatic;
4998     MEDIA_OBJECT_KA2_INLINE_DATA        *pInline;
4999     MEDIA_OBJECT_NLAS_INLINE_DATA       *pInlineNLAS;
5000     VPHAL_COMPOSITE_MO_INLINE_DATA      MOInlineData;
5001     MHW_MEDIA_OBJECT_PARAMS             MediaObjectParams;
5002     uint16_t                            wMask;
5003     uint16_t                            wCombinedMask;
5004     PRECT                               rcDst;
5005     int32_t                             x, y, dx, dy;
5006     int32_t                             xl, xr, yt, yb;
5007     bool                                bResult;
5008     float                               fSrcX[8];
5009     uint32_t                            applyRotation;
5010     uint32_t                            targetIndex;
5011 
5012     bResult             = false;
5013     pRenderHal          = m_pRenderHal;
5014     pMhwMiInterface     = pRenderHal->pMhwMiInterface;
5015     MOS_ZeroMemory(fSrcX, sizeof(float) * 8);
5016 
5017     if (pRenderHal->pfnLockBB(pRenderHal, pBatchBuffer) != MOS_STATUS_SUCCESS)
5018     {
5019         VPHAL_RENDER_ASSERTMESSAGE("Failed to lock batch buffer.");
5020         goto finish;
5021     }
5022 
5023     pBbArgs   = &pRenderingData->BbArgs;
5024     rcDst     = pBbArgs->rcDst;
5025 
5026     MOS_ZeroMemory(&MediaObjectParams, sizeof(MediaObjectParams));
5027     MediaObjectParams.dwInterfaceDescriptorOffset   = pRenderingData->iMediaID;
5028     MediaObjectParams.dwInlineDataSize              =
5029         pRenderingData->iCmdInlineSize + pRenderingData->iNLASInlineSize;
5030 
5031     MOInlineData.NLASInline     = g_cInit_MEDIA_OBJECT_NLAS_INLINE_DATA;
5032     MOInlineData.KA2Inline      = pRenderingData->Inline;
5033     pInline                     = &MOInlineData.KA2Inline;
5034     pInlineNLAS                 = &MOInlineData.NLASInline;
5035     pStatic                     = &pRenderingData->Static;
5036 
5037     // Traverse blocks in the render target area. If destination is not 16x16
5038     // pixel aligned, the top-most row and left-most column will launch MO cmds
5039     // starting from non-16x16 aligned dest coords. But the rest of the MO cmds
5040     // are aligned to 16x16 pixel boundary. Worst-case we would process 15 pixel
5041     // rows top and columns left twice.
5042     // In case of dual render targets, all horizontal and vertical
5043     // settings should be set according to non-rotated output.
5044     if (pRenderingData->pTarget[1] == nullptr ||
5045         m_bKernelSupportDualOutput)
5046     {
5047         applyRotation   = 0xFFFFFFFF;
5048         targetIndex     = 0;
5049     }
5050     else
5051     {
5052         applyRotation   = 0;
5053         targetIndex     = 1;
5054     }
5055 
5056     y  = pBbArgs->rcOutput.top;
5057     for (dy = 0; dy < pRenderingData->iBlocksY; dy++)
5058     {
5059         pInline->DW00.DestinationBlockVerticalOrigin = y;
5060 
5061         wCombinedMask = (pBbArgs->bSkipBlocks) ? 0x0000 : 0xffff;
5062         switch (pRenderingData->iLayers)
5063         {
5064             case 8:
5065                 yt = rcDst[7].top    - y;
5066                 yb = rcDst[7].bottom - y;
5067                 yt = MOS_MIN(MOS_MAX(0, yt), VPHAL_COMP_BLOCK_HEIGHT);
5068                 yb = MOS_MIN(MOS_MAX(0, yb), VPHAL_COMP_BLOCK_HEIGHT);
5069                 wMask = (0xffff << yt) & ((0x0001 << yb) - 1);
5070                 wCombinedMask |= wMask;
5071 
5072                 // Gen9+ Possible HW Rotation, kernels not available yet.
5073                 // DW09 bits 2:0 indicate RotationMirrorMode,
5074                 // bit 3 indicates if RotationMirrorMode applies to all layers,
5075                 // =1 means to apply for all layers, =0 means only for Layer0
5076                 // In case of RatationMirrorAllLayer(bit3) = 0, all layers from
5077                 // layer 1 onwards must be no rotation in a single rendering phase.
5078                 SetInline16x16Mask(
5079                     (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5080                     pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5081                     (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW12,
5082                     wMask,
5083                     VPHAL_VERTICAL_16X16BLOCK_MASK);
5084             case 7:
5085                 yt = rcDst[6].top    - y;
5086                 yb = rcDst[6].bottom - y;
5087                 yt = MOS_MIN(MOS_MAX(0, yt), VPHAL_COMP_BLOCK_HEIGHT);
5088                 yb = MOS_MIN(MOS_MAX(0, yb), VPHAL_COMP_BLOCK_HEIGHT);
5089                 wMask = (0xffff << yt) & ((0x0001 << yb) - 1);
5090                 wCombinedMask |= wMask;
5091                 SetInline16x16Mask(
5092                     (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5093                     pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5094                     (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW11,
5095                     wMask,
5096                     VPHAL_VERTICAL_16X16BLOCK_MASK);
5097             case 6:
5098                 yt = rcDst[5].top    - y;
5099                 yb = rcDst[5].bottom - y;
5100                 yt = MOS_MIN(MOS_MAX(0, yt), VPHAL_COMP_BLOCK_HEIGHT);
5101                 yb = MOS_MIN(MOS_MAX(0, yb), VPHAL_COMP_BLOCK_HEIGHT);
5102                 wMask = (0xffff << yt) & ((0x0001 << yb) - 1);
5103                 wCombinedMask |= wMask;
5104                 SetInline16x16Mask(
5105                     (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5106                     pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5107                     (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW10,
5108                     wMask,
5109                     VPHAL_VERTICAL_16X16BLOCK_MASK);
5110             case 5:
5111                 yt = rcDst[4].top    - y;
5112                 yb = rcDst[4].bottom - y;
5113                 yt = MOS_MIN(MOS_MAX(0, yt), VPHAL_COMP_BLOCK_HEIGHT);
5114                 yb = MOS_MIN(MOS_MAX(0, yb), VPHAL_COMP_BLOCK_HEIGHT);
5115                 wMask = (0xffff << yt) & ((0x0001 << yb) - 1);
5116                 wCombinedMask |= wMask;
5117                 SetInline16x16Mask(
5118                     (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5119                     pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5120                     (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW09,
5121                     wMask,
5122                     VPHAL_VERTICAL_16X16BLOCK_MASK);
5123             case 4:
5124                 yt = rcDst[3].top    - y;
5125                 yb = rcDst[3].bottom - y;
5126                 yt = MOS_MIN(MOS_MAX(0, yt), VPHAL_COMP_BLOCK_HEIGHT);
5127                 yb = MOS_MIN(MOS_MAX(0, yb), VPHAL_COMP_BLOCK_HEIGHT);
5128                 wMask = (0xffff << yt) & ((0x0001 << yb) - 1);
5129                 wCombinedMask |= wMask;
5130                 SetInline16x16Mask(
5131                     (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5132                     pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5133                     (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW08,
5134                     wMask,
5135                     VPHAL_VERTICAL_16X16BLOCK_MASK);
5136             case 3:
5137                 yt = rcDst[2].top    - y;
5138                 yb = rcDst[2].bottom - y;
5139                 yt = MOS_MIN(MOS_MAX(0, yt), VPHAL_COMP_BLOCK_HEIGHT);
5140                 yb = MOS_MIN(MOS_MAX(0, yb), VPHAL_COMP_BLOCK_HEIGHT);
5141                 wMask = (0xffff << yt) & ((0x0001 << yb) - 1);
5142                 wCombinedMask |= wMask;
5143                 SetInline16x16Mask(
5144                     (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5145                     pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5146                     (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW03,
5147                     wMask,
5148                     VPHAL_VERTICAL_16X16BLOCK_MASK);
5149             case 2:
5150                 yt = rcDst[1].top    - y;
5151                 yb = rcDst[1].bottom - y;
5152                 yt = MOS_MIN(MOS_MAX(0, yt), VPHAL_COMP_BLOCK_HEIGHT);
5153                 yb = MOS_MIN(MOS_MAX(0, yb), VPHAL_COMP_BLOCK_HEIGHT);
5154                 wMask = (0xffff << yt) & ((0x0001 << yb) - 1);
5155                 wCombinedMask |= wMask;
5156                 SetInline16x16Mask(
5157                     (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5158                     pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5159                     (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW02,
5160                     wMask,
5161                     VPHAL_VERTICAL_16X16BLOCK_MASK);
5162             case 1:
5163                 yt = rcDst[0].top    - y;
5164                 yb = rcDst[0].bottom - y;
5165                 yt = MOS_MIN(MOS_MAX(0, yt), VPHAL_COMP_BLOCK_HEIGHT);
5166                 yb = MOS_MIN(MOS_MAX(0, yb), VPHAL_COMP_BLOCK_HEIGHT);
5167                 wMask = (0xffff << yt) & ((0x0001 << yb) - 1);
5168                 wCombinedMask |= wMask;
5169                 SetInline16x16Mask((VPHAL_ROTATION)
5170                     (pStatic->DW09.RotationMirrorMode & applyRotation),
5171                     (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW01,
5172                     wMask,
5173                     VPHAL_VERTICAL_16X16BLOCK_MASK);
5174                 break;
5175             case 0:
5176                 // This case is true only for colorfill only cases. Force block mask to zero.
5177                 pInline->DW01.VerticalBlockCompositeMaskLayer0 = 0;
5178                 break;
5179         }
5180 
5181         // Skip row if no blocks are flagged for rendering
5182         if (!wCombinedMask)
5183         {
5184             y += VPHAL_COMP_BLOCK_HEIGHT;
5185             y -= y % VPHAL_COMP_BLOCK_HEIGHT;
5186             continue;
5187         }
5188 
5189         x = pBbArgs->rcOutput.left;
5190 
5191         // get the horizontal origin - the second term is necessary to ensure
5192         // accurate computation of the starting value of fSrcX when the output
5193         // rectangle does not start at 0 (for example, split-screen demo mode)
5194         switch (pRenderingData->iLayers)
5195         {
5196             case 8:
5197                 fSrcX[7] = pStatic->DW47.HorizontalFrameOriginLayer7 +
5198                     ((float)(x) / (float)(pRenderingData->pTarget[targetIndex]->dwWidth));
5199             case 7:
5200                 fSrcX[6] = pStatic->DW46.HorizontalFrameOriginLayer6 +
5201                     ((float)(x) / (float)(pRenderingData->pTarget[targetIndex]->dwWidth));
5202             case 6:
5203                 fSrcX[5] = pStatic->DW45.HorizontalFrameOriginLayer5 +
5204                     ((float)(x) / (float)(pRenderingData->pTarget[targetIndex]->dwWidth));
5205             case 5:
5206                 fSrcX[4] = pStatic->DW44.HorizontalFrameOriginLayer4 +
5207                     ((float)(x) / (float)(pRenderingData->pTarget[targetIndex]->dwWidth));
5208             case 4:
5209                 fSrcX[3] = pStatic->DW43.HorizontalFrameOriginLayer3 +
5210                     ((float)(x) / (float)(pRenderingData->pTarget[targetIndex]->dwWidth));
5211             case 3:
5212                 fSrcX[2] = pStatic->DW42.HorizontalFrameOriginLayer2 +
5213                     ((float)(x) / (float)(pRenderingData->pTarget[targetIndex]->dwWidth));
5214             case 2:
5215                 fSrcX[1] = pStatic->DW41.HorizontalFrameOriginLayer1 +
5216                     ((float)(x) / (float)(pRenderingData->pTarget[targetIndex]->dwWidth));
5217             case 1:
5218                 fSrcX[0] = pStatic->DW40.HorizontalFrameOriginLayer0 +
5219                     ((float)(x) / (float)(pRenderingData->pTarget[targetIndex]->dwWidth));
5220                 break;
5221             case 0:
5222             default:
5223                 fSrcX[0] = fSrcX[1] = fSrcX[2] = fSrcX[3] = 0;
5224                 fSrcX[4] = fSrcX[5] = fSrcX[6] = fSrcX[7] = 0;
5225                 break;
5226         }
5227 
5228         for (dx = 0; dx < pRenderingData->iBlocksX; dx++)
5229         {
5230             pInline->DW00.DestinationBlockHorizontalOrigin = x;
5231 
5232             wCombinedMask = (pBbArgs->bSkipBlocks) ? 0x0000 : 0xffff;
5233             switch (pRenderingData->iLayers)
5234             {
5235                 case 8:
5236                     xl = rcDst[7].left  - x;
5237                     xr = rcDst[7].right - x;
5238                     xl = MOS_MIN(MOS_MAX(0, xl), VPHAL_COMP_BLOCK_WIDTH);
5239                     xr = MOS_MIN(MOS_MAX(0, xr), VPHAL_COMP_BLOCK_WIDTH);
5240                     wMask = (0xffff << xl) & ((0x0001 << xr) - 1);
5241                     wCombinedMask |= wMask;
5242                     SetInline16x16Mask(
5243                         (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5244                         pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5245                         (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW12,
5246                         wMask,
5247                         VPHAL_HORIZONTAL_16X16BLOCK_MASK);
5248                 case 7:
5249                     xl = rcDst[6].left  - x;
5250                     xr = rcDst[6].right - x;
5251                     xl = MOS_MIN(MOS_MAX(0, xl), VPHAL_COMP_BLOCK_WIDTH);
5252                     xr = MOS_MIN(MOS_MAX(0, xr), VPHAL_COMP_BLOCK_WIDTH);
5253                     wMask = (0xffff << xl) & ((0x0001 << xr) - 1);
5254                     wCombinedMask |= wMask;
5255                     SetInline16x16Mask(
5256                         (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5257                         pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5258                         (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW11,
5259                         wMask,
5260                         VPHAL_HORIZONTAL_16X16BLOCK_MASK);
5261                 case 6:
5262                     xl = rcDst[5].left  - x;
5263                     xr = rcDst[5].right - x;
5264                     xl = MOS_MIN(MOS_MAX(0, xl), VPHAL_COMP_BLOCK_WIDTH);
5265                     xr = MOS_MIN(MOS_MAX(0, xr), VPHAL_COMP_BLOCK_WIDTH);
5266                     wMask = (0xffff << xl) & ((0x0001 << xr) - 1);
5267                     wCombinedMask |= wMask;
5268                     SetInline16x16Mask(
5269                         (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5270                         pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5271                         (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW10,
5272                         wMask,
5273                         VPHAL_HORIZONTAL_16X16BLOCK_MASK);
5274                 case 5:
5275                     xl = rcDst[4].left  - x;
5276                     xr = rcDst[4].right - x;
5277                     xl = MOS_MIN(MOS_MAX(0, xl), VPHAL_COMP_BLOCK_WIDTH);
5278                     xr = MOS_MIN(MOS_MAX(0, xr), VPHAL_COMP_BLOCK_WIDTH);
5279                     wMask = (0xffff << xl) & ((0x0001 << xr) - 1);
5280                     wCombinedMask |= wMask;
5281                     SetInline16x16Mask(
5282                         (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5283                         pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5284                         (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW09,
5285                         wMask,
5286                         VPHAL_HORIZONTAL_16X16BLOCK_MASK);
5287                 case 4:
5288                     xl = rcDst[3].left  - x;
5289                     xr = rcDst[3].right - x;
5290                     xl = MOS_MIN(MOS_MAX(0, xl), VPHAL_COMP_BLOCK_WIDTH);
5291                     xr = MOS_MIN(MOS_MAX(0, xr), VPHAL_COMP_BLOCK_WIDTH);
5292                     wMask = (0xffff << xl) & ((0x0001 << xr) - 1);
5293                     wCombinedMask |= wMask;
5294                     SetInline16x16Mask(
5295                         (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5296                         pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5297                         (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW08,
5298                         wMask,
5299                         VPHAL_HORIZONTAL_16X16BLOCK_MASK);
5300                 case 3:
5301                     xl = rcDst[2].left  - x;
5302                     xr = rcDst[2].right - x;
5303                     xl = MOS_MIN(MOS_MAX(0, xl), VPHAL_COMP_BLOCK_WIDTH);
5304                     xr = MOS_MIN(MOS_MAX(0, xr), VPHAL_COMP_BLOCK_WIDTH);
5305                     wMask = (0xffff << xl) & ((0x0001 << xr) - 1);
5306                     wCombinedMask |= wMask;
5307                     SetInline16x16Mask(
5308                         (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5309                         pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5310                         (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW03,
5311                         wMask,
5312                         VPHAL_HORIZONTAL_16X16BLOCK_MASK);
5313                 case 2:
5314                     xl = rcDst[1].left  - x;
5315                     xr = rcDst[1].right - x;
5316                     xl = MOS_MIN(MOS_MAX(0, xl), VPHAL_COMP_BLOCK_WIDTH);
5317                     xr = MOS_MIN(MOS_MAX(0, xr), VPHAL_COMP_BLOCK_WIDTH);
5318                     wMask = (0xffff << xl) & ((0x0001 << xr) - 1);
5319                     wCombinedMask |= wMask;
5320                     SetInline16x16Mask(
5321                         (VPHAL_ROTATION)((pStatic->DW09.RotationMirrorMode *
5322                         pStatic->DW09.RotationMirrorAllLayer) & applyRotation),
5323                         (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW02,
5324                         wMask,
5325                         VPHAL_HORIZONTAL_16X16BLOCK_MASK);
5326                 case 1:
5327                     xl = rcDst[0].left  - x;
5328                     xr = rcDst[0].right - x;
5329                     xl = MOS_MIN(MOS_MAX(0, xl), VPHAL_COMP_BLOCK_WIDTH);
5330                     xr = MOS_MIN(MOS_MAX(0, xr), VPHAL_COMP_BLOCK_WIDTH);
5331                     wMask = (0xffff << xl) & ((0x0001 << xr) - 1);
5332                     wCombinedMask |= wMask;
5333                     SetInline16x16Mask((VPHAL_ROTATION)
5334                         (pStatic->DW09.RotationMirrorMode & applyRotation),
5335                         (PVPHAL_16X16BLOCK_COMPOSITE_MASK)&pInline->DW01,
5336                         wMask,
5337                         VPHAL_HORIZONTAL_16X16BLOCK_MASK);
5338                     break;
5339                 case 0:
5340                     // This case is true only for colorfill only cases. Force block mask to zero.
5341                     pInline->DW01.HorizontalBlockCompositeMaskLayer0 = 0;
5342                     break;
5343             }
5344 
5345             ModifyInlineData(pBbArgs, pRenderingData, pStatic, pInline, pInlineNLAS, x, fSrcX);
5346 
5347             if (wCombinedMask)
5348             {
5349                 if (pBbArgs->bEnableNLAS)
5350                 {
5351                     MediaObjectParams.pInlineData = &MOInlineData.NLASInline;
5352                 }
5353                 else
5354                 {
5355                     MediaObjectParams.pInlineData = &MOInlineData.KA2Inline;
5356                 }
5357                 VPHAL_RENDER_CHK_STATUS(pRenderHal->pMhwRenderInterface->AddMediaObject(
5358                     nullptr,
5359                     pBatchBuffer,
5360                     &MediaObjectParams));
5361             }
5362 
5363             x += VPHAL_COMP_BLOCK_WIDTH;
5364             x -= x % VPHAL_COMP_BLOCK_WIDTH;
5365         }
5366 
5367         y += VPHAL_COMP_BLOCK_HEIGHT;
5368         y -= y % VPHAL_COMP_BLOCK_HEIGHT;
5369     }
5370 
5371     VPHAL_RENDER_CHK_STATUS(pMhwMiInterface->AddMiBatchBufferEnd(nullptr, pBatchBuffer));
5372 
5373     if (pRenderHal->pfnUnlockBB(pRenderHal, pBatchBuffer) != MOS_STATUS_SUCCESS)
5374     {
5375         VPHAL_RENDER_ASSERTMESSAGE("Failed to unlock batch buffer.");
5376         bResult = false;
5377         goto finish;
5378     }
5379 
5380     bResult = true;
5381 
5382 finish:
5383     if (pBatchBuffer && pBatchBuffer->bLocked)
5384     {
5385         // Only happens in Error cases
5386         VPHAL_RENDER_ASSERT(0);
5387         eStatus = pRenderHal->pfnUnlockBB(pRenderHal, pBatchBuffer);
5388         VPHAL_RENDER_ASSERT(eStatus == MOS_STATUS_SUCCESS);
5389         bResult = false;
5390     }
5391     return bResult;
5392 }
5393 
5394 //!
5395 //! \brief    Judge whether  media walker pattern  will be vertical or not
5396 //! \details  if input layer is one , and input is linear format and rotation 90
5397 //!           or 270 is needed then the media walker pattern should be vertical
5398 //! \param    [in] pRenderingData
5399 //!           Pointer to Rendering Data
5400 //! \return   bool
5401 //!           Return true if vertical media pattern used, otherwise false
5402 //!
MediaWalkerVertical(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)5403 bool CompositeState::MediaWalkerVertical(
5404     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)
5405 {
5406     PVPHAL_SURFACE  pSource;
5407     bool            bVertical     = false;
5408 
5409     pSource     = pRenderingData->pLayers[0];
5410 
5411     if (pRenderingData->iLayers == 1 &&
5412         pSource->TileType == MOS_TILE_LINEAR &&
5413        (pSource->Rotation == VPHAL_ROTATION_90 || pSource->Rotation == VPHAL_ROTATION_270))
5414     {
5415         bVertical = true;
5416     }
5417 
5418     return bVertical;
5419 }
5420 
5421 //!
5422 //! \brief    Modify MediaWalker Static Data
5423 //! \param    [in] pRenderingData
5424 //!           Pointer to Rendering Data
5425 //! \return   void
5426 //!
ModifyMediaWalkerStaticData(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)5427 void CompositeState::ModifyMediaWalkerStaticData(
5428     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData)
5429 {
5430     MOS_UNUSED(pRenderingData);
5431 }
5432 
5433 //!
5434 //! \brief    Render Composite BatchBuffer
5435 //! \details  Render Composite BatchBuffer, fill Walker static data fields and set walker
5436 //!           cmd params
5437 //! \param    [in] pBatchBuffer
5438 //!           Pointer to BatchBuffer
5439 //! \param    [in] pRenderingData
5440 //!           Pointer to Rendering Data
5441 //! \param    [in] pWalkerParams
5442 //!           Pointer to Walker parameters
5443 //! \return   bool
5444 //!           Return true if successful, otherwise false
5445 //!
RenderBufferMediaWalker(PMHW_BATCH_BUFFER pBatchBuffer,PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,PMHW_WALKER_PARAMS pWalkerParams)5446 bool CompositeState::RenderBufferMediaWalker(
5447     PMHW_BATCH_BUFFER               pBatchBuffer,
5448     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,
5449     PMHW_WALKER_PARAMS              pWalkerParams)
5450 {
5451     PRENDERHAL_INTERFACE                pRenderHal;
5452     MEDIA_WALKER_KA2_STATIC_DATA        *pWalkerStatic;
5453     PVPHAL_BB_COMP_ARGS                 pBbArgs;
5454     bool                                bResult;
5455     int32_t                             iLayers;
5456     uint32_t                            uiMediaWalkerBlockSize;
5457     uint32_t*                           pdwDestXYTopLeft;
5458     uint32_t*                           pdwDestXYBottomRight;
5459     RECT                                AlignedRect;
5460     bool                                bVerticalPattern;
5461 
5462     MOS_UNUSED(pBatchBuffer);
5463 
5464     bResult          = false;
5465     pRenderHal       = m_pRenderHal;
5466     bVerticalPattern = false;
5467     pBbArgs          = &pRenderingData->BbArgs;
5468     pWalkerStatic    = &pRenderingData->WalkerStatic;
5469 
5470     VPHAL_RENDER_ASSERT(m_bFtrMediaWalker && !pBatchBuffer);
5471 
5472     pdwDestXYTopLeft     = (uint32_t*)(&pWalkerStatic->DW48);
5473     pdwDestXYBottomRight = (uint32_t*)(&pWalkerStatic->DW56);
5474 
5475     // GRF7.0-7, GRF8.0-7
5476     for (iLayers = 0;
5477          iLayers < pBbArgs->iLayers;
5478          iLayers++, pdwDestXYBottomRight++, pdwDestXYTopLeft++)
5479     {
5480         *pdwDestXYTopLeft     = (pBbArgs->rcDst[iLayers].top    << 16 ) |
5481                                  pBbArgs->rcDst[iLayers].left;
5482         *pdwDestXYBottomRight = ((pBbArgs->rcDst[iLayers].bottom - 1) << 16 ) |
5483                                  (pBbArgs->rcDst[iLayers].right - 1);
5484     }
5485 
5486     // GRF 9.0-4
5487     pWalkerStatic->DW64.MainVideoXScalingStepLeft                   =
5488         (float)pRenderingData->Inline.DW04.VideoXScalingStep;
5489     pWalkerStatic->DW65.VideoStepDeltaForNonLinearRegion            = 0;
5490     pWalkerStatic->DW66.StartofLinearScalingInPixelPositionC0       = 0;
5491     pWalkerStatic->DW66.StartofRHSNonLinearScalingInPixelPositionC1 = 0;
5492     pWalkerStatic->DW67.MainVideoXScalingStepCenter                 = 0;
5493     pWalkerStatic->DW68.MainVideoXScalingStepRight                  = 0;
5494 
5495     if (pRenderingData->pTarget[1] == nullptr)
5496     {
5497         pWalkerStatic->DW69.DestHorizontalBlockOrigin                  =
5498              (uint16_t)pRenderingData->pTarget[0]->rcDst.left;
5499         pWalkerStatic->DW69.DestVerticalBlockOrigin                    =
5500              (uint16_t)pRenderingData->pTarget[0]->rcDst.top;
5501 
5502         AlignedRect   = pRenderingData->pTarget[0]->rcDst;
5503     }
5504     else
5505     {
5506         // Horizontal and Vertical base on non-rotated in case of dual output
5507         pWalkerStatic->DW69.DestHorizontalBlockOrigin                   =
5508             (uint16_t)pRenderingData->pTarget[1]->rcDst.left;
5509         pWalkerStatic->DW69.DestVerticalBlockOrigin                     =
5510              (uint16_t)pRenderingData->pTarget[1]->rcDst.top;
5511 
5512          AlignedRect   = pRenderingData->pTarget[1]->rcDst;
5513     }
5514 
5515     ModifyMediaWalkerStaticData(pRenderingData);
5516 
5517     // Get media walker kernel block size
5518     uiMediaWalkerBlockSize = pRenderHal->pHwSizes->dwSizeMediaWalkerBlock;
5519     bVerticalPattern       = MediaWalkerVertical(pRenderingData);
5520 
5521     // Calculate aligned output area in order to determine the total # blocks
5522     // to process in case of non-16x16 aligned target.
5523     AlignedRect.right  += uiMediaWalkerBlockSize  - 1;
5524     AlignedRect.bottom += uiMediaWalkerBlockSize - 1;
5525     AlignedRect.left   -= AlignedRect.left   % uiMediaWalkerBlockSize;
5526     AlignedRect.top    -= AlignedRect.top    % uiMediaWalkerBlockSize;
5527     AlignedRect.right  -= AlignedRect.right  % uiMediaWalkerBlockSize;
5528     AlignedRect.bottom -= AlignedRect.bottom % uiMediaWalkerBlockSize;
5529 
5530     // Set walker cmd params - Rasterscan
5531     pWalkerParams->InterfaceDescriptorOffset    = pRenderingData->iMediaID;
5532 
5533     pWalkerParams->dwGlobalLoopExecCount                = 1;
5534 
5535     if (uiMediaWalkerBlockSize == 32)
5536     {
5537         pWalkerParams->ColorCountMinusOne = 3;
5538     }
5539     else
5540     {
5541         pWalkerParams->ColorCountMinusOne = 0;
5542     }
5543 
5544     if (AlignedRect.left !=0 || AlignedRect.top !=0)
5545     {
5546         // if the rect starts from any other macro  block other than the first
5547         // then the global resolution should be the whole frame and the global
5548         // start should be the rect start.
5549         pWalkerParams->GlobalResolution.x           =
5550             (AlignedRect.right / uiMediaWalkerBlockSize);
5551         pWalkerParams->GlobalResolution.y           =
5552             (AlignedRect.bottom / uiMediaWalkerBlockSize);
5553     }
5554     else
5555     {
5556         pWalkerParams->GlobalResolution.x           = pRenderingData->iBlocksX;
5557         pWalkerParams->GlobalResolution.y           = pRenderingData->iBlocksY;
5558     }
5559 
5560     pWalkerParams->GlobalStart.x                =
5561         (AlignedRect.left / uiMediaWalkerBlockSize);
5562     pWalkerParams->GlobalStart.y                =
5563         (AlignedRect.top / uiMediaWalkerBlockSize);
5564 
5565     pWalkerParams->GlobalOutlerLoopStride.x     = pRenderingData->iBlocksX;
5566     pWalkerParams->GlobalOutlerLoopStride.y     = 0;
5567 
5568     pWalkerParams->GlobalInnerLoopUnit.x        = 0;
5569     pWalkerParams->GlobalInnerLoopUnit.y        = pRenderingData->iBlocksY;
5570 
5571     pWalkerParams->BlockResolution.x            = pRenderingData->iBlocksX;
5572     pWalkerParams->BlockResolution.y            = pRenderingData->iBlocksY;
5573 
5574     pWalkerParams->LocalStart.x                 = 0;
5575     pWalkerParams->LocalStart.y                 = 0;
5576 
5577     if(bVerticalPattern)
5578     {
5579         pWalkerParams->LocalOutLoopStride.x         = 1;
5580         pWalkerParams->LocalOutLoopStride.y         = 0;
5581 
5582         pWalkerParams->LocalInnerLoopUnit.x         = 0;
5583         pWalkerParams->LocalInnerLoopUnit.y         = 1;
5584 
5585         pWalkerParams->dwLocalLoopExecCount         = pRenderingData->iBlocksX - 1;
5586         pWalkerParams->LocalEnd.x                   = 0;
5587         pWalkerParams->LocalEnd.y                   = pRenderingData->iBlocksY - 1;
5588     }
5589     else
5590     {
5591         pWalkerParams->LocalOutLoopStride.x         = 0;
5592         pWalkerParams->LocalOutLoopStride.y         = 1;
5593 
5594         pWalkerParams->LocalInnerLoopUnit.x         = 1;
5595         pWalkerParams->LocalInnerLoopUnit.y         = 0;
5596 
5597         pWalkerParams->dwLocalLoopExecCount         = pRenderingData->iBlocksY - 1;
5598         pWalkerParams->LocalEnd.x                   = pRenderingData->iBlocksX - 1;
5599         pWalkerParams->LocalEnd.y                   = 0;
5600     }
5601 
5602     bResult = true;
5603 
5604     return bResult;
5605 }
5606 
5607 //!
5608 //! \brief    Render GpGpu Walker Buffer
5609 //! \details  Render GpGpu Walker Buffer, fill Walker static data fields and set walker
5610 //!           cmd params
5611 //! \param    [in] pBatchBuffer
5612 //!           Pointer to BatchBuffer
5613 //! \param    [in] pRenderingData
5614 //!           Pointer to Rendering Data
5615 //! \param    [in] pWalkerParams
5616 //!           Pointer to Walker parameters
5617 //! \return   bool
5618 //!           Return true if successful, otherwise false
5619 //!
RenderBufferComputeWalker(PMHW_BATCH_BUFFER pBatchBuffer,PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,PMHW_GPGPU_WALKER_PARAMS pWalkerParams)5620 bool CompositeState::RenderBufferComputeWalker(
5621     PMHW_BATCH_BUFFER               pBatchBuffer,
5622     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,
5623     PMHW_GPGPU_WALKER_PARAMS        pWalkerParams)
5624 {
5625     PRENDERHAL_INTERFACE                pRenderHal;
5626     MEDIA_WALKER_KA2_STATIC_DATA        *pWalkerStatic;
5627     PVPHAL_BB_COMP_ARGS                 pBbArgs;
5628     bool                                bResult;
5629     int32_t                             iLayers;
5630     uint32_t                            uiMediaWalkerBlockSize;
5631     uint32_t*                           pdwDestXYTopLeft;
5632     uint32_t*                           pdwDestXYBottomRight;
5633     RECT                                AlignedRect;
5634 
5635     MOS_UNUSED(pBatchBuffer);
5636 
5637     bResult          = false;
5638     pRenderHal       = m_pRenderHal;
5639     pBbArgs          = &pRenderingData->BbArgs;
5640     pWalkerStatic    = &pRenderingData->WalkerStatic;
5641 
5642     VPHAL_RENDER_ASSERT(m_bFtrMediaWalker && !pBatchBuffer);
5643 
5644     pdwDestXYTopLeft     = (uint32_t*)(&pWalkerStatic->DW48);
5645     pdwDestXYBottomRight = (uint32_t*)(&pWalkerStatic->DW56);
5646 
5647     // GRF7.0-7, GRF8.0-7
5648     for (iLayers = 0;
5649          iLayers < pBbArgs->iLayers;
5650          iLayers++, pdwDestXYBottomRight++, pdwDestXYTopLeft++)
5651     {
5652         *pdwDestXYTopLeft     = (pBbArgs->rcDst[iLayers].top    << 16 ) |
5653                                  pBbArgs->rcDst[iLayers].left;
5654         *pdwDestXYBottomRight = ((pBbArgs->rcDst[iLayers].bottom - 1) << 16 ) |
5655                                  (pBbArgs->rcDst[iLayers].right - 1);
5656     }
5657 
5658     // GRF 9.0-4
5659     pWalkerStatic->DW64.MainVideoXScalingStepLeft                   =
5660         (float)pRenderingData->Inline.DW04.VideoXScalingStep;
5661     pWalkerStatic->DW65.VideoStepDeltaForNonLinearRegion            = 0;
5662     pWalkerStatic->DW66.StartofLinearScalingInPixelPositionC0       = 0;
5663     pWalkerStatic->DW66.StartofRHSNonLinearScalingInPixelPositionC1 = 0;
5664     pWalkerStatic->DW67.MainVideoXScalingStepCenter                 = 0;
5665     pWalkerStatic->DW68.MainVideoXScalingStepRight                  = 0;
5666 
5667     if (pRenderingData->pTarget[1] == nullptr)
5668     {
5669         pWalkerStatic->DW69.DestHorizontalBlockOrigin                  =
5670              (uint16_t)pRenderingData->pTarget[0]->rcDst.left;
5671         pWalkerStatic->DW69.DestVerticalBlockOrigin                    =
5672              (uint16_t)pRenderingData->pTarget[0]->rcDst.top;
5673 
5674         AlignedRect   = pRenderingData->pTarget[0]->rcDst;
5675     }
5676     else
5677     {
5678         // Horizontal and Vertical base on non-rotated in case of dual output
5679         pWalkerStatic->DW69.DestHorizontalBlockOrigin                   =
5680             (uint16_t)pRenderingData->pTarget[1]->rcDst.left;
5681         pWalkerStatic->DW69.DestVerticalBlockOrigin                     =
5682              (uint16_t)pRenderingData->pTarget[1]->rcDst.top;
5683 
5684          AlignedRect   = pRenderingData->pTarget[1]->rcDst;
5685     }
5686 
5687     ModifyMediaWalkerStaticData(pRenderingData);
5688 
5689     // Get media walker kernel block size
5690     uiMediaWalkerBlockSize = pRenderHal->pHwSizes->dwSizeMediaWalkerBlock;
5691 
5692     // Calculate aligned output area in order to determine the total # blocks
5693     // to process in case of non-16x16 aligned target.
5694     AlignedRect.right  += uiMediaWalkerBlockSize  - 1;
5695     AlignedRect.bottom += uiMediaWalkerBlockSize - 1;
5696     AlignedRect.left   -= AlignedRect.left   % uiMediaWalkerBlockSize;
5697     AlignedRect.top    -= AlignedRect.top    % uiMediaWalkerBlockSize;
5698     AlignedRect.right  -= AlignedRect.right  % uiMediaWalkerBlockSize;
5699     AlignedRect.bottom -= AlignedRect.bottom % uiMediaWalkerBlockSize;
5700 
5701     // Set walker cmd params - Rasterscan
5702     pWalkerParams->InterfaceDescriptorOffset    = pRenderingData->iMediaID;
5703 
5704     pWalkerParams->GroupStartingX = (AlignedRect.left / uiMediaWalkerBlockSize);
5705     pWalkerParams->GroupStartingY = (AlignedRect.top / uiMediaWalkerBlockSize);
5706     pWalkerParams->GroupWidth     = pRenderingData->iBlocksX;
5707     pWalkerParams->GroupHeight    = pRenderingData->iBlocksY;
5708 
5709     pWalkerParams->ThreadWidth  = VPHAL_COMP_COMPUTE_WALKER_THREAD_SPACE_WIDTH;
5710     pWalkerParams->ThreadHeight = VPHAL_COMP_COMPUTE_WALKER_THREAD_SPACE_HEIGHT;
5711     pWalkerParams->ThreadDepth  = VPHAL_COMP_COMPUTE_WALKER_THREAD_SPACE_DEPTH;
5712     pWalkerParams->IndirectDataStartAddress = pRenderingData->iCurbeOffset;
5713     // Indirect Data Length is a multiple of 64 bytes (size of L3 cacheline). Bits [5:0] are zero.
5714     pWalkerParams->IndirectDataLength       = MOS_ALIGN_CEIL(pRenderingData->iCurbeLength, 1 << MHW_COMPUTE_INDIRECT_SHIFT);
5715     pWalkerParams->BindingTableID = pRenderingData->iBindingTable;
5716 
5717     bResult = true;
5718 
5719     return bResult;
5720 }
5721 
5722 //!
5723 //! \brief    Calculate Composite parameter and render data
5724 //! \param    [in] pCompParams
5725 //!           Pointer to Composite parameters. For both input and output.
5726 //! \param    [in] pSource
5727 //!           Pointer to surface. For both input and output.
5728 //! \param    [in] pRenderingData
5729 //!           Pointer to Composite RenderData. For both input and output.
5730 //! \param    [out] pbColorfill
5731 //!           Pointer to color fill flag.
5732 //! \return   void
5733 //!
CalculateRenderData(PVPHAL_COMPOSITE_PARAMS pCompParams,PVPHAL_SURFACE pSource,PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,bool * pbColorfill)5734 void CompositeState::CalculateRenderData(
5735     PVPHAL_COMPOSITE_PARAMS         pCompParams,
5736     PVPHAL_SURFACE                  pSource,
5737     PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,
5738     bool*                           pbColorfill)
5739 {
5740     // Check if Colorfill is required
5741     if ((pCompParams->pColorFillParams != nullptr) &&
5742         (!RECT1_CONTAINS_RECT2(pSource->rcDst, pCompParams->Target[0].rcDst)))
5743     {
5744         VPHAL_RENDER_NORMALMESSAGE("bColorfill enabled");
5745         *pbColorfill = true;
5746     }
5747 
5748     // Set HDC Direct Write Flag
5749     if (pCompParams->uSourceCount == 1                                          &&  // Single Layer
5750         pSource->ScalingMode == VPHAL_SCALING_AVS                               &&  // AVS
5751         !pSource->bInterlacedScaling                                            &&  // No interlace scaling
5752         IS_PA_FORMAT(pSource->Format)                                           &&  // Input Format is Packed
5753         (IS_PA_FORMAT(pCompParams->Target[0].Format) ||
5754          pCompParams->Target[0].Format == Format_NV12)                          &&  // Output format is Packed or 4:2:0
5755         pSource->Rotation == VPHAL_ROTATION_IDENTITY                            &&  // No Rotation
5756         !(*pbColorfill)                                                         &&  // No Colorfill
5757         pSource->pLumaKeyParams == nullptr                                      &&  // No Lumakey
5758         pSource->pProcampParams == nullptr                                      &&  // No Procamp
5759         pSource->pBlendingParams == nullptr                                     &&  // No Blending
5760         m_bKernelSupportHdcDW)                                                      // if HDC direct write is supported
5761     {
5762         VPHAL_RENDER_NORMALMESSAGE("bHdcDwEnable enabled");
5763         pRenderingData->bHdcDwEnable = true;
5764     }
5765 }
5766 
5767 //!
5768 //! \brief    Perform multiple layer composite operation in one phase
5769 //! \details  Perform multiple layer composite operation in one phase(scaling, blending,
5770 //!           lumakey, CSC)
5771 //! \param    [in,out] pCompParams
5772 //!           Pointer to Composite parameters
5773 //! \return   MOS_STATUS
5774 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
5775 //!
RenderPhase(PVPHAL_COMPOSITE_PARAMS pCompParams)5776 MOS_STATUS CompositeState::RenderPhase(
5777     PVPHAL_COMPOSITE_PARAMS pCompParams)
5778 {
5779     VPHAL_RENDERING_DATA_COMPOSITE  RenderingData           = {};
5780     PMOS_INTERFACE                  pOsInterface            = nullptr;
5781     PRENDERHAL_INTERFACE            pRenderHal              = nullptr;
5782     PMHW_BATCH_BUFFER               pBatchBuffer            = nullptr;
5783     Kdll_State                      *pKernelDllState        = nullptr;
5784     Kdll_CacheEntry                 *pKernelEntry           = nullptr;
5785     Kdll_CSC_Params                 *pCscParams             = nullptr;;
5786     Kdll_CSC_Matrix                 *pMatrix                = nullptr;;
5787     Kdll_Procamp                    *pProcamp               = nullptr;;
5788     int32_t                         iFilterSize             = 0;
5789     Kdll_FilterEntry                *pFilter                = nullptr;;
5790     uint32_t                        dwKernelHash            = 0;
5791     MOS_STATUS                      eStatus                 = MOS_STATUS_UNKNOWN;
5792     PVPHAL_SURFACE                  pSource                 = nullptr;
5793     PVPHAL_SURFACE                  *pSourceArray           = nullptr;
5794     PRENDERHAL_MEDIA_STATE          pMediaState             = nullptr;
5795     int32_t                         iBindingTableID         = 0;
5796     int32_t                         iLayer                  = 0;
5797     int32_t                         iRes                    = 0;
5798     MHW_WALKER_PARAMS               WalkerParams            = {};
5799     PMHW_WALKER_PARAMS              pWalkerParams           = nullptr;
5800     MHW_GPGPU_WALKER_PARAMS         ComputeWalkerParams     = {};
5801     PMHW_GPGPU_WALKER_PARAMS        pComputeWalkerParams    = nullptr;
5802     bool                            bKernelEntryUpdate      = false;
5803     bool                            bColorfill              = false;
5804 
5805     VPHAL_RENDER_ASSERT(pCompParams);
5806     VPHAL_RENDER_ASSERT(m_pOsInterface);
5807     VPHAL_RENDER_ASSERT(m_pOsInterface->osCpInterface);
5808     VPHAL_RENDER_ASSERT(m_pRenderHal);
5809     VPHAL_RENDER_ASSERT(m_pKernelDllState);
5810 
5811     pOsInterface    = m_pOsInterface;
5812     pRenderHal      = m_pRenderHal;
5813     pKernelDllState = m_pKernelDllState;
5814 
5815     //VPHAL_DBG_STATE_DUMPPER_SET_CURRENT_STAGE(VPHAL_DBG_STAGE_COMP);
5816 
5817     // Check whether composition parameters are valid.
5818     VPHAL_RENDER_CHK_STATUS(IsCompositeParamsValid(*pCompParams));
5819 
5820     //============================
5821     // Allocate states for rendering
5822     //============================
5823     // Prepare for rendering
5824     VPHAL_RENDER_CHK_STATUS(RenderInit(
5825         pCompParams,
5826         &RenderingData));
5827 
5828     // Allocate and reset media state
5829     RenderingData.pMediaState = pMediaState =
5830                             pRenderHal->pfnAssignMediaState(pRenderHal, RENDERHAL_COMPONENT_COMP);
5831     VPHAL_RENDER_CHK_NULL(pMediaState);
5832 
5833     // Allocate and reset SSH instance
5834     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnAssignSshInstance(pRenderHal));
5835 
5836     // Allocate and reset BT
5837     VPHAL_RENDER_CHK_STATUS(pRenderHal->pfnAssignBindingTable(
5838                pRenderHal,
5839                &iBindingTableID));
5840 
5841     RenderingData.iBindingTable = iBindingTableID;
5842 
5843     //===============================
5844     // Setup params for each layer
5845     //===============================
5846     pSourceArray = pCompParams->pSource;
5847     for (iLayer = 0; iLayer < (int32_t)pCompParams->uSourceCount; iLayer++, pSourceArray++)
5848     {
5849         // Get next source
5850         pSource = *pSourceArray;
5851 
5852         // Check Scaling mode for 3D Sampler use case
5853         if (m_need3DSampler && pSource->ScalingMode == VPHAL_SCALING_AVS)
5854         {
5855             VPHAL_RENDER_NORMALMESSAGE("Modify ScalingMode to BILINREA from AVS due to 3D Sampler enabled");
5856             pSource->ScalingMode = VPHAL_SCALING_BILINEAR;
5857         }
5858 
5859         // Set scaling mode for the current layer
5860         if (pCompParams->pConstriction)
5861         {
5862             pSource->ScalingMode = VPHAL_SCALING_BILINEAR;
5863         }
5864         else
5865         {
5866             if (pSource->ScalingMode == VPHAL_SCALING_AVS &&
5867                 pSource->SurfType == SURF_IN_PRIMARY)
5868             {
5869                 m_bChromaUpSampling = VpHal_IsChromaUpSamplingNeeded(
5870                                                     pSource,
5871                                                     &pCompParams->Target[0]);
5872             }
5873             else if (m_need3DSampler                                       &&
5874                      pSource->ScalingMode != VPHAL_SCALING_AVS             &&
5875                      pSource->SurfType == SURF_IN_PRIMARY                  &&
5876                      ((IS_PL2_FORMAT(pSource->Format) && iLayer == 0)      || // when 3D sampler been used, PL2 chromasitting kernel does not support sub-layer chromasitting
5877                      pSource->Format == Format_YUY2))
5878             {
5879                 m_bChromaUpSampling   = VpHal_IsChromaUpSamplingNeeded(
5880                                                     pSource,
5881                                                     &pCompParams->Target[0]);
5882                 m_bChromaDownSampling = VpHal_IsChromaDownSamplingNeeded(
5883                                                     pSource,
5884                                                     &pCompParams->Target[0]);
5885             }
5886             else
5887             {
5888                 m_bChromaUpSampling   = false;
5889                 m_bChromaDownSampling = false;
5890             }
5891 
5892             SetScalingMode(
5893                 pSource,
5894                 pCompParams->uSourceCount);
5895         }
5896 
5897         // Get Allocation index of source for rendering
5898         if (pOsInterface->pfnRegisterResource(
5899                 pOsInterface,
5900                 &pSource->OsResource,
5901                 false,
5902                 true) != MOS_STATUS_SUCCESS)
5903         {
5904             eStatus = MOS_STATUS_UNKNOWN;
5905             goto finish;
5906         }
5907 
5908         // The parameter YOffset of surface state should be
5909         // a multiple of 4 when the input is accessed in field mode.For interlaced NV12
5910         // input, if its height is not a multiple of 4, the YOffset of UV plane will not
5911         // be a multiple of 4.So under this condition, we treat it as progressive input.
5912         if (VpHal_RndrCommonIsAlignmentWANeeded(
5913                 pSource,
5914                 pOsInterface->CurrentGpuContextOrdinal))
5915         {
5916             pSource->SampleType         = SAMPLE_PROGRESSIVE;
5917             pSource->bInterlacedScaling = false;
5918         }
5919 
5920         // If there is no scaling used for interlace surface on 10bit PA formats, force to progressive due to no supoort for kernel.
5921         if (pSource->bInterlacedScaling &&
5922             (pSource->rcSrc.right - pSource->rcSrc.left) == (pSource->rcDst.right - pSource->rcDst.left) &&
5923             (pSource->rcSrc.bottom - pSource->rcSrc.top) == (pSource->rcDst.bottom - pSource->rcDst.top) &&
5924             (pSource->Format == Format_Y210 || pSource->Format == Format_Y410))
5925         {
5926             pSource->SampleType = SAMPLE_PROGRESSIVE;
5927             pSource->bInterlacedScaling = false;
5928         }
5929 
5930         // Get Allocation index of reference for rendering
5931         if (pSource->bFieldWeaving && pSource->pBwdRef)
5932         {
5933             if (pOsInterface->pfnRegisterResource(
5934                     pOsInterface,
5935                     &pSource->pBwdRef->OsResource,
5936                     false,
5937                     true) != MOS_STATUS_SUCCESS)
5938             {
5939                 eStatus = MOS_STATUS_UNKNOWN;
5940                 goto finish;
5941             }
5942         }
5943 
5944         CalculateRenderData(pCompParams, pSource, &RenderingData, &bColorfill);
5945 
5946         // Setup rendering parameters for current layer
5947         iRes = SetLayer(
5948                     &RenderingData,
5949                     pSource,
5950                     iLayer,
5951                     pCompParams);
5952         if (iRes < 0)
5953         {
5954             VPHAL_RENDER_ASSERTMESSAGE("Failed to set layer parameters.");
5955             eStatus = MOS_STATUS_UNKNOWN;
5956             goto finish;
5957         }
5958 
5959         // Report mode
5960         if (pSource->SurfType == SURF_IN_PRIMARY)
5961         {
5962             SetReporting(pSource);
5963         }
5964     }
5965 
5966     // Get allocation index for render target Setup Surface States for Render Target
5967     for (iLayer = 0; iLayer < (int32_t)pCompParams->uTargetCount; iLayer++)
5968     {
5969         if (pOsInterface->pfnRegisterResource(
5970                 pOsInterface,
5971                 &pCompParams->Target[iLayer].OsResource,
5972                 true,
5973                 true) != MOS_STATUS_SUCCESS)
5974         {
5975             eStatus = MOS_STATUS_UNKNOWN;
5976             goto finish;
5977         }
5978     }
5979 
5980     // Setup rendering parameters for RT layer(s)
5981     iRes = SetLayerRT(
5982                &RenderingData,
5983                pCompParams);
5984     if (iRes < 0)
5985     {
5986          VPHAL_RENDER_ASSERTMESSAGE("Failed to set Render Target.");
5987          eStatus = MOS_STATUS_UNKNOWN;
5988          goto finish;
5989     }
5990 
5991     //============================
5992     // Create search filter for Dynamic Linking
5993     //============================
5994     pFilter = m_SearchFilter;
5995     MOS_ZeroMemory(pFilter, sizeof(m_SearchFilter));
5996     pCompParams->bComputeWlaker = pRenderHal->bComputeContextInUse;
5997 
5998     if (!BuildFilter(
5999              pCompParams,
6000              pFilter,
6001              &iFilterSize))
6002     {
6003         VPHAL_RENDER_ASSERTMESSAGE("Failed to create filter description.");
6004         eStatus = MOS_STATUS_UNIMPLEMENTED;
6005         goto finish;
6006     }
6007 
6008     //Log for debug
6009     for (int32_t i = 0; i < iFilterSize; i++)
6010     {
6011         Kdll_FilterEntry *pTempFilter = (pFilter + i);
6012 
6013         if (pTempFilter == nullptr)
6014             continue;
6015 
6016         VPHAL_RENDER_NORMALMESSAGE("Kernel Search Filter %d: layer %d, format %d, cspace %d, \
6017                                    bEnableDscale %d, bIsDitherNeeded %d, chromasiting %d, colorfill %d, dualout %d, \
6018                                    lumakey %d, procamp %d, RenderMethod %d, sampler %d, samplerlumakey %d ",
6019                                    i, pTempFilter->layer, pTempFilter->format, pTempFilter->cspace,
6020                                    pTempFilter->bEnableDscale, pTempFilter->bIsDitherNeeded,
6021                                    pTempFilter->chromasiting, pTempFilter->colorfill,  pTempFilter->dualout,
6022                                    pTempFilter->lumakey, pTempFilter->procamp, pTempFilter->RenderMethod, pTempFilter->sampler, pTempFilter->samplerlumakey);
6023     }
6024 
6025     //============================
6026     // KERNEL SEARCH
6027     //============================
6028     dwKernelHash = KernelDll_SimpleHash(pFilter, iFilterSize * sizeof(Kdll_FilterEntry));
6029     pKernelEntry = KernelDll_GetCombinedKernel(pKernelDllState, pFilter, iFilterSize, dwKernelHash);
6030 
6031     if (pKernelEntry)
6032     {
6033         pCscParams = pKernelEntry->pCscParams;
6034         pMatrix    = &pCscParams->Matrix[pCscParams->MatrixID[0]];
6035         pKernelDllState->colorfill_cspace = pKernelEntry->colorfill_cspace;
6036 
6037         if ((pMatrix->iProcampID != DL_PROCAMP_DISABLED) &&
6038             (pMatrix->iProcampID < m_iMaxProcampEntries))
6039         {
6040             pProcamp           = &(m_Procamp[pMatrix->iProcampID]);
6041             bKernelEntryUpdate = (pProcamp->iProcampVersion != pMatrix->iProcampVersion) ? true : false;
6042         }
6043     }
6044 
6045     if (!pKernelEntry || bKernelEntryUpdate)
6046     {
6047         Kdll_SearchState *pSearchState = &m_KernelSearch;
6048 
6049         // Remove kernel entry from kernel caches
6050         if (bKernelEntryUpdate)
6051         {
6052             KernelDll_ReleaseHashEntry(&(pKernelDllState->KernelHashTable), pKernelEntry->wHashEntry);
6053             KernelDll_ReleaseCacheEntry(&(pKernelDllState->KernelCache), pKernelEntry);
6054         }
6055 
6056         // Setup kernel search
6057         pKernelDllState->pfnStartKernelSearch(
6058             pKernelDllState,
6059             pSearchState,
6060             pFilter,
6061             iFilterSize,
6062             1);
6063 
6064         // Search kernel
6065         if (!pKernelDllState->pfnSearchKernel(pKernelDllState, pSearchState))
6066         {
6067             VPHAL_RENDER_ASSERTMESSAGE("Failed to find a kernel.");
6068             eStatus = MOS_STATUS_UNKNOWN;
6069             goto finish;
6070         }
6071 
6072         // Build kernel
6073         if (!pKernelDllState->pfnBuildKernel(pKernelDllState, pSearchState))
6074         {
6075             VPHAL_RENDER_ASSERTMESSAGE("Failed to build kernel.");
6076             eStatus = MOS_STATUS_UNKNOWN;
6077             goto finish;
6078         }
6079 
6080         // Load resulting kernel into kernel cache
6081         pKernelEntry = KernelDll_AddKernel(
6082                            pKernelDllState,
6083                            pSearchState,
6084                            pFilter,
6085                            iFilterSize,
6086                            dwKernelHash);
6087 
6088         if (!pKernelEntry)
6089         {
6090             VPHAL_RENDER_ASSERTMESSAGE("Failed to store kernel in local cache.");
6091             eStatus = MOS_STATUS_UNKNOWN;
6092             goto finish;
6093         }
6094     }
6095     else
6096     {
6097         VPHAL_RENDER_NORMALMESSAGE("Use previous kernel list.");
6098     }
6099 
6100     RenderingData.bCmFcEnable  = pKernelDllState->bEnableCMFC ? true : false;
6101 
6102     RenderingData.bAlphaCalculateEnable = pCompParams->bAlphaCalculateEnable;
6103 
6104     RenderingData.pKernelEntry = pKernelEntry;
6105     RenderingData.pProcamp     = m_Procamp;
6106 
6107     //============================
6108     // Return RT Primaries to the app
6109     //============================
6110     if (pFilter[iFilterSize - 1].layer == Layer_RenderTarget)
6111     {
6112         pSource = &pCompParams->Target[0];
6113         switch (pFilter[iFilterSize - 1].cspace)
6114         {
6115             case CSpace_xvYCC709:
6116                 pSource->ExtendedGamut = true;
6117                 pSource->ColorSpace    = CSpace_BT709;
6118                 break;
6119             case CSpace_BT709:
6120                 pSource->ExtendedGamut = false;
6121                 pSource->ColorSpace    = CSpace_BT709;
6122                 break;
6123             case CSpace_BT709_FullRange:
6124                 pSource->ExtendedGamut = false;
6125                 pSource->ColorSpace    = CSpace_BT709_FullRange;
6126                 break;
6127             case CSpace_xvYCC601:
6128                 pSource->ExtendedGamut = true;
6129                 pSource->ColorSpace    = CSpace_BT601;
6130                 break;
6131             case CSpace_BT601:
6132                 pSource->ExtendedGamut = false;
6133                 pSource->ColorSpace    = CSpace_BT601;
6134                 break;
6135             case CSpace_BT601_FullRange:
6136                 pSource->ExtendedGamut = false;
6137                 pSource->ColorSpace    = CSpace_BT601_FullRange;
6138                 break;
6139             case CSpace_BT2020:
6140                 pSource->ExtendedGamut = false;
6141                 pSource->ColorSpace    = CSpace_BT2020;
6142             case CSpace_BT2020_FullRange:
6143                 pSource->ExtendedGamut = false;
6144                 pSource->ColorSpace    = CSpace_BT2020_FullRange;
6145             case CSpace_BT2020_RGB:
6146                 pSource->ExtendedGamut = false;
6147                 pSource->ColorSpace    = CSpace_BT2020_RGB;
6148             case CSpace_BT2020_stRGB:
6149                 pSource->ExtendedGamut = false;
6150                 pSource->ColorSpace    = CSpace_BT2020_stRGB;
6151             default:
6152                 pSource->ExtendedGamut = false;
6153                 pSource->ColorSpace    = CSpace_sRGB;
6154                 break;
6155         }
6156     }
6157 
6158     if (m_bFtrMediaWalker && (!m_bFtrComputeWalker))
6159     {
6160         pBatchBuffer  = nullptr;
6161         pWalkerParams = &WalkerParams;
6162 
6163         MOS_ZeroMemory(&WalkerParams, sizeof(WalkerParams));
6164 
6165         // calculates media object walker static data fields
6166         if (!RenderBufferMediaWalker(
6167                  pBatchBuffer,
6168                  &RenderingData,
6169                  &WalkerParams))
6170         {
6171             VPHAL_RENDER_ASSERTMESSAGE("Failed to render media walker batch.");
6172             eStatus = MOS_STATUS_UNKNOWN;
6173             goto finish;
6174         }
6175 
6176         // Send Media states for compositing
6177         if (!SubmitStates(&RenderingData))
6178         {
6179             VPHAL_RENDER_ASSERTMESSAGE("Failed to submit compositing states.");
6180             eStatus = MOS_STATUS_UNKNOWN;
6181             goto finish;
6182         }
6183 
6184         // The VfeScoreboard is set after Vphal_CompSubmitStates calls pRenderHal->pfnSetVfeStateParams()
6185         pWalkerParams->UseScoreboard  = pRenderHal->VfeScoreboard.ScoreboardEnable;
6186         pWalkerParams->ScoreboardMask = pRenderHal->VfeScoreboard.ScoreboardMask;
6187     }
6188     else if (m_bFtrComputeWalker)
6189     {
6190         pBatchBuffer         = nullptr;
6191         pWalkerParams        = nullptr;
6192         pComputeWalkerParams = &ComputeWalkerParams;
6193 
6194         MOS_ZeroMemory(&ComputeWalkerParams, sizeof(ComputeWalkerParams));
6195 
6196         // calculates media object walker static data fields
6197         if (!RenderBufferComputeWalker(
6198                  pBatchBuffer,
6199                  &RenderingData,
6200                  &ComputeWalkerParams))
6201         {
6202             VPHAL_RENDER_ASSERTMESSAGE("Failed to render media walker batch.");
6203             eStatus = MOS_STATUS_UNKNOWN;
6204             goto finish;
6205         }
6206 
6207         // Send Media states for compositing
6208         if (!SubmitStates(&RenderingData))
6209         {
6210             VPHAL_RENDER_ASSERTMESSAGE("Failed to submit compositing states.");
6211             eStatus = MOS_STATUS_UNKNOWN;
6212             goto finish;
6213         }
6214     }
6215     else
6216     {
6217         // Send Media states for compositing
6218         if (!SubmitStates(&RenderingData))
6219         {
6220             VPHAL_RENDER_ASSERTMESSAGE("Failed to submit compositing states.");
6221             eStatus = MOS_STATUS_UNKNOWN;
6222             goto finish;
6223         }
6224 
6225         // Get a valid batch buffer (find a match if possible)
6226         VPHAL_RENDER_CHK_STATUS(AllocateBuffer(&RenderingData, &pBatchBuffer));
6227 
6228         // No match was found - render a new batch buffer
6229         if (!((PVPHAL_BATCH_BUFFER_PARAMS)pBatchBuffer->pPrivateData)->bMatch)
6230         {
6231             if (!RenderBuffer(
6232                      pBatchBuffer,
6233                      &RenderingData))
6234             {
6235                 VPHAL_RENDER_ASSERTMESSAGE("Failed to render batch buffers.");
6236                 eStatus = MOS_STATUS_UNKNOWN;
6237                 goto finish;
6238             }
6239         }
6240 
6241         // Set CallID to avoid BB reuse in the same call
6242         ((PVPHAL_BATCH_BUFFER_PARAMS)pBatchBuffer->pPrivateData)->iCallID = m_iCallID;
6243     }
6244 
6245     // Enable extra PIPE_CONTROL in command buffer for CMFC Coeff Surface update
6246     if (RenderingData.bCmFcEnable)
6247     {
6248         pRenderHal->bCmfcCoeffUpdate  = true;
6249         pRenderHal->pCmfcCoeffSurface = &m_CmfcCoeff.OsResource;
6250     }
6251     else
6252     {
6253         pRenderHal->bCmfcCoeffUpdate  = false;
6254         pRenderHal->pCmfcCoeffSurface = nullptr;
6255     }
6256 
6257     VPHAL_DBG_STATE_DUMPPER_DUMP_GSH(pRenderHal);
6258     VPHAL_DBG_STATE_DUMPPER_DUMP_SSH(pRenderHal);
6259     VPHAL_DBG_STATE_DUMPPER_DUMP_BATCH_BUFFER(pRenderHal, pBatchBuffer);
6260 
6261     VPHAL_RENDER_CHK_STATUS(VpHal_RndrSubmitCommands(
6262         pRenderHal,
6263         pBatchBuffer,
6264         m_bNullHwRenderComp,
6265         pWalkerParams,
6266         pComputeWalkerParams,
6267         &m_StatusTableUpdateParams,
6268         kernelCombinedFc,
6269         m_KernelSearch.KernelCount,
6270         m_KernelSearch.KernelID,
6271         m_bLastPhase));
6272 
6273 finish:
6274     // clean rendering data
6275     CleanRenderingData(&RenderingData);
6276     pRenderHal->bCmfcCoeffUpdate  = false;
6277     pRenderHal->pCmfcCoeffSurface = nullptr;
6278     return eStatus;
6279 }
6280 
6281 //!
6282 //! \brief    Build filter description for dynamic linking
6283 //! \details  Build filter description(render method, current layer, layer format, layer
6284 //!           rotation, layer colorspace, sampling mode, scaling mode, luma key, blending,
6285 //!           colorfill, procamp, CSC) for dynamic linking
6286 //!           parameters
6287 //! \param    [in] pCompParams
6288 //!           Pointer to Composite parameters
6289 //! \param    [out] pFilter
6290 //!           Pointer to first filter entry
6291 //! \param    [out] piFilterSize
6292 //!           Pointer to filter size
6293 //! \return   bool
6294 //!           Return true if successful, otherwise false
6295 //!
BuildFilter(PVPHAL_COMPOSITE_PARAMS pCompParams,PKdll_FilterEntry pFilter,int32_t * piFilterSize)6296 bool CompositeState::BuildFilter(
6297     PVPHAL_COMPOSITE_PARAMS         pCompParams,
6298     PKdll_FilterEntry               pFilter,
6299     int32_t*                        piFilterSize)
6300 {
6301     PVPHAL_SURFACE              pSrc;
6302     VPHAL_CSPACE                cspace_main;
6303     int32_t                     iMaxFilterSize;
6304     bool                        bColorFill, bLumaKey;
6305     int32_t                     i;
6306     PRECT                       pTargetRect;
6307     RENDERHAL_SURFACE           RenderHalSurface;
6308     bool                        bNeed;
6309     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
6310 
6311     VPHAL_RENDER_ASSERT(pCompParams);
6312     VPHAL_RENDER_ASSERT(pFilter);
6313     VPHAL_RENDER_ASSERT(piFilterSize);
6314 
6315     cspace_main    = CSpace_sRGB;                   // Default colorspace
6316     *piFilterSize  = 0;
6317     iMaxFilterSize = DL_MAX_SEARCH_FILTER_SIZE - 1; // Save one entry for Render Target
6318     pTargetRect    = &(pCompParams->Target[0].rcDst);
6319 
6320     // Initialize ColorFill flag
6321     bColorFill = (pCompParams->pColorFillParams != nullptr);
6322 
6323     for (i = 0; (i < (int)pCompParams->uSourceCount) && (iMaxFilterSize > 0); i++)
6324     {
6325         pSrc = pCompParams->pSource[i];
6326 
6327         //--------------------------------
6328         // Skip non-visible layers
6329         //--------------------------------
6330         if (pSrc->iLayerID < 0)
6331         {
6332             continue;
6333         }
6334 
6335         //--------------------------------
6336         // Composition path does not support conversion from BT2020 RGB to BT2020 YUV, BT2020->BT601/BT709, BT601/BT709 -> BT2020
6337         //--------------------------------
6338         if (IS_COLOR_SPACE_BT2020_RGB(pSrc->ColorSpace)   &&
6339             IS_COLOR_SPACE_BT2020_YUV(pCompParams->Target[0].ColorSpace))  //BT2020 RGB->BT2020 YUV
6340         {
6341             eStatus = MOS_STATUS_UNIMPLEMENTED;
6342         }
6343         else if (IS_COLOR_SPACE_BT2020(pSrc->ColorSpace) &&
6344                  !IS_COLOR_SPACE_BT2020(pCompParams->Target[0].ColorSpace)) //BT2020->BT601/BT709
6345         {
6346             eStatus = MOS_STATUS_UNIMPLEMENTED;
6347         }
6348         else if (!IS_COLOR_SPACE_BT2020(pSrc->ColorSpace) &&
6349                  IS_COLOR_SPACE_BT2020(pCompParams->Target[0].ColorSpace))  //BT601/BT709 -> BT2020
6350         {
6351             eStatus = MOS_STATUS_UNIMPLEMENTED;
6352         }
6353 
6354         if (eStatus == MOS_STATUS_UNIMPLEMENTED)
6355         {
6356             goto finish;
6357         }
6358 
6359         //--------------------------------
6360         // Set render method
6361         //--------------------------------
6362         pFilter->RenderMethod = m_bFtrMediaWalker ? RenderMethod_MediaObjectWalker : RenderMethod_MediaObject;
6363 
6364         //--------------------------------
6365         // Set CSC coefficient setting method for CoeffID_0
6366         //--------------------------------
6367         pFilter->SetCSCCoeffMode = m_bFtrCSCCoeffPatchMode ? SetCSCCoeffMethod_Patch : SetCSCCoeffMethod_Curbe;
6368 
6369         //--------------------------------
6370         // Set current layer
6371         //--------------------------------
6372         pFilter->layer = g_cSurfaceType_Layer[pSrc->SurfType];
6373 
6374         //--------------------------------
6375         // Set layer format
6376         //--------------------------------
6377         pFilter->format = pSrc->Format;
6378 
6379         // On G8, NV12 format needs the width and Height to be a multiple of 4 for both
6380         // 3D sampler and 8x8 sampler; G75 needs the width of NV12 input surface to be
6381         // a multiple of 4 for 3D sampler; G9 does not has such restriction; to simplify the
6382         // implementation, we enable 2 plane NV12 for all of the platform when the width
6383         // or Height is not a multiple of 4. Here to set the filter format in order to select
6384         // the PL2 kernel when building the combined kernel.
6385         VPHAL_RENDER_CHK_STATUS(VpHal_RndrCommonInitRenderHalSurface(pSrc, &RenderHalSurface));
6386         bNeed = m_pRenderHal->pfnIs2PlaneNV12Needed(
6387                 m_pRenderHal,
6388                 &RenderHalSurface,
6389                 RENDERHAL_SS_BOUNDARY_SRCRECT) ? true : false;
6390         bNeed |= IsNV12SamplerLumakeyNeeded(pSrc, m_pRenderHal) && i;
6391         if (bNeed)
6392         {
6393             if (pFilter->format == Format_NV12)
6394             {
6395                 pFilter->format = Format_NV12_UnAligned;
6396             }
6397             else if (pFilter->format == Format_P208)
6398             {
6399                 pFilter->format = Format_P208_UnAligned;
6400             }
6401             else if (pFilter->format == Format_NV11)
6402             {
6403                 pFilter->format = Format_NV11_UnAligned;
6404             }
6405             else if (pFilter->format == Format_PL2)
6406             {
6407                 pFilter->format = Format_PL2_UnAligned;
6408             }
6409         }
6410 
6411         // Y_Uoffset(Height*2 + Height/2) of RENDERHAL_PLANES_YV12 define Bitfield_Range(0, 13) on gen9+.
6412         // The max value is 16383. So use PL3 kernel to avoid out of range when Y_Uoffset is larger than 16383.
6413         // Use PL3 plane to avoid YV12 blending issue with DI enabled and U channel shift issue with not 4-aligned height
6414         if ((pFilter->format   == Format_YV12)           &&
6415             (pSrc->ScalingMode != VPHAL_SCALING_AVS)     &&
6416             (pSrc->bIEF        != true)                  &&
6417             (pSrc->SurfType    != SURF_OUT_RENDERTARGET) &&
6418             m_pRenderHal->bEnableYV12SinglePass          &&
6419             !pSrc->pDeinterlaceParams                    &&
6420             !pSrc->bInterlacedScaling                    &&
6421             MOS_IS_ALIGNED(pSrc->dwHeight, 4)            &&
6422             ((pSrc->dwHeight * 2 + pSrc->dwHeight / 2) < RENDERHAL_MAX_YV12_PLANE_Y_U_OFFSET_G9))
6423         {
6424             pFilter->format = Format_YV12_Planar;
6425         }
6426 
6427         if (pFilter->format == Format_A8R8G8B8 ||
6428             pFilter->format == Format_X8R8G8B8 ||
6429             pFilter->format == Format_A8B8G8R8 ||
6430             pFilter->format == Format_X8B8G8R8 ||
6431             pFilter->format == Format_R5G6B5)
6432         {
6433             pFilter->format = Format_RGB;
6434         }
6435 
6436         //--------------------------------
6437         // Set layer rotation
6438         //--------------------------------
6439         pFilter->rotation = pSrc->Rotation;
6440 
6441         //--------------------------------
6442         // Set layer color space
6443         //--------------------------------
6444         // Source is palletized, leave CSC to software (driver)
6445         if (IS_PAL_FORMAT(pFilter->format))
6446         {
6447             pFilter->cspace = CSpace_Any;
6448         }
6449         // Source is YUV or RGB, set primaries
6450         else
6451         {
6452             pFilter->cspace = pSrc->ColorSpace;
6453         }
6454 
6455         // Save color space of main video
6456         if (pSrc->SurfType == SURF_IN_PRIMARY)
6457         {
6458             cspace_main = pFilter->cspace;
6459         }
6460 
6461         //--------------------------------
6462         // Set sampling mode
6463         //--------------------------------
6464         bLumaKey = (pSrc->pLumaKeyParams != nullptr);
6465 
6466         // Progressive main video (except RGB format) or for RGB10, use AVS
6467         if (pSrc->bUseSampleUnorm)
6468         {
6469             pFilter->sampler = (pSrc->bInterlacedScaling || pSrc->bFieldWeaving) ? Sample_iScaling : Sample_Scaling;
6470         }
6471         else
6472         {
6473             pFilter->sampler = (pSrc->ScalingMode == VPHAL_SCALING_AVS && !IsBobDiEnabled(pSrc)) ?
6474                 (pSrc->bInterlacedScaling ? Sample_iScaling_AVS : Sample_Scaling_AVS) :
6475                 (pSrc->bInterlacedScaling || pSrc->bFieldWeaving) ? Sample_iScaling_034x : Sample_Scaling_034x;
6476         }
6477 
6478         // When input format is Format_R10G10B10A2/Format_B10G10R10A2/Y410(kernel regards Y410 as Format_R10G10B10A2)
6479         // Dscale kernel should be used
6480         if (pSrc->Format == Format_R10G10B10A2 ||
6481             pSrc->Format == Format_B10G10R10A2 ||
6482             pSrc->Format == Format_Y410        ||
6483             pSrc->Format == Format_Y416)
6484         {
6485             pFilter->bEnableDscale = true;
6486         }
6487         else
6488         {
6489             pFilter->bEnableDscale = false;
6490         }
6491 
6492         if (m_bFtrComputeWalker)
6493         {
6494             pFilter->bWaEnableDscale = true;
6495         }
6496         else
6497         {
6498             pFilter->bWaEnableDscale = MEDIA_IS_WA(m_pWaTable, WaEnableDscale);
6499         }
6500 
6501         //--------------------------------
6502         // Set Luma key
6503         //--------------------------------
6504         if (bLumaKey)
6505         {
6506             pFilter->lumakey = LumaKey_True;
6507             pFilter->samplerlumakey = pSrc->bUseSamplerLumakey ? LumaKey_True : LumaKey_False;
6508         }
6509         else
6510         {
6511             pFilter->lumakey = LumaKey_False;
6512             pFilter->samplerlumakey = LumaKey_False;
6513         }
6514 
6515         //--------------------------------
6516         // Select function
6517         //--------------------------------
6518         if (pSrc->pBlendingParams != nullptr)
6519         {
6520             switch (pSrc->pBlendingParams->BlendType)
6521             {
6522                 case BLEND_SOURCE:
6523                     if (IS_ALPHA4_FORMAT(pSrc->Format))
6524                     {
6525                         pFilter->process = Process_SBlend_4bits;
6526                     }
6527                     else
6528                     {
6529                         pFilter->process = Process_SBlend;
6530                     }
6531                     break;
6532 
6533                 case BLEND_PARTIAL:
6534                     pFilter->process = Process_PBlend;
6535                     break;
6536 
6537                 case BLEND_CONSTANT:
6538                     pFilter->process = Process_CBlend;
6539                     break;
6540 
6541                 case BLEND_CONSTANT_SOURCE:
6542                     pFilter->process = Process_CSBlend;
6543                     break;
6544 
6545                 case BLEND_CONSTANT_PARTIAL:
6546                     pFilter->process = Process_CPBlend;
6547                     break;
6548 
6549                 case BLEND_NONE:
6550                 default:
6551                     pFilter->process = Process_Composite;
6552                     break;
6553             }
6554         }
6555         else
6556         {
6557             pFilter->process = Process_Composite;
6558         }
6559 
6560         if (pFilter->samplerlumakey && pFilter->process != Process_Composite)
6561         {
6562             VPHAL_RENDER_ASSERTMESSAGE("Invalid kll processing for sampler lumakey! Sampler lumakey can only work with composition.");
6563             pFilter->samplerlumakey = LumaKey_False;
6564         }
6565 
6566         //--------------------------------
6567         // Set color fill
6568         //--------------------------------
6569         if (*piFilterSize == 0 &&
6570             (bLumaKey ||
6571              (bColorFill && (!RECT1_CONTAINS_RECT2(pSrc->rcDst, pCompParams->Target[0].rcDst))) ||
6572              (!pCompParams->bForceSkipColorFill &&
6573              ((pFilter->process == Process_PBlend) ||
6574               (pFilter->process == Process_CBlend) ||
6575               (pFilter->process == Process_SBlend) ||
6576               (pFilter->process == Process_CSBlend)))))
6577         {
6578             pFilter->colorfill = ColorFill_True;
6579         }
6580         else
6581         {
6582             pFilter->colorfill = ColorFill_False;
6583         }
6584 
6585         //--------------------------------
6586         // Set Procamp parameters
6587         //--------------------------------
6588         if (pSrc->pProcampParams && pSrc->pProcampParams->bEnabled)
6589         {
6590             pFilter->procamp = 0;
6591         }
6592         else
6593         {
6594             pFilter->procamp = DL_PROCAMP_DISABLED;
6595         }
6596 
6597         //--------------------------------
6598         // Set chromasiting parameters
6599         //--------------------------------
6600         pFilter->chromasiting = DL_CHROMASITING_DISABLE;
6601         if (pSrc->bChromaSiting)
6602         {
6603             pFilter->chromasiting = 0 ;
6604         }
6605 
6606         //--------------------------------
6607         // reset CSC
6608         //--------------------------------
6609         pFilter->matrix = DL_CSC_DISABLED;
6610 
6611         if (0 == pSrc->iLayerID)
6612         {
6613            //set first layer's scalingRatio
6614            SetFilterScalingRatio(&(pFilter->ScalingRatio));
6615         }
6616 
6617         // Update filter
6618         pFilter++;
6619         (*piFilterSize)++;
6620         iMaxFilterSize--;
6621     }
6622 
6623     //-----------------------------------------
6624     // Set Render Target parameters
6625     //-----------------------------------------
6626     if (pCompParams->uTargetCount == 2)
6627     {
6628         pFilter->dualout = true;
6629     }
6630     pSrc = &pCompParams->Target[0];
6631     pFilter->RenderMethod    = m_bFtrMediaWalker ? RenderMethod_MediaObjectWalker : RenderMethod_MediaObject;
6632     pFilter->SetCSCCoeffMode = m_bFtrCSCCoeffPatchMode ? SetCSCCoeffMethod_Patch : SetCSCCoeffMethod_Curbe;
6633     pFilter->layer    = Layer_RenderTarget;
6634     pFilter->format   = pSrc->Format;
6635     pFilter->tiletype = pSrc->TileType;
6636     pFilter->sampler  = Sample_None;
6637     pFilter->process  = Process_None;
6638     pFilter->procamp  = DL_PROCAMP_DISABLED;
6639     pFilter->matrix   = DL_CSC_DISABLED;
6640     pFilter->bFillOutputAlphaWithConstant = true;
6641 
6642     //set rendertarget's scalingRatio
6643     SetFilterScalingRatio(&(pFilter->ScalingRatio));
6644 
6645     if(pCompParams->pSource[0] != nullptr &&
6646        pCompParams->pSource[0]->Format == Format_R5G6B5 &&
6647        pCompParams->Target[0].Format == Format_R5G6B5)
6648     {
6649         pFilter->bIsDitherNeeded = false;
6650     }else
6651     {
6652         pFilter->bIsDitherNeeded = true;
6653     }
6654 
6655     if (pFilter->format == Format_A8R8G8B8    ||
6656         pFilter->format == Format_A8B8G8R8    ||
6657         pFilter->format == Format_R10G10B10A2 ||
6658         pFilter->format == Format_B10G10R10A2 ||
6659         pFilter->format == Format_AYUV        ||
6660         pFilter->format == Format_Y416)
6661     {
6662         if (pCompParams->pCompAlpha != nullptr && pCompParams->pSource[0] != nullptr &&
6663             (pCompParams->pCompAlpha->AlphaMode == VPHAL_ALPHA_FILL_MODE_NONE ||
6664              pCompParams->pCompAlpha->AlphaMode == VPHAL_ALPHA_FILL_MODE_SOURCE_STREAM))
6665         {
6666             // When layer 0 does not have alpha channel, Save_RGB will be linked instead of
6667             // Save_ARGB, to avoid output alpha value corruption.
6668             switch (pCompParams->pSource[0]->Format)
6669             {
6670                 case Format_AYUV:
6671                 case Format_AUYV:
6672                 case Format_AI44:
6673                 case Format_IA44:
6674                 case Format_A8R8G8B8:
6675                 case Format_A8B8G8R8:
6676                 case Format_R10G10B10A2:
6677                 case Format_B10G10R10A2:
6678                 case Format_A8P8:
6679                 case Format_A8:
6680                 case Format_Y416:
6681                     pFilter->bFillOutputAlphaWithConstant = false;
6682                     break;
6683 
6684                 default:
6685                     break;
6686             }
6687         }
6688     }
6689 
6690     // If Rotation is done in sampler. Multiple phases are not required.
6691     if ((!m_bSamplerSupportRotation) &&
6692         (pCompParams->uSourceCount > 0))
6693     {
6694         // either single layer L0 or all layer with the same rotation degree.
6695         pFilter->rotation = pCompParams->pSource[0]->Rotation;
6696     }
6697 
6698     //-------------------------------------------------------
6699     // Set color fill for RT. Valid for colorfill only cases
6700     //-------------------------------------------------------
6701     // If filter size is zero i.e. number of layers is zero, set colorfill to true.
6702     if (*piFilterSize == 0)
6703     {
6704         if(bColorFill)
6705         {
6706             pFilter->colorfill = ColorFill_True;
6707         }
6708         else
6709         {
6710             eStatus = MOS_STATUS_UNIMPLEMENTED;
6711             goto finish;
6712         }
6713     }
6714     else
6715     {
6716         pFilter->colorfill = ColorFill_False;
6717     }
6718 
6719     // Get App supplied RT format
6720     pFilter->cspace = pSrc->ColorSpace;
6721 
6722     // Update filter
6723     (*piFilterSize)++;
6724 
6725 finish:
6726     return ((eStatus == MOS_STATUS_SUCCESS) ? true : false);
6727 }
6728 
6729 //!
6730 //! \brief    Initialize Colorfill parameters
6731 //! \details  Initialize Colorfill parameters
6732 //! \return   void
6733 //!
InitColorFillParams()6734 void CompositeState::InitColorFillParams()
6735 {
6736     m_csSrc.dwValue   = 0;
6737     m_csDst.dwValue   = 0;
6738     m_CSpaceSrc       = CSpace_None;
6739     m_CSpaceDst       = CSpace_None;
6740 }
6741 
6742 //!
6743 //! \brief    Check if sample unorm being used for source surface.
6744 //! \param    [in] pCompParams
6745 //!           Pointer to Composite parameters
6746 //! \param    pSrc
6747 //!           [in] Pointer to Source Surface
6748 //! \return   bool
6749 //!           Return TRUE if use sample unorm, otherwise FALSE
6750 //!
IsUsingSampleUnorm(PVPHAL_COMPOSITE_PARAMS pCompParams,PVPHAL_SURFACE pSrc)6751 bool CompositeState::IsUsingSampleUnorm(
6752     PVPHAL_COMPOSITE_PARAMS         pCompParams,
6753     PVPHAL_SURFACE                  pSrc)
6754 {
6755     float                       fStepX = 0, fStepY = 0;
6756     float                       fAdjustX = 0, fAdjustY = 0;
6757     bool                        bRet;
6758     PRECT                       pTargetRect = {0};
6759 
6760     if (nullptr == pCompParams || nullptr == pSrc)
6761     {
6762         VPHAL_RENDER_ASSERTMESSAGE("nullptr for input parameters");
6763         bRet = false;
6764         goto finish;
6765     }
6766 
6767     // Force using sampler16 when compute walker in use
6768     if (m_bFtrComputeWalker)
6769     {
6770         bRet = false;
6771         goto finish;
6772     }
6773 
6774     pTargetRect    = &(pCompParams->Target[0].rcDst);
6775     if (pCompParams->pConstriction)
6776     {
6777         fAdjustX = (pTargetRect->right  - pTargetRect->left) * 1.0f /
6778             pCompParams->pConstriction->right;
6779         fAdjustY = (pTargetRect->bottom - pTargetRect->top ) * 1.0f /
6780             pCompParams->pConstriction->bottom;
6781     }
6782     else
6783     {
6784         fAdjustX = fAdjustY = 1.0f;
6785     }
6786     // Calculate scaling factor for X and Y (include BOB DI)
6787     if (pSrc->Rotation == VPHAL_ROTATION_IDENTITY ||
6788         pSrc->Rotation == VPHAL_ROTATION_180      ||
6789         pSrc->Rotation == VPHAL_MIRROR_HORIZONTAL ||
6790         pSrc->Rotation == VPHAL_MIRROR_VERTICAL)
6791     {
6792         fStepX = (pSrc->rcSrc.right  - pSrc->rcSrc.left) * fAdjustX /
6793                     ((pSrc->rcDst.right  - pSrc->rcDst.left) > 0 ?
6794                     (pSrc->rcDst.right  - pSrc->rcDst.left) : 1);
6795         fStepY = (pSrc->rcSrc.bottom - pSrc->rcSrc.top ) * fAdjustY /
6796                     ((pSrc->rcDst.bottom - pSrc->rcDst.top ) > 0 ?
6797                     (pSrc->rcDst.bottom - pSrc->rcDst.top ) : 1);
6798     }
6799     else
6800     {
6801         // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 ||
6802         fStepX = (pSrc->rcSrc.right  - pSrc->rcSrc.left) * fAdjustX /
6803                     ((pSrc->rcDst.bottom - pSrc->rcDst.top ) > 0 ?
6804                     (pSrc->rcDst.bottom - pSrc->rcDst.top ) : 1);
6805         fStepY = (pSrc->rcSrc.bottom - pSrc->rcSrc.top ) * fAdjustY /
6806                     ((pSrc->rcDst.right  - pSrc->rcDst.left) > 0 ?
6807                     (pSrc->rcDst.right  - pSrc->rcDst.left) : 1);
6808     }
6809     if (IsBobDiEnabled(pSrc) &&
6810         pSrc->ScalingMode != VPHAL_SCALING_AVS)
6811     {
6812         fStepY *= 0.5f;
6813     }
6814 
6815     // Progressive main video (except RGB format) or for RGB10, use AVS
6816     if ((pSrc->ScalingMode == VPHAL_SCALING_AVS) &&
6817         !IsBobDiEnabled(pSrc))
6818     {
6819         // GEN8 cannot support YV12 input format for iAVS scaling
6820         if (pSrc->bInterlacedScaling && !m_bYV12iAvsScaling && pSrc->Format == Format_YV12)
6821         {
6822             bRet = true;
6823             goto finish;
6824         }
6825         else
6826         {
6827             bRet = false;  // AVS
6828             goto finish;
6829         }
6830     }
6831     else
6832     {
6833         if (pSrc->Format == Format_R10G10B10A2   ||
6834             pSrc->Format == Format_B10G10R10A2   ||
6835             pSrc->Format == Format_Y410          ||
6836             pSrc->Format == Format_Y416)
6837         {
6838             bRet = false;  // DScaler
6839             goto finish;
6840         }
6841         else if (fStepX >= 3.0f || fStepY >= 3.0f)
6842         {
6843             return !MEDIA_IS_WA(m_pWaTable, WaEnableDscale);
6844         }
6845         else
6846         {
6847             bRet = true;
6848             goto finish;
6849         }
6850     }
6851 
6852 finish:
6853     return bRet;
6854 }
6855 
6856 //!
6857 //! \brief    Check if sampler lumakey being supported or not for source surface.
6858 //! \param    pSrc
6859 //!           [in] Pointer to Source Surface
6860 //! \return   bool
6861 //!           Return TRUE if support, otherwise FALSE
6862 //!
IsSamplerLumakeySupported(PVPHAL_SURFACE pSrc)6863 bool CompositeState::IsSamplerLumakeySupported(PVPHAL_SURFACE pSrc)
6864 {
6865     // The kernel is different b/w sampler luma key and EU computed luma key.
6866     // Sampler based: IDR_VP_Prepare_LumaKey_SampleUnorm
6867     // EU computed:   IDR_VP_Compute_Lumakey
6868     // When sampler lumakey being enabled by set pUnormSampler->DW1.ChromakeyEnable to 1, a lumakey mask will be generated
6869     // during sampler scaling.
6870     // IDR_VP_Prepare_LumaKey_SampleUnorm is used to prepare lumakey related parameters for composition according to the
6871     // lumakey mask, and the result will be put in the common registers. To avoid the result being overwriten by other
6872     // operation, IDR_VP_Prepare_LumaKey_SampleUnorm need to be called rigth before IDR_VP_Call_Composite.
6873     // Following are the conditions to enable sampler lumakey.
6874     // 1 Flag m_bEnableSamplerLumakey is set to true.
6875     // 2 Lumakey is needed for current layer.
6876     // 3 Enable sampler lumakey only for composition.
6877     // 4 Disable sampler lumakey if there's no AVS as back up for layer 0
6878     // 5 Enable sampler lumakey only on YUY2 and NV12 surfaces due to hw limitation.
6879     // 6 Enable sampler lumakey feature only if this lumakey layer is not the bottom layer.
6880     // 7 Enable sampler lumakey only when sample unorm being used.
6881     // 8 Disable sampler lumakey for mirror case, since mirror is done after sampler scaling, which cause the lumakey mask
6882     //   not matching the layer any more.
6883     return m_bEnableSamplerLumakey                                                              &&
6884             pSrc->pLumaKeyParams != NULL                                                        &&
6885             (pSrc->pBlendingParams == NULL || pSrc->pBlendingParams->BlendType == BLEND_NONE)   &&
6886             !m_need3DSampler                                                                    &&
6887             (pSrc->Format == Format_YUY2 || pSrc->Format == Format_NV12)                        &&
6888             pSrc->iLayerID                                                                      &&
6889             pSrc->bUseSampleUnorm                                                               &&
6890             pSrc->Rotation < VPHAL_MIRROR_HORIZONTAL;
6891 }
6892 
6893 //!
6894 //! \brief    Initialize Composite state
6895 //! \details  Initialize Composite state, including setup KernelDLL/Procamp/Colorfill
6896 //! \param    [in] pSettings
6897 //!           Pointer to VPHAL Settings
6898 //! \param    [in] pKernelDllState
6899 //!           Pointer to KernelDLL State
6900 //! \return   MOS_STATUS
6901 //!           Return MOS_STATUS_SUCCESS if successful
6902 //!
Initialize(const VphalSettings * pSettings,Kdll_State * pKernelDllState)6903 MOS_STATUS CompositeState::Initialize(
6904     const VphalSettings             *pSettings,
6905     Kdll_State                      *pKernelDllState)
6906 {
6907     MOS_USER_FEATURE_VALUE_DATA     UserFeatureData;
6908     MOS_NULL_RENDERING_FLAGS        NullRenderingFlags;
6909     bool                            bAllocated;
6910     MOS_STATUS                      eStatus;
6911 
6912     eStatus = MOS_STATUS_SUCCESS;
6913 
6914     MOS_UNUSED(pSettings);
6915     VPHAL_RENDER_CHK_NULL(pKernelDllState);
6916 
6917     if (m_reporting == nullptr)
6918     {
6919         m_reporting = MOS_New(VphalFeatureReport);
6920     }
6921 
6922 #if (_DEBUG || _RELEASE_INTERNAL)
6923     // Read user feature key to enable 8-tap adaptive filter;
6924     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
6925     MOS_USER_FEATURE_INVALID_KEY_ASSERT(MOS_UserFeature_ReadValue_ID(
6926         nullptr,
6927         __VPHAL_COMP_8TAP_ADAPTIVE_ENABLE_ID,
6928         &UserFeatureData));
6929     m_b8TapAdaptiveEnable = UserFeatureData.bData ? true : false;
6930 #endif
6931 
6932     NullRenderingFlags = m_pOsInterface->pfnGetNullHWRenderFlags(
6933                         m_pOsInterface);
6934 
6935     m_bNullHwRenderComp =
6936                     NullRenderingFlags.VPComp ||
6937                     NullRenderingFlags.VPGobal;
6938 
6939     // Setup kernelDLLL
6940     m_pKernelDllState = pKernelDllState;
6941 
6942     if (m_pKernelDllState->bEnableCMFC)
6943     {
6944         // Allocate auto CSC Coeff Surface
6945         VPHAL_RENDER_CHK_STATUS(VpHal_ReAllocateSurface(
6946             m_pOsInterface,
6947             &m_CmfcCoeff,
6948             "CSCCoeffSurface",
6949             Format_L8,
6950             MOS_GFXRES_2D,
6951             MOS_TILE_LINEAR,
6952             VPHAL_COMP_CMFC_COEFF_WIDTH,
6953             VPHAL_COMP_CMFC_COEFF_HEIGHT,
6954             false,
6955             MOS_MMC_DISABLED,
6956             &bAllocated));
6957     }
6958 
6959     // Setup Procamp Parameters
6960     KernelDll_SetupProcampParameters(pKernelDllState,
6961                                      m_Procamp,
6962                                      m_iMaxProcampEntries);
6963 
6964     // Init Color fill params
6965     InitColorFillParams();
6966 
6967 finish:
6968     return eStatus;
6969 }
6970 
6971 //!
6972 //! \brief    Composite Destructor
6973 //!
~CompositeState()6974 CompositeState::~CompositeState()
6975 {
6976 }
6977 
6978 //!
6979 //! \brief    Composite Destroy function
6980 //! \details  Destroy resource allocated by Composite
6981 //!
Destroy()6982 void CompositeState::Destroy()
6983 {
6984     PRENDERHAL_INTERFACE                pRenderHal;
6985     PMOS_INTERFACE                      pOsInterface;
6986     PMHW_BATCH_BUFFER                   pBuffer;
6987     int32_t                             i;
6988 
6989     VPHAL_RENDER_ASSERT(m_pRenderHal);
6990     VPHAL_RENDER_ASSERT(m_pOsInterface);
6991 
6992     pRenderHal   = m_pRenderHal;
6993     pOsInterface = m_pOsInterface;
6994 
6995     // Destroy Batch Buffers
6996     for (i = 0; i < m_iBatchBufferCount; i++)
6997     {
6998         pBuffer = &m_BatchBuffer[i];
6999         pRenderHal->pfnFreeBB(pRenderHal, pBuffer);
7000     }
7001 
7002     // Free intermediate compositing buffer
7003     pOsInterface->pfnFreeResource(
7004         pOsInterface,
7005         &m_Intermediate.OsResource);
7006 
7007     if (m_Intermediate2.pBlendingParams)
7008     {
7009         MOS_FreeMemory(m_Intermediate2.pBlendingParams);
7010         m_Intermediate2.pBlendingParams = nullptr;
7011     }
7012 
7013     pOsInterface->pfnFreeResource(
7014         pOsInterface,
7015         &m_Intermediate2.OsResource);
7016 
7017     pOsInterface->pfnFreeResource(
7018         pOsInterface,
7019         &m_CmfcCoeff.OsResource);
7020 
7021     // Destroy sampler 8x8 state table parameters
7022     VpHal_RndrCommonDestroyAVSParams(&m_AvsParameters);
7023 }
7024 
7025 //! \brief    Initialize interface for Composite
7026 //! \param    [in] pOsInterface
7027 //!           Pointer to MOS interface structure
7028 //! \param    [in] pRenderHal
7029 //!           Pointer to RenderHal interface structure
7030 //! \param    [in] pPerfData
7031 //!           Pointer to performance data structure
7032 //! \param    [in] compositeCacheCntl
7033 //!           Composite Cache Control Data
7034 //! \return   MOS_STATUS
7035 //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
7036 //!
CompositeState(PMOS_INTERFACE pOsInterface,PRENDERHAL_INTERFACE pRenderHal,PVPHAL_RNDR_PERF_DATA pPerfData,const VPHAL_COMPOSITE_CACHE_CNTL & compositeCacheCntl,MOS_STATUS * peStatus)7037 CompositeState::CompositeState(
7038     PMOS_INTERFACE                      pOsInterface,
7039     PRENDERHAL_INTERFACE                pRenderHal,
7040     PVPHAL_RNDR_PERF_DATA               pPerfData,
7041     const VPHAL_COMPOSITE_CACHE_CNTL    &compositeCacheCntl,
7042     MOS_STATUS                          *peStatus)
7043     : RenderState(pOsInterface, pRenderHal, pPerfData, peStatus),
7044     m_iMaxProcampEntries(0),
7045     m_iProcampVersion(0),
7046     m_bNullHwRenderComp(false),
7047     m_b8TapAdaptiveEnable(false),
7048     m_ThreadCountPrimary(0),
7049     m_iBatchBufferCount(0),
7050     m_iCallID(0),
7051     m_bLastPhase(false),
7052     m_fSamplerLinearBiasX(0),
7053     m_fSamplerLinearBiasY(0),
7054     m_bFtrMediaWalker(false),
7055     m_bFtrComputeWalker(false),
7056     m_bFtrCSCCoeffPatchMode(false),
7057     m_bSamplerSupportRotation(false),
7058     m_bChromaUpSampling(false),
7059     m_bChromaDownSampling(false),
7060     m_bFallbackIefPatch(false),
7061     m_bKernelSupportDualOutput(false),
7062     m_bKernelSupportHdcDW(false),
7063     m_bApplyTwoLayersCompOptimize(false),
7064     m_need3DSampler(false),
7065     m_bEnableSamplerLumakey(false),
7066     m_bYV12iAvsScaling(false),
7067     m_bAvsTableCoeffExtraEnabled(false),
7068     m_bAvsTableBalancedFilter(false)
7069 {
7070     MOS_STATUS                  eStatus = MOS_STATUS_SUCCESS;
7071     MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
7072 
7073     MOS_ZeroMemory(&m_Procamp, sizeof(m_Procamp));
7074     MOS_ZeroMemory(&m_csSrc, sizeof(m_csSrc));
7075     MOS_ZeroMemory(&m_csDst, sizeof(m_csDst));
7076     MOS_ZeroMemory(&m_CSpaceSrc, sizeof(m_CSpaceSrc));
7077     MOS_ZeroMemory(&m_CSpaceDst, sizeof(m_CSpaceDst));
7078     MOS_ZeroMemory(&m_SurfMemObjCtl, sizeof(m_SurfMemObjCtl));
7079     MOS_ZeroMemory(&m_SearchFilter, sizeof(m_SearchFilter));
7080     MOS_ZeroMemory(&m_KernelSearch, sizeof(m_KernelSearch));
7081     MOS_ZeroMemory(&m_KernelParams, sizeof(m_KernelParams));
7082     MOS_ZeroMemory(&m_Intermediate, sizeof(m_Intermediate));
7083     MOS_ZeroMemory(&m_Intermediate2, sizeof(m_Intermediate2));
7084     MOS_ZeroMemory(&m_CmfcCoeff, sizeof(m_CmfcCoeff));
7085     MOS_ZeroMemory(&m_RenderHalCmfcCoeff, sizeof(m_RenderHalCmfcCoeff));
7086     MOS_ZeroMemory(&m_AvsParameters, sizeof(m_AvsParameters));
7087     MOS_ZeroMemory(&m_mhwSamplerAvsTableParam, sizeof(m_mhwSamplerAvsTableParam));
7088     MOS_ZeroMemory(&m_BatchBuffer, sizeof(m_BatchBuffer));
7089     MOS_ZeroMemory(&m_BufferParam, sizeof(m_BufferParam));
7090 
7091     // Set Bilinear Sampler Bias
7092     m_fSamplerLinearBiasX       = VPHAL_SAMPLER_BIAS_GEN575;
7093     m_fSamplerLinearBiasY       = VPHAL_SAMPLER_BIAS_GEN575;
7094 
7095     // Batch buffers
7096     m_iBatchBufferCount         = 0;
7097 
7098     // Procamp
7099     // Set Max number of procamp entries
7100     m_iMaxProcampEntries        = VPHAL_MAX_PROCAMP;
7101     m_iProcampVersion           = 1;
7102 
7103     //CSCCoeffPatchMode
7104     m_bFtrCSCCoeffPatchMode     = true;
7105 
7106     // Cache settings
7107     m_SurfMemObjCtl             = compositeCacheCntl;
7108 
7109     // Composite Kernel
7110     m_KernelParams              = g_cInitKernelParamsComposite;
7111     m_ThreadCountPrimary        = VPHAL_USE_MEDIA_THREADS_MAX;
7112     VPHAL_RENDER_CHK_NULL(pRenderHal);
7113     m_bFtrMediaWalker           = pRenderHal->pfnGetMediaWalkerStatus(pRenderHal) ? true : false;
7114 
7115     MOS_ZeroMemory(&m_mhwSamplerAvsTableParam, sizeof(m_mhwSamplerAvsTableParam));
7116 
7117     VPHAL_RENDER_CHK_NULL(pOsInterface);
7118     // Reset Intermediate output surface (multiple phase)
7119     pOsInterface->pfnResetResourceAllocationIndex(pOsInterface, &m_Intermediate.OsResource);
7120 
7121     MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
7122     MOS_USER_FEATURE_INVALID_KEY_ASSERT(MOS_UserFeature_ReadValue_ID(
7123         nullptr,
7124         __MEDIA_USER_FEATURE_VALUE_CSC_COEFF_PATCH_MODE_DISABLE_ID,
7125         &UserFeatureData));
7126     m_bFtrCSCCoeffPatchMode = UserFeatureData.bData ? false : true;
7127 
7128 finish:
7129     // copy status to output argument to pass status to caller
7130     if (peStatus)
7131     {
7132         *peStatus = eStatus;
7133     }
7134 }
7135 
7136 //!
7137 //! \brief    Judge if Composite render is needed
7138 //! \details  Check Render parameter/data if Composite render needed
7139 //! \param    [in] pcRenderParams
7140 //!           Pointer to Render parameters
7141 //! \param    [in,out] pRenderPassData
7142 //!           Pointer to Render data
7143 //! \return   bool
7144 //!           true if meeded. Else false
7145 //!
7146 // use set render flags
IsNeeded(PCVPHAL_RENDER_PARAMS pcRenderParams,RenderpassData * pRenderPassData)7147 bool CompositeState::IsNeeded(
7148     PCVPHAL_RENDER_PARAMS  pcRenderParams,
7149     RenderpassData         *pRenderPassData)
7150 {
7151     VPHAL_RENDER_ASSERT(pRenderPassData);
7152 
7153     MOS_UNUSED(pcRenderParams);
7154 
7155     return pRenderPassData->bCompNeeded;
7156 }
7157 
7158 //!
7159 //! \brief    Judge if Composite render support multiple stream rendering
7160 //! \details  Judge if Composite render support multiple stream rendering
7161 //! \return   bool
7162 //!           true if supported. Else false
7163 //!
IsMultipleStreamSupported()7164 bool CompositeState::IsMultipleStreamSupported()
7165 {
7166     return true;
7167 }
7168 
7169 //!
7170 //! \brief    set Report data
7171 //! \details  set Report data for this render
7172 //! \param    [in] pSource
7173 //!           pointer to the surface
7174 //!
SetReporting(PVPHAL_SURFACE pSource)7175 void CompositeState::SetReporting(PVPHAL_SURFACE pSource)
7176 {
7177     m_reporting->IEF                   = pSource->bIEF;
7178     m_reporting->ScalingMode           = pSource->ScalingMode;
7179     m_reporting->DeinterlaceMode       =
7180                 (IsBobDiEnabled(pSource)) ? VPHAL_DI_REPORT_BOB :
7181                                                 VPHAL_DI_REPORT_PROGRESSIVE;
7182 }
7183 
7184 //!
7185 //! \brief    copy Report data
7186 //! \details  copy Report data from this render
7187 //! \param    [out] pReporting
7188 //!           pointer to the Report data to copy data to
7189 //!
CopyReporting(VphalFeatureReport * pReporting)7190 void CompositeState::CopyReporting(VphalFeatureReport* pReporting)
7191 {
7192     VPHAL_RENDER_ASSERT(pReporting);
7193 
7194     pReporting->IEF         = m_reporting->IEF;
7195     pReporting->ScalingMode = m_reporting->ScalingMode;
7196 
7197     if (m_reporting->DeinterlaceMode != VPHAL_DI_REPORT_PROGRESSIVE)
7198     {
7199         pReporting->DeinterlaceMode = m_reporting->DeinterlaceMode;
7200     }
7201 }
7202 
GetThreadCountForVfeState(PVPHAL_RENDERING_DATA_COMPOSITE pRenderingData,PVPHAL_SURFACE pTarget)7203 int32_t CompositeState::GetThreadCountForVfeState(
7204     PVPHAL_RENDERING_DATA_COMPOSITE     pRenderingData,
7205     PVPHAL_SURFACE                      pTarget)
7206 {
7207     int iThreadCount;
7208 
7209     // For optimal performance, we use a different ThreadCount if we are doing
7210     // Composition for Primary Layer only, and the RenderTarget is Overlay or
7211     // FlipChain.
7212     iThreadCount = VPHAL_USE_MEDIA_THREADS_MAX;
7213     if (pRenderingData->iLayers == 1 &&
7214         (pTarget->bOverlay || pTarget->bFlipChain))
7215     {
7216         for (int i = 0; i < VPHAL_COMP_MAX_LAYERS; i++)
7217         {
7218             VPHAL_SURFACE *pSurface = pRenderingData->pLayers[i];
7219             if (pSurface != nullptr)
7220             {
7221                 if (pSurface->SurfType == SURF_IN_PRIMARY)
7222                 {
7223                     iThreadCount = m_ThreadCountPrimary;
7224                 }
7225                 break;
7226             }
7227         }
7228     }
7229 
7230     if (m_pPerfData->CompMaxThreads.bEnabled)
7231     {
7232         iThreadCount =
7233             m_pPerfData->CompMaxThreads.uiVal;
7234     }
7235 
7236     return iThreadCount;
7237 }
7238 
IsSamplerIDForY(int32_t SamplerID)7239 bool CompositeState::IsSamplerIDForY(
7240     int32_t                            SamplerID)
7241 {
7242     return (SamplerID == VPHAL_SAMPLER_Y) ? true : false;
7243 }
7244