iHD: Re-apply "Decoder-VP9-GEN-9-10-11-12-Fix-the-GPU-hang-due-to-w."
This CL re-applies the aforementioned patch. That patch was originally
introduced by CL:2229422. It was removed in CL:2269975 with the
intention to re-apply it in its own CL to allow for bisectability.
The patch is needed because it's upstream starting on
intel-media-20.2.pre4 [1].
Note that I regenerated the .patch by cherry picking from upstream
instead of using the file previously checked into Chrome OS.
[1] https://github.com/intel/media-driver/commit/1aa3e6995ccfac86b4ec68265591545302435038
BUG=b:159825228
TEST=emerge-eve x11-libs/libva-intel-media-driver
TEST=See CL:2229422 for functional testing (I did not repeat it)
Cq-Depend: chromium:2278395
Change-Id: I8f331ac6545edceabe664db44551c432f2fddbf8
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/2278614
Tested-by: Andres Calderon Jaramillo <andrescj@chromium.org>
Commit-Queue: Andres Calderon Jaramillo <andrescj@chromium.org>
Reviewed-by: Miguel Casas <mcasas@chromium.org>
diff --git a/x11-libs/libva-intel-media-driver/files/0006-Decoder-VP9-GEN-9-10-11-12-Fix-the-GPU-hang-due-to-w.patch b/x11-libs/libva-intel-media-driver/files/0006-Decoder-VP9-GEN-9-10-11-12-Fix-the-GPU-hang-due-to-w.patch
new file mode 100644
index 0000000..aec9303
--- /dev/null
+++ b/x11-libs/libva-intel-media-driver/files/0006-Decoder-VP9-GEN-9-10-11-12-Fix-the-GPU-hang-due-to-w.patch
@@ -0,0 +1,446 @@
+From 234430ba0c49ba7dec0fa35306479d009cd4f34d Mon Sep 17 00:00:00 2001
+From: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
+Date: Mon, 1 Jun 2020 17:19:04 -0700
+Subject: [PATCH] Decoder:VP9:GEN{9,10,11,12} : Fix the GPU hang due to wrong
+ SegmentIDStreamIn & UsePrevInFindMvReferences
+
+We have been seeing random gpu hang on various devices while decoding 4k
+VP9 streams. This patch is addressing a couple of issues which is expected
+to fix the hangs:
+
+a) The current code tries to reset SegmentIDStreamIn if there is
+a resolution change on inter-frames. But due to the mishandling,
+the code was eventually setting SegmentIDStreamIn to true for all
+non-scaling use cases. The patch ensures that the reset happens
+only for res-change on P-frames irrespective of other conditions.
+
+b) The current implementation sets the SegmentIDStreamIn for any
+decode where there is no Segmentation Enabled. We rather follow
+strict constraints similar to the legacy i965 implementation.
+
+c) Ensure the correct SegmentIDStreamIn for key-frames, intra-only
+frames and error-resilient mode.
+
+d) Reset UsePrevInFindMvReferences to zero if last picture has a different size,
+Current picture is error-resilient mode, Last picture was intra_only or keyframe,
+Last picture was not a displayed picture.
+
+Thanks to Wang, Yan<yan.wang@intel.com> for the review
+and Li, Steven(steven.li@intel.com) for the suggestion
+on keeping the scaling logic outside of the inter-frame code block.
+
+ChromeOS bug id: https://partnerissuetracker.corp.google.com/issues/152554969
+
+(cherry picked from commit 1aa3e6995ccfac86b4ec68265591545302435038)
+---
+ .../gen10/hw/vdbox/mhw_vdbox_hcp_g10_X.cpp | 45 +++++++++++++-----
+ .../gen11/hw/vdbox/mhw_vdbox_hcp_g11_X.cpp | 46 +++++++++++++-----
+ .../gen12/hw/vdbox/mhw_vdbox_hcp_g12_X.cpp | 46 +++++++++++++-----
+ .../hw/vdbox/mhw_vdbox_hcp_g9_bxt.cpp | 47 ++++++++++++++-----
+ .../hw/vdbox/mhw_vdbox_hcp_g9_kbl.cpp | 47 ++++++++++++++-----
+ 5 files changed, 172 insertions(+), 59 deletions(-)
+
+diff --git a/media_driver/agnostic/gen10/hw/vdbox/mhw_vdbox_hcp_g10_X.cpp b/media_driver/agnostic/gen10/hw/vdbox/mhw_vdbox_hcp_g10_X.cpp
+index e47cc03a..0d99e653 100644
+--- a/media_driver/agnostic/gen10/hw/vdbox/mhw_vdbox_hcp_g10_X.cpp
++++ b/media_driver/agnostic/gen10/hw/vdbox/mhw_vdbox_hcp_g10_X.cpp
+@@ -2258,6 +2258,7 @@ MOS_STATUS MhwVdboxHcpInterfaceG10::AddHcpVp9PicStateCmd(
+
+ uint32_t curFrameWidth = vp9PicParams->FrameWidthMinus1 + 1;
+ uint32_t curFrameHeight = vp9PicParams->FrameHeightMinus1 + 1;
++ bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true;
+
+ cmd.DW1.FrameWidthInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
+ cmd.DW1.FrameHeightInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
+@@ -2275,6 +2276,27 @@ MOS_STATUS MhwVdboxHcpInterfaceG10::AddHcpVp9PicStateCmd(
+ cmd.DW2.LosslessMode = vp9PicParams->PicFlags.fields.LosslessFlag;
+ cmd.DW2.SegmentIdStreamoutEnable = cmd.DW2.SegmentationUpdateMap;
+
++ uint8_t segmentIDStreaminEnable = 0;
++ if (vp9PicParams->PicFlags.fields.intra_only ||
++ (vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME)) {
++ segmentIDStreaminEnable = 1;
++ } else if (vp9PicParams->PicFlags.fields.segmentation_enabled) {
++ if (!vp9PicParams->PicFlags.fields.segmentation_update_map)
++ segmentIDStreaminEnable = 1;
++ else if (vp9PicParams->PicFlags.fields.segmentation_temporal_update)
++ segmentIDStreaminEnable = 1;
++ }
++ if (vp9PicParams->PicFlags.fields.error_resilient_mode) {
++ segmentIDStreaminEnable = 1;
++ }
++ // Resolution change will reset the segment ID buffer
++ if (isScaling)
++ {
++ segmentIDStreaminEnable = 1;
++ }
++
++ cmd.DW2.SegmentIdStreaminEnable = segmentIDStreaminEnable;
++
+ cmd.DW3.Log2TileRow = vp9PicParams->log2_tile_rows; // No need to minus 1 here.
+ cmd.DW3.Log2TileColumn = vp9PicParams->log2_tile_columns; // No need to minus 1 here.
+ if (vp9PicParams->subsampling_x == 1 && vp9PicParams->subsampling_y == 1)
+@@ -2314,8 +2336,6 @@ MOS_STATUS MhwVdboxHcpInterfaceG10::AddHcpVp9PicStateCmd(
+ uint32_t altRefFrameWidth = vp9RefList[altRefPicIndex]->dwFrameWidth;
+ uint32_t altRefFrameHeight = vp9RefList[altRefPicIndex]->dwFrameHeight;
+
+- bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true;
+-
+ cmd.DW2.AllowHiPrecisionMv = vp9PicParams->PicFlags.fields.allow_high_precision_mv;
+ cmd.DW2.McompFilterType = vp9PicParams->PicFlags.fields.mcomp_filter_type;
+ cmd.DW2.SegmentationTemporalUpdate = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update;
+@@ -2326,15 +2346,18 @@ MOS_STATUS MhwVdboxHcpInterfaceG10::AddHcpVp9PicStateCmd(
+
+ cmd.DW2.LastFrameType = !params->PrevFrameParams.fields.KeyFrame;
+
+- cmd.DW2.UsePrevInFindMvReferences = vp9PicParams->PicFlags.fields.error_resilient_mode ||
+- params->PrevFrameParams.fields.KeyFrame ||
+- params->PrevFrameParams.fields.IntraOnly ||
+- !params->PrevFrameParams.fields.Display ||
+- isScaling ? false : true;
+-
+- cmd.DW2.SegmentIdStreaminEnable = vp9PicParams->PicFlags.fields.error_resilient_mode ||
+- !cmd.DW2.SegmentationEnabled ||
+- isScaling ? false : true;
++ // Reset UsePrevInFindMvReferences to zero if last picture has a different size,
++ // Current picture is error-resilient mode, Last picture was intra_only or keyframe,
++ // Last picture was not a displayed picture.
++ cmd.DW2.UsePrevInFindMvReferences =
++ !(vp9PicParams->PicFlags.fields.error_resilient_mode ||
++ params->PrevFrameParams.fields.KeyFrame ||
++ params->PrevFrameParams.fields.IntraOnly ||
++ !params->PrevFrameParams.fields.Display);
++ // Reset UsePrevInFindMvReferences in case of resolution change on inter frames
++ if (isScaling) {
++ cmd.DW2.UsePrevInFindMvReferences = 0;
++ }
+
+ cmd.DW4.HorizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
+ cmd.DW4.VerticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
+diff --git a/media_driver/agnostic/gen11/hw/vdbox/mhw_vdbox_hcp_g11_X.cpp b/media_driver/agnostic/gen11/hw/vdbox/mhw_vdbox_hcp_g11_X.cpp
+index e9990b0b..bd8447a1 100644
+--- a/media_driver/agnostic/gen11/hw/vdbox/mhw_vdbox_hcp_g11_X.cpp
++++ b/media_driver/agnostic/gen11/hw/vdbox/mhw_vdbox_hcp_g11_X.cpp
+@@ -3128,6 +3128,7 @@ MOS_STATUS MhwVdboxHcpInterfaceG11::AddHcpVp9PicStateCmd(
+
+ uint32_t curFrameWidth = vp9PicParams->FrameWidthMinus1 + 1;
+ uint32_t curFrameHeight = vp9PicParams->FrameHeightMinus1 + 1;
++ bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true;
+
+ cmd.DW1.FrameWidthInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
+ cmd.DW1.FrameHeightInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
+@@ -3145,6 +3146,27 @@ MOS_STATUS MhwVdboxHcpInterfaceG11::AddHcpVp9PicStateCmd(
+ cmd.DW2.LosslessMode = vp9PicParams->PicFlags.fields.LosslessFlag;
+ cmd.DW2.SegmentIdStreamoutEnable = cmd.DW2.SegmentationUpdateMap;
+
++ uint8_t segmentIDStreaminEnable = 0;
++ if (vp9PicParams->PicFlags.fields.intra_only ||
++ (vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME)) {
++ segmentIDStreaminEnable = 1;
++ } else if (vp9PicParams->PicFlags.fields.segmentation_enabled) {
++ if (!vp9PicParams->PicFlags.fields.segmentation_update_map)
++ segmentIDStreaminEnable = 1;
++ else if (vp9PicParams->PicFlags.fields.segmentation_temporal_update)
++ segmentIDStreaminEnable = 1;
++ }
++ if (vp9PicParams->PicFlags.fields.error_resilient_mode) {
++ segmentIDStreaminEnable = 1;
++ }
++ // Resolution change will reset the segment ID buffer
++ if (isScaling)
++ {
++ segmentIDStreaminEnable = 1;
++ }
++
++ cmd.DW2.SegmentIdStreaminEnable = segmentIDStreaminEnable;
++
+ cmd.DW3.Log2TileRow = vp9PicParams->log2_tile_rows; // No need to minus 1 here.
+ cmd.DW3.Log2TileColumn = vp9PicParams->log2_tile_columns; // No need to minus 1 here.
+ if (vp9PicParams->subsampling_x == 1 && vp9PicParams->subsampling_y == 1)
+@@ -3184,9 +3206,6 @@ MOS_STATUS MhwVdboxHcpInterfaceG11::AddHcpVp9PicStateCmd(
+ uint32_t altRefFrameWidth = vp9RefList[altRefPicIndex]->dwFrameWidth;
+ uint32_t altRefFrameHeight = vp9RefList[altRefPicIndex]->dwFrameHeight;
+
+- bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ?
+- false : true;
+-
+ cmd.DW2.AllowHiPrecisionMv = vp9PicParams->PicFlags.fields.allow_high_precision_mv;
+ cmd.DW2.McompFilterType = vp9PicParams->PicFlags.fields.mcomp_filter_type;
+ cmd.DW2.SegmentationTemporalUpdate = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update;
+@@ -3197,15 +3216,18 @@ MOS_STATUS MhwVdboxHcpInterfaceG11::AddHcpVp9PicStateCmd(
+
+ cmd.DW2.LastFrameType = !params->PrevFrameParams.fields.KeyFrame;
+
+- cmd.DW2.UsePrevInFindMvReferences = vp9PicParams->PicFlags.fields.error_resilient_mode ||
+- params->PrevFrameParams.fields.KeyFrame ||
+- params->PrevFrameParams.fields.IntraOnly ||
+- !params->PrevFrameParams.fields.Display ||
+- isScaling ? false : true;
+-
+- cmd.DW2.SegmentIdStreaminEnable = vp9PicParams->PicFlags.fields.error_resilient_mode ||
+- !cmd.DW2.SegmentationEnabled ||
+- isScaling ? false : true;
++ // Reset UsePrevInFindMvReferences to zero if last picture has a different size,
++ // Current picture is error-resilient mode, Last picture was intra_only or keyframe,
++ // Last picture was not a displayed picture.
++ cmd.DW2.UsePrevInFindMvReferences =
++ !(vp9PicParams->PicFlags.fields.error_resilient_mode ||
++ params->PrevFrameParams.fields.KeyFrame ||
++ params->PrevFrameParams.fields.IntraOnly ||
++ !params->PrevFrameParams.fields.Display);
++ // Reset UsePrevInFindMvReferences in case of resolution change on inter frames
++ if (isScaling) {
++ cmd.DW2.UsePrevInFindMvReferences = 0;
++ }
+
+ cmd.DW4.HorizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
+ cmd.DW4.VerticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
+diff --git a/media_driver/agnostic/gen12/hw/vdbox/mhw_vdbox_hcp_g12_X.cpp b/media_driver/agnostic/gen12/hw/vdbox/mhw_vdbox_hcp_g12_X.cpp
+index b3f4ef19..a2b42846 100644
+--- a/media_driver/agnostic/gen12/hw/vdbox/mhw_vdbox_hcp_g12_X.cpp
++++ b/media_driver/agnostic/gen12/hw/vdbox/mhw_vdbox_hcp_g12_X.cpp
+@@ -3543,6 +3543,7 @@ MOS_STATUS MhwVdboxHcpInterfaceG12::AddHcpVp9PicStateCmd(
+
+ uint32_t curFrameWidth = vp9PicParams->FrameWidthMinus1 + 1;
+ uint32_t curFrameHeight = vp9PicParams->FrameHeightMinus1 + 1;
++ bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true;
+
+ cmd.DW1.FrameWidthInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
+ cmd.DW1.FrameHeightInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
+@@ -3560,6 +3561,27 @@ MOS_STATUS MhwVdboxHcpInterfaceG12::AddHcpVp9PicStateCmd(
+ cmd.DW2.LosslessMode = vp9PicParams->PicFlags.fields.LosslessFlag;
+ cmd.DW2.SegmentIdStreamoutEnable = cmd.DW2.SegmentationUpdateMap;
+
++ uint8_t segmentIDStreaminEnable = 0;
++ if (vp9PicParams->PicFlags.fields.intra_only ||
++ (vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME)) {
++ segmentIDStreaminEnable = 1;
++ } else if (vp9PicParams->PicFlags.fields.segmentation_enabled) {
++ if (!vp9PicParams->PicFlags.fields.segmentation_update_map)
++ segmentIDStreaminEnable = 1;
++ else if (vp9PicParams->PicFlags.fields.segmentation_temporal_update)
++ segmentIDStreaminEnable = 1;
++ }
++ if (vp9PicParams->PicFlags.fields.error_resilient_mode) {
++ segmentIDStreaminEnable = 1;
++ }
++ // Resolution change will reset the segment ID buffer
++ if (isScaling)
++ {
++ segmentIDStreaminEnable = 1;
++ }
++
++ cmd.DW2.SegmentIdStreaminEnable = segmentIDStreaminEnable;
++
+ cmd.DW3.Log2TileRow = vp9PicParams->log2_tile_rows; // No need to minus 1 here.
+ cmd.DW3.Log2TileColumn = vp9PicParams->log2_tile_columns; // No need to minus 1 here.
+ if (vp9PicParams->subsampling_x == 1 && vp9PicParams->subsampling_y == 1)
+@@ -3599,9 +3621,6 @@ MOS_STATUS MhwVdboxHcpInterfaceG12::AddHcpVp9PicStateCmd(
+ uint32_t altRefFrameWidth = vp9RefList[altRefPicIndex]->dwFrameWidth;
+ uint32_t altRefFrameHeight = vp9RefList[altRefPicIndex]->dwFrameHeight;
+
+- bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ?
+- false : true;
+-
+ cmd.DW2.AllowHiPrecisionMv = vp9PicParams->PicFlags.fields.allow_high_precision_mv;
+ cmd.DW2.McompFilterType = vp9PicParams->PicFlags.fields.mcomp_filter_type;
+ cmd.DW2.SegmentationTemporalUpdate = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update;
+@@ -3612,15 +3631,18 @@ MOS_STATUS MhwVdboxHcpInterfaceG12::AddHcpVp9PicStateCmd(
+
+ cmd.DW2.LastFrameType = !params->PrevFrameParams.fields.KeyFrame;
+
+- cmd.DW2.UsePrevInFindMvReferences = vp9PicParams->PicFlags.fields.error_resilient_mode ||
+- params->PrevFrameParams.fields.KeyFrame ||
+- params->PrevFrameParams.fields.IntraOnly ||
+- !params->PrevFrameParams.fields.Display ||
+- isScaling ? false : true;
+-
+- cmd.DW2.SegmentIdStreaminEnable = vp9PicParams->PicFlags.fields.error_resilient_mode ||
+- !cmd.DW2.SegmentationEnabled ||
+- isScaling ? false : true;
++ // Reset UsePrevInFindMvReferences to zero if last picture has a different size,
++ // Current picture is error-resilient mode, Last picture was intra_only or keyframe,
++ // Last picture was not a displayed picture.
++ cmd.DW2.UsePrevInFindMvReferences =
++ !(vp9PicParams->PicFlags.fields.error_resilient_mode ||
++ params->PrevFrameParams.fields.KeyFrame ||
++ params->PrevFrameParams.fields.IntraOnly ||
++ !params->PrevFrameParams.fields.Display);
++ // Reset UsePrevInFindMvReferences in case of resolution change on inter frames
++ if (isScaling) {
++ cmd.DW2.UsePrevInFindMvReferences = 0;
++ }
+
+ cmd.DW4.HorizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
+ cmd.DW4.VerticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
+diff --git a/media_driver/agnostic/gen9_bxt/hw/vdbox/mhw_vdbox_hcp_g9_bxt.cpp b/media_driver/agnostic/gen9_bxt/hw/vdbox/mhw_vdbox_hcp_g9_bxt.cpp
+index 2def6fd7..acd23e33 100644
+--- a/media_driver/agnostic/gen9_bxt/hw/vdbox/mhw_vdbox_hcp_g9_bxt.cpp
++++ b/media_driver/agnostic/gen9_bxt/hw/vdbox/mhw_vdbox_hcp_g9_bxt.cpp
+@@ -399,6 +399,7 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9PicStateCmd(
+
+ uint32_t curFrameWidth = vp9PicParams->FrameWidthMinus1 + 1;
+ uint32_t curFrameHeight = vp9PicParams->FrameHeightMinus1 + 1;
++ bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true;
+
+ cmd.DW1.FrameWidthInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
+ cmd.DW1.FrameHeightInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
+@@ -416,6 +417,27 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9PicStateCmd(
+ cmd.DW2.LosslessMode = vp9PicParams->PicFlags.fields.LosslessFlag;
+ cmd.DW2.SegmentIdStreamoutEnable = cmd.DW2.SegmentationUpdateMap;
+
++ uint8_t segmentIDStreaminEnable = 0;
++ if (vp9PicParams->PicFlags.fields.intra_only ||
++ (vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME)) {
++ segmentIDStreaminEnable = 1;
++ } else if (vp9PicParams->PicFlags.fields.segmentation_enabled) {
++ if (!vp9PicParams->PicFlags.fields.segmentation_update_map)
++ segmentIDStreaminEnable = 1;
++ else if (vp9PicParams->PicFlags.fields.segmentation_temporal_update)
++ segmentIDStreaminEnable = 1;
++ }
++ if (vp9PicParams->PicFlags.fields.error_resilient_mode) {
++ segmentIDStreaminEnable = 1;
++ }
++ // Resolution change will reset the segment ID buffer
++ if (isScaling)
++ {
++ segmentIDStreaminEnable = 1;
++ }
++
++ cmd.DW2.SegmentIdStreaminEnable = segmentIDStreaminEnable;
++
+ cmd.DW3.Log2TileRow = vp9PicParams->log2_tile_rows; // No need to minus 1 here.
+ cmd.DW3.Log2TileColumn = vp9PicParams->log2_tile_columns; // No need to minus 1 here.
+
+@@ -438,8 +460,6 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9PicStateCmd(
+ uint32_t altRefFrameWidth = vp9RefList[altRefPicIndex]->dwFrameWidth;
+ uint32_t altRefFrameHeight = vp9RefList[altRefPicIndex]->dwFrameHeight;
+
+- bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true;
+-
+ cmd.DW2.AllowHiPrecisionMv = vp9PicParams->PicFlags.fields.allow_high_precision_mv;
+ cmd.DW2.McompFilterType = vp9PicParams->PicFlags.fields.mcomp_filter_type;
+ cmd.DW2.SegmentationTemporalUpdate = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update;
+@@ -450,15 +470,18 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9PicStateCmd(
+
+ cmd.DW2.LastFrameType = !params->PrevFrameParams.fields.KeyFrame;
+
+- cmd.DW2.UsePrevInFindMvReferences = vp9PicParams->PicFlags.fields.error_resilient_mode ||
+- params->PrevFrameParams.fields.KeyFrame ||
+- params->PrevFrameParams.fields.IntraOnly ||
+- !params->PrevFrameParams.fields.Display ||
+- isScaling ? false : true;
+-
+- cmd.DW2.SegmentIdStreaminEnable = vp9PicParams->PicFlags.fields.error_resilient_mode ||
+- !cmd.DW2.SegmentationEnabled ||
+- isScaling ? false : true;
++ // Reset UsePrevInFindMvReferences to zero if last picture has a different size,
++ // Current picture is error-resilient mode, Last picture was intra_only or keyframe,
++ // Last picture was not a displayed picture.
++ cmd.DW2.UsePrevInFindMvReferences =
++ !(vp9PicParams->PicFlags.fields.error_resilient_mode ||
++ params->PrevFrameParams.fields.KeyFrame ||
++ params->PrevFrameParams.fields.IntraOnly ||
++ !params->PrevFrameParams.fields.Display);
++ // Reset UsePrevInFindMvReferences in case of resolution change on inter frames
++ if (isScaling) {
++ cmd.DW2.UsePrevInFindMvReferences = 0;
++ }
+
+ cmd.DW4.HorizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
+ cmd.DW4.VerticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
+@@ -548,4 +571,4 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Bxt::AddHcpVp9SegmentStateCmd(
+ MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(cmdBuffer, batchBuffer, segData, cmd.byteSize));
+
+ return eStatus;
+-}
+\ No newline at end of file
++}
+diff --git a/media_driver/agnostic/gen9_kbl/hw/vdbox/mhw_vdbox_hcp_g9_kbl.cpp b/media_driver/agnostic/gen9_kbl/hw/vdbox/mhw_vdbox_hcp_g9_kbl.cpp
+index 9fd31b5c..ca57f073 100644
+--- a/media_driver/agnostic/gen9_kbl/hw/vdbox/mhw_vdbox_hcp_g9_kbl.cpp
++++ b/media_driver/agnostic/gen9_kbl/hw/vdbox/mhw_vdbox_hcp_g9_kbl.cpp
+@@ -1237,6 +1237,7 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpVp9PicStateCmd(
+
+ uint32_t curFrameWidth = vp9PicParams->FrameWidthMinus1 + 1;
+ uint32_t curFrameHeight = vp9PicParams->FrameHeightMinus1 + 1;
++ bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true;
+
+ cmd.DW1.FrameWidthInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
+ cmd.DW1.FrameHeightInPixelsMinus1 = MOS_ALIGN_CEIL(curFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH) - 1;
+@@ -1254,6 +1255,27 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpVp9PicStateCmd(
+ cmd.DW2.LosslessMode = vp9PicParams->PicFlags.fields.LosslessFlag;
+ cmd.DW2.SegmentIdStreamoutEnable = cmd.DW2.SegmentationUpdateMap;
+
++ uint8_t segmentIDStreaminEnable = 0;
++ if (vp9PicParams->PicFlags.fields.intra_only ||
++ (vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME)) {
++ segmentIDStreaminEnable = 1;
++ } else if (vp9PicParams->PicFlags.fields.segmentation_enabled) {
++ if (!vp9PicParams->PicFlags.fields.segmentation_update_map)
++ segmentIDStreaminEnable = 1;
++ else if (vp9PicParams->PicFlags.fields.segmentation_temporal_update)
++ segmentIDStreaminEnable = 1;
++ }
++ if (vp9PicParams->PicFlags.fields.error_resilient_mode) {
++ segmentIDStreaminEnable = 1;
++ }
++ // Resolution change will reset the segment ID buffer
++ if (isScaling)
++ {
++ segmentIDStreaminEnable = 1;
++ }
++
++ cmd.DW2.SegmentIdStreaminEnable = segmentIDStreaminEnable;
++
+ cmd.DW3.Log2TileRow = vp9PicParams->log2_tile_rows; // No need to minus 1 here.
+ cmd.DW3.Log2TileColumn = vp9PicParams->log2_tile_columns; // No need to minus 1 here.
+ if (vp9PicParams->subsampling_x == 1 && vp9PicParams->subsampling_y == 1)
+@@ -1293,8 +1315,6 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpVp9PicStateCmd(
+ uint32_t altRefFrameWidth = vp9RefList[altRefPicIndex]->dwFrameWidth;
+ uint32_t altRefFrameHeight = vp9RefList[altRefPicIndex]->dwFrameHeight;
+
+- bool isScaling = (curFrameWidth == params->dwPrevFrmWidth) && (curFrameHeight == params->dwPrevFrmHeight) ? false : true;
+-
+ cmd.DW2.AllowHiPrecisionMv = vp9PicParams->PicFlags.fields.allow_high_precision_mv;
+ cmd.DW2.McompFilterType = vp9PicParams->PicFlags.fields.mcomp_filter_type;
+ cmd.DW2.SegmentationTemporalUpdate = cmd.DW2.SegmentationUpdateMap && vp9PicParams->PicFlags.fields.segmentation_temporal_update;
+@@ -1305,15 +1325,18 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpVp9PicStateCmd(
+
+ cmd.DW2.LastFrameType = !params->PrevFrameParams.fields.KeyFrame;
+
+- cmd.DW2.UsePrevInFindMvReferences = vp9PicParams->PicFlags.fields.error_resilient_mode ||
+- params->PrevFrameParams.fields.KeyFrame ||
+- params->PrevFrameParams.fields.IntraOnly ||
+- !params->PrevFrameParams.fields.Display ||
+- isScaling ? false : true;
+-
+- cmd.DW2.SegmentIdStreaminEnable = vp9PicParams->PicFlags.fields.error_resilient_mode ||
+- !cmd.DW2.SegmentationEnabled ||
+- isScaling ? false : true;
++ // Reset UsePrevInFindMvReferences to zero if last picture has a different size,
++ // Current picture is error-resilient mode, Last picture was intra_only or keyframe,
++ // Last picture was not a displayed picture.
++ cmd.DW2.UsePrevInFindMvReferences =
++ !(vp9PicParams->PicFlags.fields.error_resilient_mode ||
++ params->PrevFrameParams.fields.KeyFrame ||
++ params->PrevFrameParams.fields.IntraOnly ||
++ !params->PrevFrameParams.fields.Display);
++ // Reset UsePrevInFindMvReferences in case of resolution change on inter frames
++ if (isScaling) {
++ cmd.DW2.UsePrevInFindMvReferences = 0;
++ }
+
+ cmd.DW4.HorizontalScaleFactorForLast = (lastRefFrameWidth * m_vp9ScalingFactor) / curFrameWidth;
+ cmd.DW4.VerticalScaleFactorForLast = (lastRefFrameHeight * m_vp9ScalingFactor) / curFrameHeight;
+@@ -1595,4 +1618,4 @@ MOS_STATUS MhwVdboxHcpInterfaceG9Kbl::AddHcpHevcPicBrcBuffer(
+ m_osInterface->pfnUnlockResource(m_osInterface, hcpImgStates);
+
+ return eStatus;
+-}
+\ No newline at end of file
++}
+--
+2.26.2
+
diff --git a/x11-libs/libva-intel-media-driver/libva-intel-media-driver-20.1.1-r6.ebuild b/x11-libs/libva-intel-media-driver/libva-intel-media-driver-20.1.1-r7.ebuild
similarity index 100%
rename from x11-libs/libva-intel-media-driver/libva-intel-media-driver-20.1.1-r6.ebuild
rename to x11-libs/libva-intel-media-driver/libva-intel-media-driver-20.1.1-r7.ebuild
diff --git a/x11-libs/libva-intel-media-driver/libva-intel-media-driver-20.1.1.ebuild b/x11-libs/libva-intel-media-driver/libva-intel-media-driver-20.1.1.ebuild
index 3ffdd7e..c6dcc7b 100644
--- a/x11-libs/libva-intel-media-driver/libva-intel-media-driver-20.1.1.ebuild
+++ b/x11-libs/libva-intel-media-driver/libva-intel-media-driver-20.1.1.ebuild
@@ -27,6 +27,7 @@
"${FILESDIR}"/0003-VP-Explicitly-initialize-maxSrcRect-of-VphalRenderer.patch
"${FILESDIR}"/0004-VP-fix-crash-in-vp8-playback.patch
"${FILESDIR}"/0005-VP-Fix-memory-corruption.patch
+ "${FILESDIR}"/0006-Decoder-VP9-GEN-9-10-11-12-Fix-the-GPU-hang-due-to-w.patch
)
src_configure() {