/*==============================================================================
Copyright(c) 2017 Intel Corporation

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/


#include "Internal/Common/GmmLibInc.h"

/////////////////////////////////////////////////////////////////////////////////////
/// Copies parameters or sets flags based on info sent by the client.
///
/// @param[in]  CreateParams: Flags which specify what sort of resource to create
/// @return     false if encountered invalid param. true otherwise.
/////////////////////////////////////////////////////////////////////////////////////
bool GmmLib::GmmResourceInfoCommon::CopyClientParams(GMM_RESCREATE_PARAMS &CreateParams)
{
    uint32_t BitsPerPixel;

    if((CreateParams.Format > GMM_FORMAT_INVALID) &&
       (CreateParams.Format < GMM_RESOURCE_FORMATS))
    {
        BitsPerPixel = pGmmGlobalContext->GetPlatformInfo().FormatTable[CreateParams.Format].Element.BitsPer;
    }
    else
    {
        GMM_ASSERTDPF(0, "Format Error");
        return false;
    }
    {
        // Promote tiling options if caller does not provide any.
        // X/Y/W/L are tiling formats, and Yf/Ys are modifiers to the internal
        // ordering for Y and L macro-formats.
        if((CreateParams.Flags.Info.Linear +
            CreateParams.Flags.Info.TiledW +
            CreateParams.Flags.Info.TiledX +
            CreateParams.Flags.Info.TiledY) == 0)
        {
            if(CreateParams.Type == RESOURCE_1D ||
               CreateParams.Type == RESOURCE_BUFFER ||
               CreateParams.Type == RESOURCE_SCRATCH ||
               CreateParams.Flags.Info.ExistingSysMem)
            {
                CreateParams.Flags.Info.Linear = true;
            }

            if(pGmmGlobalContext->GetSkuTable().FtrTileY)
            {

                CreateParams.Flags.Info.TiledYs |= CreateParams.Flags.Info.StdSwizzle || CreateParams.Flags.Gpu.TiledResource;

                // Propose L+Y by default.
                CreateParams.Flags.Info.Linear = true;
                CreateParams.Flags.Info.TiledY = true;

                // Pre-Gen11 Planar
                if(GmmIsPlanar(CreateParams.Format) && (GFX_GET_CURRENT_RENDERCORE(pGmmGlobalContext->GetPlatformInfo().Platform) < IGFX_GEN11_CORE))
                {
                    CreateParams.Flags.Info.TiledX = true;
                }
            }
            //Auto-tiling selection if not Linear already
            else if(CreateParams.Flags.Info.Linear == 0)
             {
                // Xe_HP onwards.
                if((CreateParams.Flags.Info.TiledYs +
                    CreateParams.Flags.Info.TiledYf +
                    CreateParams.Flags.Info.Tile4 +
                    CreateParams.Flags.Info.Tile64) == 0)
                {
                    GMM_ASSERTDPF(!CreateParams.Flags.Info.StdSwizzle, "StdSwizzle not supported on current platform");

                    if(!pGmmGlobalContext->GetWaTable().WaDefaultTile4)
                    {
                        // Default Tiling is set to Tile64 on FtrTileY disabled platforms
                        CreateParams.Flags.Info.Tile4 = ((!GMM_IS_SUPPORTED_BPP_ON_TILE_64_YF_YS(BitsPerPixel)) ||            // 24,48,96 bpps are not supported on Tile64, Tile4 is bpp independent
                                                         ((CreateParams.Type == RESOURCE_3D) && (CreateParams.Flags.Gpu.Depth || CreateParams.Flags.Gpu.SeparateStencil)) ||
                                                         ((!pGmmGlobalContext->GetSkuTable().FtrDisplayDisabled) &&
                                                          (CreateParams.Flags.Gpu.FlipChain || CreateParams.Flags.Gpu.Overlay)
                                                          ));
                        CreateParams.Flags.Info.Tile64 = !CreateParams.Flags.Info.Tile4;
                    }
                    else
                    {
                        CreateParams.Flags.Info.Tile64 = (CreateParams.MSAA.NumSamples > 1) || CreateParams.Flags.Gpu.TiledResource; // Colour & Depth/Stencil(IMS) MSAA should use Tile64
                        CreateParams.Flags.Info.Tile4  = !CreateParams.Flags.Info.Tile64;
                    }
                }
                else if((CreateParams.Flags.Info.TiledYs +
                         CreateParams.Flags.Info.TiledYf) > 0)
                {
                    GMM_ASSERTDPF(0, "Tile Yf/Ys not supported on given platform");

                    // Overrides the flags.
                    if(pGmmGlobalContext->GetWaTable().WaDefaultTile4)
                    {
                        CreateParams.Flags.Info.Tile64 = CreateParams.Flags.Info.TiledYs ||
                                                         (CreateParams.MSAA.NumSamples > 1) || CreateParams.Flags.Gpu.TiledResource; // Colour & Depth/Stencil(IMS) MSAA should use Tile64

                        CreateParams.Flags.Info.Tile4   = !CreateParams.Flags.Info.Tile64;
                        CreateParams.Flags.Info.TiledYf = 0;
                        CreateParams.Flags.Info.TiledYs = 0;
                    }
                }
            }
        }
        //Convert non linear & non-tiledX tiling selection by client to proper tiling.
        else if(CreateParams.Flags.Info.Linear + CreateParams.Flags.Info.TiledX == 0)
         {
            if(!pGmmGlobalContext->GetSkuTable().FtrTileY)
            {
                __GMM_ASSERT(!(CreateParams.Flags.Info.TiledYs ||
                               CreateParams.Flags.Info.TiledYf ||
                               CreateParams.Flags.Info.TiledY));

                // On Xe_HP onwards translate UMD's TileY/TileYs request to Tile4/Tile64 respectively
                // Exclude TileX, Linear from override
                if(pGmmGlobalContext->GetWaTable().WaDefaultTile4 && (CreateParams.Flags.Info.TiledYs ||
                                                                       CreateParams.Flags.Info.TiledY))
                {
                    CreateParams.Flags.Info.Tile64 =
                    CreateParams.Flags.Info.TiledYs ||
                    (CreateParams.MSAA.NumSamples > 1) || CreateParams.Flags.Gpu.TiledResource;

                    CreateParams.Flags.Info.Tile4 = !CreateParams.Flags.Info.Tile64;

                    CreateParams.Flags.Info.TiledY  = 0;
                    CreateParams.Flags.Info.TiledYs = 0;
                    CreateParams.Flags.Info.TiledW  = 0;
                    CreateParams.Flags.Info.TiledYf = 0;
                }

                // Displayable surfaces cannot be Tiled4/64.
                __GMM_ASSERT(!pGmmGlobalContext->GetSkuTable().FtrDisplayYTiling);

                //override displayable surfaces to TileX
                if(pGmmGlobalContext->GetSkuTable().FtrDisplayXTiling)
                {
                    if(CreateParams.Flags.Gpu.FlipChain || CreateParams.Flags.Gpu.Overlay ||
                       CreateParams.Flags.Gpu.Presentable)
                    {
                        CreateParams.Flags.Info.TiledX = 1;
                        CreateParams.Flags.Info.TiledY = 0;
                        CreateParams.Flags.Info.Tile4  = 0;
                        CreateParams.Flags.Info.Tile64 = 0;
                    }
                }
            }
        }

        //ExistingSysMem allocations must be Linear
        __GMM_ASSERT(!CreateParams.Flags.Info.ExistingSysMem ||
                     CreateParams.Flags.Info.Linear);
    }

    if(pGmmGlobalContext->GetSkuTable().FtrMultiTileArch)
    {
        // For Naive apps, UMD does not populate multi tile arch params.
        // Gmm will populate them based on the kmd assigned tile to the umd process
        if(!CreateParams.MultiTileArch.Enable)
        {
            uint32_t GpuTile = 0;
            __GMM_ASSERT(CreateParams.MultiTileArch.GpuVaMappingSet == 0);
            __GMM_ASSERT(CreateParams.MultiTileArch.LocalMemEligibilitySet == 0);
            __GMM_ASSERT(CreateParams.MultiTileArch.LocalMemPreferredSet == 0);

            __GMM_ASSERT(pGmmGlobalContext->GetSkuTable().FtrAssignedGpuTile < 4);

#if !__GMM_KMD__
            GpuTile                                    = pGmmGlobalContext->GetSkuTable().FtrAssignedGpuTile;
            CreateParams.MultiTileArch.GpuVaMappingSet = __BIT(GpuTile);
#else
            GpuTile                                    = 0;
            CreateParams.MultiTileArch.GpuVaMappingSet = pGmmGlobalContext->GetGtSysInfo()->MultiTileArchInfo.TileMask;
#endif

            CreateParams.MultiTileArch.Enable = true;

            if(!CreateParams.Flags.Info.NonLocalOnly)
            {
                CreateParams.MultiTileArch.LocalMemEligibilitySet = __BIT(GpuTile);
                CreateParams.MultiTileArch.LocalMemPreferredSet   = __BIT(GpuTile);
            }
        }
    }

    Surf.Type                      = CreateParams.Type;
    Surf.Format                    = CreateParams.Format;
    Surf.BaseWidth                 = CreateParams.BaseWidth64;
    Surf.BaseHeight                = CreateParams.BaseHeight;
    Surf.Depth                     = CreateParams.Depth;
    Surf.MaxLod                    = CreateParams.MaxLod;
    Surf.ArraySize                 = CreateParams.ArraySize;
    Surf.Flags                     = CreateParams.Flags;
    Surf.MSAA                      = CreateParams.MSAA;
    Surf.Alignment.BaseAlignment   = CreateParams.BaseAlignment;
    Surf.CachePolicy.Usage         = CreateParams.Usage;
    Surf.MSAA.NumSamples           = GFX_MAX(Surf.MSAA.NumSamples, 1);
    Surf.MaximumRenamingListLength = CreateParams.MaximumRenamingListLength;
    Surf.OverridePitch             = CreateParams.OverridePitch;
    Surf.CpTag                     = CreateParams.CpTag;

    Surf.Flags.Info.__PreWddm2SVM =
    Surf.Flags.Info.SVM &&
    !(pGmmGlobalContext->GetSkuTable().FtrWddm2GpuMmu ||
      pGmmGlobalContext->GetSkuTable().FtrWddm2Svm);

#if !__GMM_KMD__ && _WIN32
    if(pGmmGlobalContext->GetWaTable().WaLLCCachingUnsupported)
    {
        Surf.Flags.Info.GttMapType = (CreateParams.Flags.Info.Cacheable) ?
                                     GMM_GTT_CACHETYPE_VLV_SNOOPED :
                                     GMM_GTT_CACHETYPE_UNCACHED;
    }
#endif

#if(_DEBUG || _RELEASE_INTERNAL)
    Surf.Platform = pGmmGlobalContext->GetPlatformInfo().Platform;
#endif

Surf.BitsPerPixel = BitsPerPixel;

    pGmmGlobalContext->GetPlatformInfoObj()->SetCCSFlag(this->GetResFlags());

    // Moderate down displayable flags if input parameters are not conducive.
    // Reject non displayable tiling modes
    if(Surf.Flags.Gpu.FlipChain || Surf.Flags.Gpu.Overlay)
    {
        if(Surf.Flags.Info.TiledY && !pGmmGlobalContext->GetSkuTable().FtrDisplayYTiling)
        {
            if(Surf.Flags.Gpu.FlipChainPreferred)
            {
                Surf.Flags.Gpu.Overlay   = 0;
                Surf.Flags.Gpu.FlipChain = 0;
            }
            else
            {
                GMM_ASSERTDPF(0, "Y-Tiling mode not displayable");
                //return false;
            }
        }
    }

    // Convert Any Pseudo Creation Params to Actual...
    GMM_TEXTURE_CALC *pTextureCalc = GMM_OVERRIDE_TEXTURE_CALC(&Surf);
    if(Surf.Flags.Gpu.UnifiedAuxSurface)
    {
        AuxSurf = Surf;

        if(Surf.Flags.Gpu.Depth && Surf.Flags.Gpu.CCS) //Depth + HiZ+CCS
        {
            //GMM_ASSERTDPF(Surf.Flags.Gpu.HiZ, "Lossless Z compression supported when Depth+HiZ+CCS is unified");
            AuxSecSurf                           = Surf;
            AuxSecSurf.Type                      = pGmmGlobalContext->GetSkuTable().FtrFlatPhysCCS ? RESOURCE_INVALID : AuxSecSurf.Type;
            Surf.Flags.Gpu.HiZ                   = 0; //Its depth buffer, so clear HiZ
            AuxSecSurf.Flags.Gpu.HiZ             = 0;
            AuxSurf.Flags.Gpu.IndirectClearColor = 0; //Clear Depth flags from HiZ, contained with separate/legacy HiZ when Depth isn't compressible.
            AuxSurf.Flags.Gpu.CCS                = 0;
            AuxSurf.Type                         = (AuxSurf.Flags.Gpu.HiZ) ? AuxSurf.Type : RESOURCE_INVALID;
            AuxSurf.Flags.Info.RenderCompressed = AuxSurf.Flags.Info.MediaCompressed = 0;
        }
        else if(Surf.Flags.Gpu.SeparateStencil && Surf.Flags.Gpu.CCS) //Stencil compression
        {
            AuxSurf.Flags.Gpu.SeparateStencil = 0;
            Surf.Flags.Gpu.CCS                = 0;
            if(GMM_SUCCESS != pTextureCalc->PreProcessTexSpecialCases(&Surf))
            {
                return false;
            }
            Surf.Flags.Gpu.CCS = 1;
            AuxSurf.Type       = pGmmGlobalContext->GetSkuTable().FtrFlatPhysCCS ? RESOURCE_INVALID : AuxSurf.Type;
        }
        else if(Surf.MSAA.NumSamples > 1 && Surf.Flags.Gpu.CCS) //MSAA+MCS+CCS
        {
            GMM_ASSERTDPF(Surf.Flags.Gpu.MCS, "Lossless MSAA supported when MSAA+MCS+CCS is unified");
            AuxSecSurf                          = Surf;
            AuxSecSurf.Type                     = pGmmGlobalContext->GetSkuTable().FtrFlatPhysCCS ? RESOURCE_INVALID : AuxSecSurf.Type;
            AuxSecSurf.Flags.Gpu.MCS            = 0;
            AuxSurf.Flags.Gpu.CCS               = 0;
            AuxSurf.Flags.Info.RenderCompressed = AuxSurf.Flags.Info.MediaCompressed = 0;
        }
        else if(Surf.Flags.Gpu.CCS)
        {
            AuxSurf.Type = (pGmmGlobalContext->GetSkuTable().FtrFlatPhysCCS && !Surf.Flags.Gpu.ProceduralTexture) ? RESOURCE_INVALID : AuxSurf.Type;
        }

        if(AuxSurf.Type != RESOURCE_INVALID &&
           GMM_SUCCESS != pTextureCalc->PreProcessTexSpecialCases(&AuxSurf))
        {
            return false;
        }
        if(AuxSecSurf.Type != RESOURCE_INVALID &&
           GMM_SUCCESS != pTextureCalc->PreProcessTexSpecialCases(&AuxSecSurf))
        {
            return false;
        }
    }
    else
    {
        if(GMM_SUCCESS != pTextureCalc->PreProcessTexSpecialCases(&Surf))
        {
            return false;
        }
    }

    RotateInfo = CreateParams.RotateInfo;

    if(pGmmGlobalContext->GetSkuTable().FtrMultiTileArch)
    {
        MultiTileArch = CreateParams.MultiTileArch;
    }

#ifdef __GMM_KMD__
    if(Surf.Flags.Gpu.S3d)
    {
        Surf.S3d = CreateParams.S3d;
    }
#endif

    return true;
}


/////////////////////////////////////////////////////////////////////////////////////
/// Validates the parameters passed in by clients to make sure they do not
/// conflict or ask for unsupporting combinations/features.
///
/// @return     1 is validation passed. 0 otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmResourceInfoCommon::ValidateParams()
{
    __GMM_BUFFER_TYPE              Restrictions             = {0};
    const __GMM_PLATFORM_RESOURCE *pPlatformResource        = NULL;
    GMM_TEXTURE_CALC *             pTextureCalc             = NULL;
    bool                           AllowMaxWidthViolations  = false;
    bool                           AllowMaxHeightViolations = false;
    uint8_t                        Status                   = 0;

    GMM_DPF_ENTER;

    __GMM_ASSERTPTR(pGmmGlobalContext, 0);

#if(defined(__GMM_KMD__) && (_DEBUG || _RELEASE_INTERNAL))
    //KMD Debug and Release Internal Drivers only
    //if GMM_TEXTURE_INFO's platform type != native platform
    //then initialize the OverridePlatformInfo.

    //If GMM_TEXTURE_INFO's platform type == IGFX_UNKNOWN_CORE then it means that UMD driver is
    //in "Release" version and passes all zeros in Surf.Platform
    if(GFX_GET_CURRENT_RENDERCORE(Surf.Platform) == IGFX_UNKNOWN_CORE)
    {
        Surf.Platform = pGmmGlobalContext->GetPlatformInfo().Platform;
        // If this is a unified surface then make sure the AUX surface has the same platform info
        if(Surf.Flags.Gpu.UnifiedAuxSurface)
        {
            AuxSurf.Platform    = Surf.Platform;
            AuxSecSurf.Platform = Surf.Platform;
        }
    }

    if(pGmmGlobalContext->GetPlatformInfoObj() != NULL &&
       (GFX_GET_CURRENT_RENDERCORE(Surf.Platform) !=
        GFX_GET_CURRENT_RENDERCORE(pGmmGlobalContext->GetPlatformInfo().Platform)) &&
       (pGmmGlobalContext->GetOverridePlatformInfoObj() == NULL ||
        (GFX_GET_CURRENT_RENDERCORE(Surf.Platform) !=
         GFX_GET_CURRENT_RENDERCORE(pGmmGlobalContext->GetOverridePlatformInfo().Platform))))
    {
        //Ensure override is a future platform.
        __GMM_ASSERT(GFX_GET_CURRENT_RENDERCORE(Surf.Platform) >
                     GFX_GET_CURRENT_RENDERCORE(pGmmGlobalContext->GetPlatformInfo().Platform));

        pGmmGlobalContext->SetOverridePlatformInfoObj(GmmLib::PlatformInfo::Create(Surf.Platform, true));

        if(pGmmGlobalContext->GetOverrideTextureCalc())
        {
            delete(pGmmGlobalContext->GetOverrideTextureCalc());
            pGmmGlobalContext->SetOverrideTextureCalc(NULL);
        }

        pGmmGlobalContext->SetOverrideTextureCalc(GmmLib::GmmTextureCalc::Create(Surf.Platform, true));
    }
#endif

    pPlatformResource = GMM_OVERRIDE_PLATFORM_INFO(&Surf);
    pTextureCalc      = GMM_OVERRIDE_TEXTURE_CALC(&Surf);

    __GMM_ASSERT(!(
    Surf.Flags.Gpu.Query &&
    !Surf.Flags.Info.Cacheable)); // Why query not set as cacheable? If not cacheable, what keeps from stolen memory (because STORE_DWORD/PIPE_CONTROL/etc. targets can't be in stolen)?

    if(Surf.Flags.Gpu.HiZ)
    {
        // HiZ checked in PreProcessTexSpecialCases before legal HZ_Width/Height expansion.
        AllowMaxWidthViolations  = true;
        AllowMaxHeightViolations = true;
    }

    // check bpp
    if(((Surf.BitsPerPixel < 8) || (Surf.BitsPerPixel % GMM_BITS(8))) &&
       !(Surf.BitsPerPixel == 1))
    {
        GMM_ASSERTDPF(0, "Invalid BitsPerPixel!");
        goto ERROR_CASE;
    }

    // Check at least one tile pref set.
    // Yf/Ys checked explicitly here, require one of Y or Linear depending on resource type (e.g 1D-->Linear)
    // that TODO: could be automatically promoted.
    if((Surf.Flags.Info.Linear == 0) &&
       (Surf.Flags.Info.TiledX == 0) &&
       (Surf.Flags.Info.TiledW == 0) &&
       (Surf.Flags.Info.TiledYf == 0) &&
       !GMM_IS_4KB_TILE(Surf.Flags) && !GMM_IS_64KB_TILE(Surf.Flags))
    {
        GMM_ASSERTDPF(0, "No Tile or Linear preference specified!");
        goto ERROR_CASE;
    }

    if(Surf.Flags.Info.Tile64 || Surf.Flags.Info.TiledYf || Surf.Flags.Info.TiledYs)
    {
        if(!GMM_IS_SUPPORTED_BPP_ON_TILE_64_YF_YS(Surf.BitsPerPixel))
        {
            GMM_ASSERTDPF(0, "BPP not supported on selected Tile format!");
            goto ERROR_CASE;
        }
    }

    if(!__CanSupportStdTiling(Surf))
    {
        GMM_ASSERTDPF(0, "Invalid TileYf/TileYs usage!");
        goto ERROR_CASE;
    }

    if(Surf.TileMode < TILE_NONE || Surf.TileMode >= GMM_TILE_MODES)
    {
        GMM_ASSERTDPF(0, "Invalid TileMode usage!");
        goto ERROR_CASE;
    }

    if(!((Surf.Format > GMM_FORMAT_INVALID) &&
         (Surf.Format < GMM_RESOURCE_FORMATS)))
    {
        GMM_ASSERTDPF(0, "Invalid Resource Format!");
        goto ERROR_CASE;
    }

    // Check resource format is supported on running platform
    if(IsPresentableformat() == false)
    {
        GMM_ASSERTDPF(0, "Bad Format!");
        goto ERROR_CASE;
    }

    if((Surf.Type == RESOURCE_PRIMARY) &&
       !Surf.Flags.Gpu.FlipChain)
    {
        GMM_ASSERTDPF(0, "Primary does not have FlipChain flag set.");
        goto ERROR_CASE;
    }

    if(Surf.Flags.Gpu.Overlay &&
       Surf.Flags.Gpu.FlipChain)
    {
        GMM_ASSERTDPF(0, "Overlay and FlipChain flags set. S3D logic may fail.");
        goto ERROR_CASE;
    }
    
    // Displayable surfaces must remain Tile4
    if(((!pGmmGlobalContext->GetSkuTable().FtrDisplayDisabled) &&
        (Surf.Flags.Gpu.Overlay || Surf.Flags.Gpu.FlipChain)) &&
       (!(Surf.Flags.Info.Linear || Surf.Flags.Info.TiledX || GMM_IS_4KB_TILE(Surf.Flags))))
    {
        GMM_ASSERTDPF(0, "Unsupported tiling format for displayable resource.");
        goto ERROR_CASE;
    }

    if(pGmmGlobalContext->GetSkuTable().FtrLocalMemory)
    {
        GMM_ASSERTDPF(((Surf.Flags.Info.NonLocalOnly && Surf.Flags.Info.LocalOnly) == 0),
                      "Incorrect segment preference, cannot be both local and system memory.");

        if(Surf.Flags.Gpu.Overlay ||
           Surf.Flags.Gpu.FlipChain)
        {
            if(Surf.Flags.Info.NonLocalOnly)
            {
                GMM_ASSERTDPF(0, "Overlay and FlipChain cannot be in system memory.");
                goto ERROR_CASE;
            }
            Surf.Flags.Info.LocalOnly    = 1;
            Surf.Flags.Info.NonLocalOnly = 0;
        }
        if(pGmmGlobalContext->GetSkuTable().FtrFlatPhysCCS &&
           (Surf.Flags.Info.RenderCompressed ||
            Surf.Flags.Info.MediaCompressed))
        {
            if(Surf.Flags.Info.NonLocalOnly)
            {
                GMM_ASSERTDPF(0, "Compressible surfaces cannot be in system memory.");
                goto ERROR_CASE;
            }
            Surf.Flags.Info.LocalOnly    = 1;
            Surf.Flags.Info.NonLocalOnly = 0;
        }

        if(!Surf.Flags.Info.NotLockable &&
           Surf.Flags.Info.Shared)
        {
            if(Surf.Flags.Info.LocalOnly)
            {
                GMM_ASSERTDPF(0, "Lockable Shared cannot be in local memory.");
                goto ERROR_CASE;
            }
            Surf.Flags.Info.LocalOnly    = 0;
            Surf.Flags.Info.NonLocalOnly = 1;
        }

        if(Surf.Flags.Gpu.CameraCapture)
        {
            if(Surf.Flags.Info.LocalOnly)
            {
                GMM_ASSERTDPF(0, "CameraCapture cannot be in local memory.");
            }
            Surf.Flags.Info.LocalOnly    = 0;
            Surf.Flags.Info.NonLocalOnly = 1;
        }

        if(!Surf.Flags.Info.NonLocalOnly &&
           (!pGmmGlobalContext->GetSkuTable().FtrLocalMemoryAllows4KB))
        {
            Surf.Flags.Info.LocalOnly = true;
        }
    }
    else
    {
        Surf.Flags.Info.LocalOnly = false; //Zero out on iGPU
    }

    if((GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) < IGFX_GEN8_CORE) &&
       Surf.Flags.Info.TiledW)
    {
        GMM_ASSERTDPF(0, "Flag not supported on this platform.");
        goto ERROR_CASE;
    }

    if((GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) > IGFX_GEN11_CORE) &&
       Surf.Flags.Info.TiledW)
    {
        GMM_ASSERTDPF(0, "Flag not supported on this platform.");
        goto ERROR_CASE;
    }

    if((GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) < IGFX_GEN9_CORE) &&
#if(_DEBUG || _RELEASE_INTERNAL)
       !pGmmGlobalContext->GetWaTable().WaDisregardPlatformChecks &&
#endif
       Surf.Flags.Gpu.MMC)
    {
        GMM_ASSERTDPF(0, "Flag not supported on this platform.");
        goto ERROR_CASE;
    }

    //For Media Memory Compression --
    if((Status = pGmmGlobalContext->GetPlatformInfoObj()->ValidateMMC(Surf)) == 0)
    {
        GMM_ASSERTDPF(0, "Invalid flag or array size!");
        goto ERROR_CASE;
    }

    if(!pGmmGlobalContext->GetSkuTable().FtrTileY)
    {
        if(Surf.Flags.Gpu.TiledResource &&
           ((Surf.Flags.Info.Linear && !(Surf.Type == RESOURCE_BUFFER)) || Surf.Flags.Info.TiledYs ||
            Surf.Flags.Info.TiledYf || Surf.Flags.Info.TiledY))
        {
            GMM_ASSERTDPF(0, "Invalid Tile for TiledResource!");
            goto ERROR_CASE;
        }
        if(GMM_IS_64KB_TILE(Surf.Flags) &&
           (Surf.MSAA.NumSamples > 1) &&
           (Surf.MaxLod != 0))
        {
            GMM_ASSERTDPF(0, "Mipped MSAA not supported for Tile64!");
            goto ERROR_CASE;
        }
        // Tile4 does not support MSAA.
        if(GMM_IS_4KB_TILE(Surf.Flags) &&
           (Surf.MSAA.NumSamples > 1))
        {
            GMM_ASSERTDPF(0, "No MSAA support for Tile4!");
            goto ERROR_CASE;
        }
    }

    __GMM_ASSERT(!(pGmmGlobalContext->GetSkuTable().FtrTileY &&
                   (Surf.Flags.Info.Tile4 || Surf.Flags.Info.Tile64)));

    //GMM asserts that ExistingSysMem allocation (whose malloc is outside GmmLib) are either
    //SVM Buffer, Index Buffer, Vertex Buffers, Render Target, Texture
    if(Surf.Flags.Info.ExistingSysMem &&
       !Surf.ExistingSysMem.IsGmmAllocated &&
       !Surf.ExistingSysMem.IsPageAligned)
    {
        if(!(Surf.Flags.Gpu.RenderTarget ||
             Surf.Flags.Gpu.Vertex ||
             Surf.Flags.Gpu.Index ||
             Surf.Flags.Gpu.Texture ||
             Surf.Flags.Info.Linear ||
             Surf.Flags.Info.SVM))
        {
            GMM_ASSERTDPF(0, "Flag not supported by ExistingSysMem alloc!");
            goto ERROR_CASE;
        }

        if(Surf.Type == RESOURCE_3D ||
           Surf.Type == RESOURCE_CUBE ||
           Surf.MaxLod ||
           GmmIsYUVPlanar(Surf.Format))
        {
            GMM_ASSERTDPF(0, "Invalid ExistingSysMem resource Type/Format");
            goto ERROR_CASE;
        }
    }

    pTextureCalc->GetResRestrictions(&Surf, Restrictions);

    // Check array size to make sure it meets HW limits
    if((Surf.ArraySize > Restrictions.MaxArraySize) &&
       ((RESOURCE_1D == Surf.Type) ||
        (RESOURCE_2D == Surf.Type) ||
        (RESOURCE_CUBE == Surf.Type)))
    {
        GMM_ASSERTDPF(0, "Invalid array size!");
        goto ERROR_CASE;
    }

    // Check dimensions to make sure it meets HW max limits
    if(((Surf.BaseHeight > Restrictions.MaxHeight) && !AllowMaxHeightViolations) ||
       ((Surf.BaseWidth > Restrictions.MaxWidth) && !AllowMaxWidthViolations) ||
       (Surf.Depth > Restrictions.MaxDepth)) // Any reason why MaxDepth != 1 for Tex2D
    {
        GMM_ASSERTDPF(0, "Invalid Dimension. Greater than max!");
        goto ERROR_CASE;
    }

    // Check width to make sure it meets Yx requirements
    if(((Surf.Format == GMM_FORMAT_Y8_UNORM_VA) && (Surf.BaseWidth % 4)) ||
       ((Surf.Format == GMM_FORMAT_Y16_UNORM) && (Surf.BaseWidth % 2)) ||
       ((Surf.Format == GMM_FORMAT_Y1_UNORM) && (Surf.BaseWidth % 32)))
    {
        GMM_ASSERTDPF(0, "Invalid width!");
        goto ERROR_CASE;
    }

    // Check dimensions to make sure it meets HW min limits
    if((Surf.BaseHeight < Restrictions.MinHeight) ||
       (Surf.BaseWidth < Restrictions.MinWidth) ||
       (Surf.Depth < Restrictions.MinDepth))
    {
        GMM_ASSERTDPF(0, "Invalid Dimension. Less than min!");
        goto ERROR_CASE;
    }

    // check mip map
    if(Surf.MaxLod > pPlatformResource->MaxLod)
    {
        GMM_ASSERTDPF(0, "Invalid mip map chain specified!");
        goto ERROR_CASE;
    }

    // MIPs are not supported for tiled Yf/Ys planar surfaces
    if((Surf.MaxLod) &&
       GmmIsPlanar(Surf.Format) &&
       (Surf.Flags.Info.TiledYf || GMM_IS_64KB_TILE(Surf.Flags)))
    {
        GMM_ASSERTDPF(0, "Invalid mip map chain specified!");
        goto ERROR_CASE;
    }

    // check depth buffer tilings
    if((Surf.Flags.Gpu.Depth == 1) &&
       (Surf.Flags.Info.TiledX == 1))
    {
        GMM_ASSERTDPF(0, "Invalid Tiling for Depth Buffer!");
        goto ERROR_CASE;
    }

#if DBG
    // Check if stencil buffer gpu flag is set w/ other flags
    if(Surf.Flags.Gpu.SeparateStencil == 1)
    {
        GMM_RESOURCE_FLAG OnlySeparateStencilGpuFlag;

        memset(&OnlySeparateStencilGpuFlag.Gpu, 0, sizeof(OnlySeparateStencilGpuFlag.Gpu));
        OnlySeparateStencilGpuFlag.Gpu.SeparateStencil = 1;

        if(memcmp(&Surf.Flags.Gpu, &OnlySeparateStencilGpuFlag.Gpu, sizeof(OnlySeparateStencilGpuFlag.Gpu)))
        {
            GMM_ASSERTDPF(0,
                          "Should not set w/ other flags b/c vertical alignment is "
                          "unique for separate stencil and incompatible w/ other "
                          "usages such as render target.");
            goto ERROR_CASE;
        }
    }
#endif

    // MSAA Restrictions
    if((Surf.MSAA.NumSamples > 1) &&
       !( //--- Legitimate MSAA Case ------------------------------------------
       (Surf.Type == RESOURCE_2D) &&
       (Surf.Flags.Gpu.Depth ||
        Surf.Flags.Gpu.HiZ ||
        Surf.Flags.Gpu.RenderTarget ||
        Surf.Flags.Gpu.SeparateStencil) &&
       // Single-LOD (pre-SKL)...
       ((GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) >= IGFX_GEN9_CORE) ||
        (Surf.MaxLod == 0)) &&
       // TileYF cannot be MSAA'ed (pre-Gen10)...
       ((GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) >= IGFX_GEN10_CORE) ||
        !Surf.Flags.Info.TiledYf) &&
       // Tile64 MSAA (Xe_HP)
       (pGmmGlobalContext->GetSkuTable().FtrTileY ||
        !GMM_IS_64KB_TILE(Surf.Flags) ||
        (Surf.MaxLod == 0)) &&
       // Tile4 does not support MSAA
       (pGmmGlobalContext->GetSkuTable().FtrTileY ||
        !GMM_IS_4KB_TILE(Surf.Flags)) &&
       // Non-Compressed/YUV...
       !GmmIsCompressed(Surf.Format) &&
       !GmmIsYUVPacked(Surf.Format) &&
       !GmmIsPlanar(Surf.Format) &&
       // Supported Sample Count for Platform...
       (((GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) >= IGFX_GEN7_CORE) &&
         ((Surf.MSAA.NumSamples == 4) || (Surf.MSAA.NumSamples == 8))) ||
        ((GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) >= IGFX_GEN8_CORE) &&
         ((Surf.MSAA.NumSamples == 2))) ||
        ((GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) >= IGFX_GEN9_CORE) &&
         ((Surf.MSAA.NumSamples == 16))))))
    {
        GMM_ASSERTDPF(0, "Invalid MSAA usage!");
        goto ERROR_CASE;
    }

    // CCS Restrictions
    if(Surf.Flags.Gpu.CCS)
    {
        if((Status = pGmmGlobalContext->GetPlatformInfoObj()->ValidateCCS(Surf)) == 0)
        {
            GMM_ASSERTDPF(0, "Invalid CCS usage!");
            goto ERROR_CASE;
        }

        if(Surf.Flags.Info.RenderCompressed && Surf.Flags.Info.MediaCompressed)
        {
            GMM_ASSERTDPF(0, "Invalid CCS usage - can't be both RC and MC!");
            goto ERROR_CASE;
        }
    }

    // UnifiedAuxSurface Restrictions
    if((Status = pGmmGlobalContext->GetPlatformInfoObj()->ValidateUnifiedAuxSurface(Surf)) == 0)
    {
        GMM_ASSERTDPF(0, "Invalid UnifiedAuxSurface usage!");
        goto ERROR_CASE;
    }

    // IndirectClearColor Restrictions
    if((Surf.Flags.Gpu.IndirectClearColor) &&
       !( //--- Legitimate IndirectClearColor Case ------------------------------------------
       ((GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) >= IGFX_GEN9_CORE) &&
        Surf.Flags.Gpu.UnifiedAuxSurface) ||
       ((GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) > IGFX_GEN11_CORE) &&
        (Surf.Flags.Gpu.HiZ || Surf.Flags.Gpu.SeparateStencil))))
    {
        GMM_ASSERTDPF(0, "Invalid IndirectClearColor usage!");
        goto ERROR_CASE;
    }

    // CornerTexelMode Restrictions
    if(Surf.Flags.Info.CornerTexelMode &&
       (!( //--- Legitimate CornerTexelMode Case -------------------------------------------
       (GFX_GET_CURRENT_RENDERCORE(pPlatformResource->Platform) >= IGFX_GEN11_CORE) &&
       (!GmmIsPlanar(Surf.Format)) &&
       (!Surf.Flags.Info.StdSwizzle))))
    {
        GMM_ASSERTDPF(0, "Flag.Info.CornerTexelMode not supported on this platform.");
        goto ERROR_CASE;
    }

 //MultiTileArch params
    if(pGmmGlobalContext->GetSkuTable().FtrMultiTileArch)
    {
        /*
            MultiTileArch validation criteria 
            - MultiTileArch.Enable must be set.
            - NonLocalOnly alloc must have LocalEligibilitySet and LocalPreferenceSet both zero
            - LocalOnly alloc must have non-zero LocalEligibilitySet
            - GpuVaMappingSet/LocalEligibilitySet must be subset of GtSysInfo.TileMask
            - PreferredSet must be subset of EligibilitySet or zero
        */
        if(!(
           // Legitimate cases
           MultiTileArch.Enable &&
           (Surf.Flags.Info.NonLocalOnly || MultiTileArch.LocalMemEligibilitySet) &&
           ((MultiTileArch.GpuVaMappingSet & pGmmGlobalContext->GetGtSysInfo()->MultiTileArchInfo.TileMask) == MultiTileArch.GpuVaMappingSet) &&
           ((MultiTileArch.LocalMemEligibilitySet & pGmmGlobalContext->GetGtSysInfo()->MultiTileArchInfo.TileMask) == MultiTileArch.LocalMemEligibilitySet) &&
           ((MultiTileArch.LocalMemEligibilitySet & MultiTileArch.LocalMemPreferredSet) == MultiTileArch.LocalMemPreferredSet)))
        {
            GMM_ASSERTDPF(0, "Invalid MultiTileArch allocation params");
            goto ERROR_CASE;
        }
    }

    // check 2D, 3D & Cubemap dimensions
    switch(Surf.Type)
    {
        case RESOURCE_1D:
        case RESOURCE_2D:
        case RESOURCE_3D:
        {
            if(!Surf.BaseWidth || !Surf.BaseHeight)
            {
                GMM_ASSERTDPF(0, "Width or Height is 0!");
                goto ERROR_CASE;
            }
            break;
        }
        case RESOURCE_CUBE:
        {
            if(!Surf.BaseWidth || !Surf.BaseHeight)
            {
                GMM_ASSERTDPF(0, "Cubemap Dimensions invalid!");
                goto ERROR_CASE;
            }
            if(Surf.BaseWidth != Surf.BaseHeight)
            {
                GMM_ASSERTDPF(0, "Cubemap Dimensions invalid (width != Height)!");
                goto ERROR_CASE;
            }
            break;
        }
        case RESOURCE_SCRATCH:
        case RESOURCE_BUFFER:
        {
            if(Surf.BaseHeight != 1)
            {
                GMM_ASSERTDPF(0, "Linear surface height not 1!");
                goto ERROR_CASE;
            }
            break;
        }
        default:
            break;
    }

    GMM_DPF_EXIT;
    return 1;

ERROR_CASE:
    __GMM_ASSERT(0);
    return 0;
}

//=============================================================================
//
// Function: GetDisplayCompressionSupport
//
// Desc: Returns true if display hw supports lossless render/media decompression
//       else returns false.
//       Umds can call it to decide if full resolve is required
//
// Parameters:
//      See function arguments.
//
// Returns:
//      uint8_t
//-----------------------------------------------------------------------------
uint8_t GMM_STDCALL GmmLib::GmmResourceInfoCommon::GetDisplayCompressionSupport()
{
    uint8_t             ComprSupported = 0;
    GMM_RESOURCE_FORMAT Format         = Surf.Format;

    if(Surf.Flags.Gpu.UnifiedAuxSurface)
    {
        bool IsSupportedRGB64_16_16_16_16 = false;
        bool IsSupportedRGB32_8_8_8_8     = false;
        bool IsSupportedRGB32_2_10_10_10  = false;
        bool IsSupportedMediaFormats      = false;

        switch(Format) //RGB64 16:16 : 16 : 16 FP16
        {
            case GMM_FORMAT_R16G16B16A16_FLOAT:
            case GMM_FORMAT_R16G16B16X16_FLOAT:
                IsSupportedRGB64_16_16_16_16 = true;
            default:
                break;
        }

        switch(Format) //RGB32 8 : 8 : 8 : 8
        {
            case GMM_FORMAT_B8G8R8A8_UNORM:
            case GMM_FORMAT_R8G8B8A8_UNORM:
            case GMM_FORMAT_B8G8R8X8_UNORM:
            case GMM_FORMAT_R8G8B8X8_UNORM:
            case GMM_FORMAT_R8G8B8A8_UNORM_SRGB:
            case GMM_FORMAT_B8X8_UNORM_G8R8_SNORM:
            case GMM_FORMAT_X8B8_UNORM_G8R8_SNORM:
            case GMM_FORMAT_A8X8_UNORM_G8R8_SNORM:
            case GMM_FORMAT_B8G8R8A8_UNORM_SRGB:
            case GMM_FORMAT_B8G8R8X8_UNORM_SRGB:
            case GMM_FORMAT_R8G8B8A8_SINT:
            case GMM_FORMAT_R8G8B8A8_SNORM:
            case GMM_FORMAT_R8G8B8A8_SSCALED:
            case GMM_FORMAT_R8G8B8A8_UINT:
            case GMM_FORMAT_R8G8B8A8_USCALED:
            case GMM_FORMAT_R8G8B8X8_UNORM_SRGB:
                IsSupportedRGB32_8_8_8_8 = true;
            default:
                break;
        }

        switch(Format) //RGB32 2 : 10 : 10 : 10
        {
            case GMM_FORMAT_B10G10R10X2_UNORM:
            case GMM_FORMAT_R10G10B10A2_UNORM:
            case GMM_FORMAT_B10G10R10A2_UNORM:
            case GMM_FORMAT_B10G10R10A2_SINT:
            case GMM_FORMAT_B10G10R10A2_SNORM:
            case GMM_FORMAT_B10G10R10A2_SSCALED:
            case GMM_FORMAT_B10G10R10A2_UINT:
            case GMM_FORMAT_B10G10R10A2_UNORM_SRGB:
            case GMM_FORMAT_B10G10R10A2_USCALED:
            case GMM_FORMAT_R10G10B10_FLOAT_A2_UNORM:
            case GMM_FORMAT_R10G10B10_SNORM_A2_UNORM:
            case GMM_FORMAT_R10G10B10A2_SINT:
            case GMM_FORMAT_R10G10B10A2_SNORM:
            case GMM_FORMAT_R10G10B10A2_SSCALED:
            case GMM_FORMAT_R10G10B10A2_UINT:
            case GMM_FORMAT_R10G10B10A2_UNORM_SRGB:
            case GMM_FORMAT_R10G10B10A2_USCALED:
            case GMM_FORMAT_R10G10B10X2_USCALED:
            case GMM_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
                IsSupportedRGB32_2_10_10_10 = true;
            default:
                break;
        }

        switch(Format)
        {
            case GMM_FORMAT_YUY2: //YUV422 8 bpc
            case GMM_FORMAT_NV12: //YUV420 - NV12
            case GMM_FORMAT_P010: //YUV420 - P0xx
            case GMM_FORMAT_P016:
            case GMM_FORMAT_Y210: //YUV422 - Y210, Y212, Y216
            case GMM_FORMAT_Y216:
            case GMM_FORMAT_Y410: //YUV444 - Y410
            case GMM_FORMAT_Y416:
                IsSupportedMediaFormats = true; //YUV444 - Y412, Y416
            default:
                break;
        }

        //Check fmt is display decompressible
        ComprSupported = pGmmGlobalContext->GetPlatformInfoObj()->CheckFmtDisplayDecompressible(Surf, IsSupportedRGB64_16_16_16_16,
                                                                                                IsSupportedRGB32_8_8_8_8, IsSupportedRGB32_2_10_10_10,
                                                                                                IsSupportedMediaFormats);
    }

    return ComprSupported;
}

//=============================================================================
//
// Function: GetDisplayFastClearSupport
//
// Desc: Returns 1 if display hw supports fast clear else returns 0.
//       Umds can call it to decide if FC resolve is required
//
// Parameters:
//      See function arguments.
//
// Returns:
//      uint8_t
//-----------------------------------------------------------------------------
uint8_t GMM_STDCALL GmmLib::GmmResourceInfoCommon::GetDisplayFastClearSupport()
{
    uint8_t FCSupported = 0;

    if(GFX_GET_CURRENT_RENDERCORE(pGmmGlobalContext->GetPlatformInfo().Platform) >= IGFX_GEN11_CORE)
    {
        FCSupported = GetDisplayCompressionSupport() && !GmmIsPlanar(Surf.Format);
        FCSupported &= Surf.Flags.Gpu.IndirectClearColor;
    }

    return FCSupported;
}
