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