private static void CreateTextureFromDDS(
            D3D11Device device,
            D3D11DeviceContext context,
            DdsFile dds,
            byte[] bitData,
            int maxSize,
            D3D11Usage usage,
            D3D11BindOptions bindOptions,
            D3D11CpuAccessOptions cpuAccessOptions,
            D3D11ResourceMiscOptions miscOptions,
            bool forceSRGB,
            out D3D11Resource texture,
            out D3D11ShaderResourceView textureView)
        {
            int width  = dds.Width;
            int height = dds.Height;
            int depth  = dds.Depth;

            D3D11ResourceDimension resDim = (D3D11ResourceDimension)dds.ResourceDimension;
            int        arraySize          = Math.Max(1, dds.ArraySize);
            DxgiFormat format             = (DxgiFormat)dds.Format;
            bool       isCubeMap          = false;

            if (dds.Format == DdsFormat.Unknown)
            {
                if (dds.PixelFormat.RgbBitCount == 32)
                {
                    if (IsBitMask(dds.PixelFormat, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000))
                    {
                        format = DxgiFormat.B8G8R8X8UNorm;
                        int length = bitData.Length / 4;
                        var bytes  = new byte[length * 4];

                        for (int i = 0; i < length; i++)
                        {
                            bytes[i * 4 + 0] = bitData[i * 4 + 2];
                            bytes[i * 4 + 1] = bitData[i * 4 + 1];
                            bytes[i * 4 + 2] = bitData[i * 4 + 0];
                        }

                        bitData = bytes;
                    }
                }
                else if (dds.PixelFormat.RgbBitCount == 24)
                {
                    if (IsBitMask(dds.PixelFormat, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000))
                    {
                        format = DxgiFormat.B8G8R8X8UNorm;
                        int length = bitData.Length / 3;
                        var bytes  = new byte[length * 4];

                        for (int i = 0; i < length; i++)
                        {
                            bytes[i * 4 + 0] = bitData[i * 3 + 0];
                            bytes[i * 4 + 1] = bitData[i * 3 + 1];
                            bytes[i * 4 + 2] = bitData[i * 3 + 2];
                        }

                        bitData = bytes;
                    }
                }
            }

            int mipCount = Math.Max(1, dds.MipmapCount);

            switch (format)
            {
            case DxgiFormat.AI44:
            case DxgiFormat.IA44:
            case DxgiFormat.P8:
            case DxgiFormat.A8P8:
                throw new NotSupportedException(format.ToString() + " format is not supported.");

            default:
                if (DdsHelpers.GetBitsPerPixel((DdsFormat)format) == 0)
                {
                    throw new NotSupportedException(format.ToString() + " format is not supported.");
                }

                break;
            }

            switch (resDim)
            {
            case D3D11ResourceDimension.Texture1D:
                // D3DX writes 1D textures with a fixed Height of 1
                if ((dds.Options & DdsOptions.Height) != 0 && height != 1)
                {
                    throw new InvalidDataException();
                }

                height = 1;
                depth  = 1;
                break;

            case D3D11ResourceDimension.Texture2D:
                if ((dds.ResourceMiscOptions & DdsResourceMiscOptions.TextureCube) != 0)
                {
                    arraySize *= 6;
                    isCubeMap  = true;
                }

                depth = 1;
                break;

            case D3D11ResourceDimension.Texture3D:
                if ((dds.Options & DdsOptions.Depth) == 0)
                {
                    throw new InvalidDataException();
                }

                if (arraySize > 1)
                {
                    throw new NotSupportedException();
                }
                break;

            default:
                if ((dds.Options & DdsOptions.Depth) != 0)
                {
                    resDim = D3D11ResourceDimension.Texture3D;
                }
                else
                {
                    if ((dds.Caps2 & DdsAdditionalCaps.CubeMap) != 0)
                    {
                        // We require all six faces to be defined
                        if ((dds.Caps2 & DdsAdditionalCaps.CubeMapAllFaces) != DdsAdditionalCaps.CubeMapAllFaces)
                        {
                            throw new NotSupportedException();
                        }

                        arraySize = 6;
                        isCubeMap = true;
                    }

                    depth  = 1;
                    resDim = D3D11ResourceDimension.Texture2D;

                    // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture
                }

                break;
            }

            if ((miscOptions & D3D11ResourceMiscOptions.TextureCube) != 0 &&
                resDim == D3D11ResourceDimension.Texture2D &&
                (arraySize % 6 == 0))
            {
                isCubeMap = true;
            }

            // Bound sizes (for security purposes we don't trust DDS file metadata larger than the D3D 11.x hardware requirements)
            if (mipCount > D3D11Constants.ReqMipLevels)
            {
                throw new NotSupportedException();
            }

            switch (resDim)
            {
            case D3D11ResourceDimension.Texture1D:
                if (arraySize > D3D11Constants.ReqTexture1DArrayAxisDimension ||
                    width > D3D11Constants.ReqTexture1DDimension)
                {
                    throw new NotSupportedException();
                }

                break;

            case D3D11ResourceDimension.Texture2D:
                if (isCubeMap)
                {
                    // This is the right bound because we set arraySize to (NumCubes*6) above
                    if (arraySize > D3D11Constants.ReqTexture2DArrayAxisDimension ||
                        width > D3D11Constants.ReqTextureCubeDimension ||
                        height > D3D11Constants.ReqTextureCubeDimension)
                    {
                        throw new NotSupportedException();
                    }
                }
                else if (arraySize > D3D11Constants.ReqTexture2DArrayAxisDimension ||
                         width > D3D11Constants.ReqTexture2DDimension ||
                         height > D3D11Constants.ReqTexture2DDimension)
                {
                    throw new NotSupportedException();
                }

                break;

            case D3D11ResourceDimension.Texture3D:
                if (arraySize > 1 ||
                    width > D3D11Constants.ReqTexture3DDimension ||
                    height > D3D11Constants.ReqTexture3DDimension ||
                    depth > D3D11Constants.ReqTexture3DDimension)
                {
                    throw new NotSupportedException();
                }

                break;

            default:
                throw new NotSupportedException();
            }

            bool autogen = false;

            if (mipCount == 1)
            {
                // See if format is supported for auto-gen mipmaps (varies by feature level)
                if (!device.CheckFormatSupport(format, out D3D11FormatSupport fmtSupport) &&
                    (fmtSupport & D3D11FormatSupport.MipAutogen) != 0)
                {
                    // 10level9 feature levels do not support auto-gen mipgen for volume textures
                    if (resDim != D3D11ResourceDimension.Texture3D ||
                        device.FeatureLevel >= D3D11FeatureLevel.FeatureLevel100)
                    {
                        autogen = true;
                    }
                }
            }

            if (autogen)
            {
                // Create texture with auto-generated mipmaps
                CreateD3DResources(
                    device,
                    resDim,
                    width,
                    height,
                    depth,
                    0,
                    arraySize,
                    format,
                    usage,
                    bindOptions | D3D11BindOptions.RenderTarget,
                    cpuAccessOptions,
                    miscOptions | D3D11ResourceMiscOptions.GenerateMips,
                    forceSRGB,
                    isCubeMap,
                    null,
                    out texture,
                    out textureView);

                try
                {
                    DdsHelpers.GetSurfaceInfo(width, height, (DdsFormat)format, out int numBytes, out int rowBytes, out int numRows);

                    if (numBytes > bitData.Length)
                    {
                        throw new EndOfStreamException();
                    }

                    D3D11ShaderResourceViewDesc desc = textureView.Description;
                    uint mipLevels = 1;

                    switch (desc.ViewDimension)
                    {
                    case D3D11SrvDimension.Texture1D:
                        mipLevels = desc.Texture1D.MipLevels;
                        break;

                    case D3D11SrvDimension.Texture1DArray:
                        mipLevels = desc.Texture1DArray.MipLevels;
                        break;

                    case D3D11SrvDimension.Texture2D:
                        mipLevels = desc.Texture2D.MipLevels;
                        break;

                    case D3D11SrvDimension.Texture2DArray:
                        mipLevels = desc.Texture2DArray.MipLevels;
                        break;

                    case D3D11SrvDimension.TextureCube:
                        mipLevels = desc.TextureCube.MipLevels;
                        break;

                    case D3D11SrvDimension.TextureCubeArray:
                        mipLevels = desc.TextureCubeArray.MipLevels;
                        break;

                    case D3D11SrvDimension.Texture3D:
                        mipLevels = desc.Texture3D.MipLevels;
                        break;

                    default:
                        throw new InvalidDataException();
                    }

                    if (arraySize > 1)
                    {
                        int pSrcBits = 0;

                        for (uint item = 0; item < (uint)arraySize; item++)
                        {
                            if (pSrcBits + numBytes > bitData.Length)
                            {
                                throw new EndOfStreamException();
                            }

                            var data = new byte[numBytes];
                            Array.Copy(bitData, pSrcBits, data, 0, numBytes);

                            uint res = D3D11Utils.CalcSubresource(0, item, mipLevels);
                            context.UpdateSubresource(texture, res, null, data, (uint)rowBytes, (uint)numBytes);

                            pSrcBits += numBytes;
                        }
                    }
                    else
                    {
                        context.UpdateSubresource(texture, 0, null, bitData, (uint)rowBytes, (uint)numBytes);
                    }

                    context.GenerateMips(textureView);
                }
                catch
                {
                    D3D11Utils.DisposeAndNull(ref textureView);
                    D3D11Utils.DisposeAndNull(ref texture);
                    throw;
                }
            }
            else
            {
                // Create the texture

                if (!FillInitData(
                        width,
                        height,
                        depth,
                        mipCount,
                        arraySize,
                        format,
                        maxSize,
                        bitData,
                        out int twidth,
                        out int theight,
                        out int tdepth,
                        out int skipMip,
                        out D3D11SubResourceData[] initData))