@@ -873,6 +873,98 @@ uint8_t GMM_STDCALL GmmLib::GmmResourceInfoCommon::CpuBlt(GMM_RES_COPY_BLT *pBlt
873873
874874 pTexInfo = &(Surf);
875875
876+ // YUV Planar surface
877+ if (pTexInfo->OffsetInfo .Plane .IsTileAlignedPlanes && GmmIsPlanar (Surf.Format ))
878+ {
879+ uint32_t PlaneId = GMM_NO_PLANE;
880+ uint32_t TotalHeight = 0 ;
881+
882+ if (pTexInfo->OffsetInfo .Plane .NoOfPlanes == 2 )
883+ {
884+ TotalHeight = GFX_ULONG_CAST (pTexInfo->OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_Y] +
885+ pTexInfo->OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_U]);
886+ }
887+ else if (pTexInfo->OffsetInfo .Plane .NoOfPlanes == 3 )
888+ {
889+ TotalHeight = GFX_ULONG_CAST (pTexInfo->OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_Y] +
890+ pTexInfo->OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_U] +
891+ pTexInfo->OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_V]);
892+ }
893+ else
894+ {
895+ TotalHeight = GFX_ULONG_CAST (pTexInfo->OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_Y]); // YV12 exception
896+ }
897+
898+ // Determine if BLT rectange is for monolithic surface or contained in specific Y/UV plane
899+ if (((pBlt->Gpu .OffsetY + pBlt->Blt .Height <= Surf.OffsetInfo .Plane .Y [GMM_PLANE_U]) || pTexInfo->OffsetInfo .Plane .NoOfPlanes == 1 ) &&
900+ (pBlt->Gpu .OffsetX + pBlt->Blt .Width <= Surf.BaseWidth ))
901+ {
902+ PlaneId = GMM_PLANE_Y;
903+ }
904+ else if (pBlt->Gpu .OffsetY >= Surf.OffsetInfo .Plane .Y [GMM_PLANE_U] &&
905+ (pBlt->Gpu .OffsetY + pBlt->Blt .Height <= (Surf.OffsetInfo .Plane .Y [GMM_PLANE_U] + pTexInfo->OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_U])) &&
906+ (pBlt->Gpu .OffsetX + pBlt->Blt .Width <= Surf.BaseWidth ))
907+ {
908+ PlaneId = GMM_PLANE_U;
909+ }
910+ else if (pBlt->Gpu .OffsetY >= Surf.OffsetInfo .Plane .Y [GMM_PLANE_V] &&
911+ (pBlt->Gpu .OffsetY + pBlt->Blt .Height <= (Surf.OffsetInfo .Plane .Y [GMM_PLANE_V] + pTexInfo->OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_U])) &&
912+ (pBlt->Gpu .OffsetX + pBlt->Blt .Width <= Surf.BaseWidth ))
913+ {
914+ PlaneId = GMM_PLANE_V;
915+ }
916+
917+ // For smaller surface, BLT rect may fall in Y Plane due to tile alignment but user may have requested monolithic BLT
918+ if (pBlt->Gpu .OffsetX == 0 &&
919+ pBlt->Gpu .OffsetY == 0 &&
920+ pBlt->Blt .Height >= TotalHeight)
921+ {
922+ PlaneId = GMM_MAX_PLANE;
923+ }
924+
925+ if (PlaneId == GMM_MAX_PLANE)
926+ {
927+ // TODO BLT rect should not overlap between planes.
928+ {
929+ // __GMM_ASSERT(0); // decide later, for now blt it
930+ // return FALSE;
931+ }
932+
933+ // BLT monolithic surface per plane and remove padding due to tiling.
934+ for (PlaneId = GMM_PLANE_Y; PlaneId <= pTexInfo->OffsetInfo .Plane .NoOfPlanes ; PlaneId++)
935+ {
936+ if (PlaneId == GMM_PLANE_Y)
937+ {
938+ pBlt->Gpu .OffsetX = GFX_ULONG_CAST (Surf.OffsetInfo .Plane .X [GMM_PLANE_Y]);
939+ pBlt->Gpu .OffsetY = GFX_ULONG_CAST (Surf.OffsetInfo .Plane .Y [GMM_PLANE_Y]);
940+ pBlt->Blt .Height = GFX_ULONG_CAST (Surf.OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_Y]);
941+ }
942+ else if (PlaneId == GMM_PLANE_U)
943+ {
944+ pBlt->Gpu .OffsetX = GFX_ULONG_CAST (Surf.OffsetInfo .Plane .X [GMM_PLANE_U]);
945+ pBlt->Gpu .OffsetY = GFX_ULONG_CAST (Surf.OffsetInfo .Plane .Y [GMM_PLANE_U]);
946+
947+ pBlt->Sys .pData = (char *)pBlt->Sys .pData + uint32_t (pBlt->Blt .Height * pBlt->Sys .RowPitch );
948+ pBlt->Blt .Height = GFX_ULONG_CAST (Surf.OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_U]);
949+ if (Surf.Flags .Info .RedecribedPlanes )
950+ {
951+ __GMM_ASSERT (0 );
952+ }
953+ }
954+ else
955+ {
956+ pBlt->Gpu .OffsetX = GFX_ULONG_CAST (Surf.OffsetInfo .Plane .X [GMM_PLANE_V]);
957+ pBlt->Gpu .OffsetY = GFX_ULONG_CAST (Surf.OffsetInfo .Plane .Y [GMM_PLANE_V]);
958+ pBlt->Blt .Height = GFX_ULONG_CAST (Surf.OffsetInfo .Plane .UnAligned .Height [GMM_PLANE_U]);
959+ pBlt->Sys .pData = (char *)pBlt->Sys .pData + uint32_t (pBlt->Blt .Height * pBlt->Sys .RowPitch );
960+ }
961+
962+ CpuBlt (pBlt);
963+ }
964+ }
965+ // else continue below
966+ }
967+
876968 // UV packed planar surfaces will have different tiling geometries for the
877969 // Y and UV planes. Blts cannot span across the tiling boundaries and we
878970 // must select the proper mode for each plane. Non-UV packed formats will
0 commit comments