bool DirectX::IsSupportedTexture()

in DirectXTex/DirectXTexD3D11.cpp [205:396]


bool DirectX::IsSupportedTexture(
    ID3D11Device* pDevice,
    const TexMetadata& metadata) noexcept
{
    if (!pDevice)
        return false;

    D3D_FEATURE_LEVEL fl = pDevice->GetFeatureLevel();

    // Validate format
    DXGI_FORMAT fmt = metadata.format;

    if (!IsValid(fmt))
        return false;

    switch (fmt)
    {
    case DXGI_FORMAT_BC4_TYPELESS:
    case DXGI_FORMAT_BC4_UNORM:
    case DXGI_FORMAT_BC4_SNORM:
    case DXGI_FORMAT_BC5_TYPELESS:
    case DXGI_FORMAT_BC5_UNORM:
    case DXGI_FORMAT_BC5_SNORM:
        if (fl < D3D_FEATURE_LEVEL_10_0)
            return false;
        break;

    case DXGI_FORMAT_BC6H_TYPELESS:
    case DXGI_FORMAT_BC6H_UF16:
    case DXGI_FORMAT_BC6H_SF16:
    case DXGI_FORMAT_BC7_TYPELESS:
    case DXGI_FORMAT_BC7_UNORM:
    case DXGI_FORMAT_BC7_UNORM_SRGB:
        if (fl < D3D_FEATURE_LEVEL_11_0)
            return false;
        break;

    default:
        break;
    }

    // Validate miplevel count
    if (metadata.mipLevels > D3D11_REQ_MIP_LEVELS)
        return false;

    // Validate array size, dimension, and width/height
    size_t arraySize = metadata.arraySize;
    size_t iWidth = metadata.width;
    size_t iHeight = metadata.height;
    size_t iDepth = metadata.depth;

    // Most cases are known apriori based on feature level, but we use this for robustness to handle the few optional cases
    UINT formatSupport = 0;
    HRESULT hr = pDevice->CheckFormatSupport(fmt, &formatSupport);
    if (FAILED(hr))
    {
        formatSupport = 0;
    }

    if (metadata.mipLevels > 1 && !(formatSupport & D3D11_FORMAT_SUPPORT_MIP))
    {
        return false;
    }

    switch (metadata.dimension)
    {
    case TEX_DIMENSION_TEXTURE1D:
        if (!(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE1D))
            return false;

        if ((arraySize > D3D11_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION)
            || (iWidth > D3D11_REQ_TEXTURE1D_U_DIMENSION))
            return false;

        if (fl < D3D_FEATURE_LEVEL_11_0)
        {
            if ((arraySize > D3D10_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION)
                || (iWidth > D3D10_REQ_TEXTURE1D_U_DIMENSION))
                return false;

            if (fl < D3D_FEATURE_LEVEL_10_0)
            {
                if ((arraySize > 1) || (iWidth > D3D_FL9_3_REQ_TEXTURE1D_U_DIMENSION))
                    return false;

                if ((fl < D3D_FEATURE_LEVEL_9_3) && (iWidth > D3D_FL9_1_REQ_TEXTURE1D_U_DIMENSION))
                    return false;
            }
        }
        break;

    case TEX_DIMENSION_TEXTURE2D:
        if (metadata.IsCubemap())
        {
            if (!(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE))
                return false;

            if ((arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
                || (iWidth > D3D11_REQ_TEXTURECUBE_DIMENSION)
                || (iHeight > D3D11_REQ_TEXTURECUBE_DIMENSION))
                return false;

            if (fl < D3D_FEATURE_LEVEL_11_0)
            {
                if ((arraySize > D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
                    || (iWidth > D3D10_REQ_TEXTURECUBE_DIMENSION)
                    || (iHeight > D3D10_REQ_TEXTURECUBE_DIMENSION))
                    return false;

                if ((fl < D3D_FEATURE_LEVEL_10_1) && (arraySize != 6))
                    return false;

                if (fl < D3D_FEATURE_LEVEL_10_0)
                {
                    if ((iWidth > D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION)
                        || (iHeight > D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION))
                        return false;

                    if ((fl < D3D_FEATURE_LEVEL_9_3)
                        && ((iWidth > D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION)
                            || (iHeight > D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION)))
                        return false;
                }
            }
        }
        else // Not a cube map
        {
            if (!(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D))
                return false;

            if ((arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
                || (iWidth > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION)
                || (iHeight > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION))
                return false;

            if (fl < D3D_FEATURE_LEVEL_11_0)
            {
                if ((arraySize > D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
                    || (iWidth > D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION)
                    || (iHeight > D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION))
                    return false;

                if (fl < D3D_FEATURE_LEVEL_10_0)
                {
                    if ((arraySize > 1)
                        || (iWidth > D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION)
                        || (iHeight > D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION))
                        return false;

                    if ((fl < D3D_FEATURE_LEVEL_9_3)
                        && ((iWidth > D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION)
                            || (iHeight > D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION)))
                        return false;
                }
            }
        }
        break;

    case TEX_DIMENSION_TEXTURE3D:
        if (!(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D))
            return false;

        if ((arraySize > 1)
            || (iWidth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
            || (iHeight > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
            || (iDepth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION))
            return false;

        if (fl < D3D_FEATURE_LEVEL_11_0)
        {
            if ((iWidth > D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
                || (iHeight > D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
                || (iDepth > D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION))
                return false;

            if (fl < D3D_FEATURE_LEVEL_10_0)
            {
                if ((iWidth > D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
                    || (iHeight > D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
                    || (iDepth > D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION))
                    return false;
            }
        }
        break;

    default:
        // Not a supported dimension
        return false;
    }

    return true;
}