virtual void GetTextureFormats(const UTexture* Texture, TArray<FName>& OutFormats) const
	{
		check(Texture);

		// we remap some of the defaults (with PVRTC and ASTC formats)
		static FName FormatRemap[][2] =
		{
			// Default format:				ASTC format:
			{ { FName(TEXT("DXT1")) },		{ FName(TEXT("ASTC_RGB")) } },
			{ { FName(TEXT("DXT5")) },		{ FName(TEXT("ASTC_RGBA")) } },
			{ { FName(TEXT("DXT5n")) },		{ FName(TEXT("ASTC_NormalAG")) } },
			{ { FName(TEXT("BC5")) },		{ FName(TEXT("ASTC_NormalRG")) } },
			{ { FName(TEXT("BC6H")) },		{ FName(TEXT("ASTC_RGB")) } },
			{ { FName(TEXT("BC7")) },		{ FName(TEXT("ASTC_RGBAuto")) } },
			{ { FName(TEXT("AutoDXT")) },	{ FName(TEXT("ASTC_RGBAuto")) } },
		};

		FName TextureFormatName = NAME_None;

		// forward rendering only needs one channel for shadow maps
		if (Texture->LODGroup == TEXTUREGROUP_Shadowmap)
		{
			TextureFormatName = FName(TEXT("G8"));
		}

		// if we didn't assign anything specially, then use the defaults
		if (TextureFormatName == NAME_None)
		{
			TextureFormatName = GetDefaultTextureFormatName(Texture, EngineSettings, false);
		}

		// perform any remapping away from defaults
		bool bFoundRemap = false;
		for (int32 RemapIndex = 0; RemapIndex < ARRAY_COUNT(FormatRemap); ++RemapIndex)
		{
			if (TextureFormatName == FormatRemap[RemapIndex][0])
			{
				// we found a remapping
				bFoundRemap = true;
				OutFormats.AddUnique(FormatRemap[RemapIndex][1]);
			}
		}

		// if we didn't already remap above, add it now
		if (!bFoundRemap)
		{
			OutFormats.Add(TextureFormatName);
		}
	}
void FIOSTargetPlatform::GetTextureFormats( const UTexture* Texture, TArray<FName>& OutFormats ) const
{
	check(Texture);

	// we remap some of the defaults (with PVRTC and ASTC formats)
	static FName FormatRemap[] =
	{
		// original				PVRTC						ASTC
		FName(TEXT("DXT1")),	FName(TEXT("PVRTC2")),		FName(TEXT("ASTC_RGB")),
		FName(TEXT("DXT5")),	FName(TEXT("PVRTC4")),		FName(TEXT("ASTC_RGBA")),
		FName(TEXT("DXT5n")),	FName(TEXT("PVRTCN")),		FName(TEXT("ASTC_NormalAG")),
		FName(TEXT("BC5")),		FName(TEXT("PVRTCN")),		FName(TEXT("ASTC_NormalRG")),
		FName(TEXT("AutoDXT")),	FName(TEXT("AutoPVRTC")),	FName(TEXT("ASTC_RGBAuto")),
	};
	static FName NameBGRA8(TEXT("BGRA8"));
	static FName NamePOTERROR(TEXT("POTERROR"));

	FName TextureFormatName = NAME_None;

	// forward rendering only needs one channel for shadow maps
	if (Texture->LODGroup == TEXTUREGROUP_Shadowmap && !SupportsMetalMRT())
	{
		TextureFormatName = FName(TEXT("G8"));
	}

	// if we didn't assign anything specially, then use the defaults
	if (TextureFormatName == NAME_None)
	{
		TextureFormatName = GetDefaultTextureFormatName(Texture, EngineSettings, false);
	}

	// perform any remapping away from defaults
	bool bFoundRemap = false;
	bool bIncludePVRTC = CookPVRTC();
	bool bIncludeASTC = CookASTC();
	for (int32 RemapIndex = 0; RemapIndex < ARRAY_COUNT(FormatRemap); RemapIndex += 3)
	{
		if (TextureFormatName == FormatRemap[RemapIndex])
		{
			// we found a remapping
			bFoundRemap = true;
			// include the formats we want (use ASTC first so that it is preferred at runtime if they both exist and it's supported)
			if (bIncludeASTC)
			{
				OutFormats.AddUnique(FormatRemap[RemapIndex + 2]);
			}
			if (bIncludePVRTC)
			{
				// handle non-power of 2 textures
				if (!Texture->Source.IsPowerOfTwo())
				{
					// option 1: Uncompress, but users will get very large textures unknowningly
					// OutFormats.AddUnique(NameBGRA8);
					// option 2: Use an "error message" texture so they see it in game
					OutFormats.AddUnique(NamePOTERROR);
				}
				else
				{
					OutFormats.AddUnique(FormatRemap[RemapIndex + 1]);
				}
			}
		}
	}

	// if we didn't already remap above, add it now
	if (!bFoundRemap)
	{
		OutFormats.Add(TextureFormatName);
	}
}