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