/*==============================================================================
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;
                }
            }
            else
            {
                // 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;
                    }
                }
            }
        }
        else
        {
            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;
    }


    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;
}
