mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-28 01:49:33 -06:00
VideoCommon: use CustomResourceManager in the texture cache and hook up to our hires textures
This commit is contained in:
@ -25,7 +25,6 @@
|
|||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
#include "VideoCommon/Assets/CustomAsset.h"
|
#include "VideoCommon/Assets/CustomAsset.h"
|
||||||
#include "VideoCommon/Assets/CustomAssetLoader.h"
|
|
||||||
#include "VideoCommon/Assets/DirectFilesystemAssetLibrary.h"
|
#include "VideoCommon/Assets/DirectFilesystemAssetLibrary.h"
|
||||||
#include "VideoCommon/OnScreenDisplay.h"
|
#include "VideoCommon/OnScreenDisplay.h"
|
||||||
#include "VideoCommon/VideoConfig.h"
|
#include "VideoCommon/VideoConfig.h"
|
||||||
@ -95,8 +94,6 @@ void HiresTexture::Update()
|
|||||||
GetTextureDirectoriesWithGameId(File::GetUserPath(D_HIRESTEXTURES_IDX), game_id);
|
GetTextureDirectoriesWithGameId(File::GetUserPath(D_HIRESTEXTURES_IDX), game_id);
|
||||||
const std::vector<std::string> extensions{".png", ".dds"};
|
const std::vector<std::string> extensions{".png", ".dds"};
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
|
|
||||||
for (const auto& texture_directory : texture_directories)
|
for (const auto& texture_directory : texture_directories)
|
||||||
{
|
{
|
||||||
const auto texture_paths =
|
const auto texture_paths =
|
||||||
@ -130,10 +127,10 @@ void HiresTexture::Update()
|
|||||||
|
|
||||||
if (g_ActiveConfig.bCacheHiresTextures)
|
if (g_ActiveConfig.bCacheHiresTextures)
|
||||||
{
|
{
|
||||||
auto hires_texture = std::make_shared<HiresTexture>(
|
auto hires_texture =
|
||||||
has_arbitrary_mipmaps,
|
std::make_shared<HiresTexture>(has_arbitrary_mipmaps, std::move(filename));
|
||||||
system.GetCustomAssetLoader().LoadGameTexture(filename, s_file_library));
|
static_cast<void>(hires_texture->LoadTexture());
|
||||||
s_hires_texture_cache.try_emplace(filename, std::move(hires_texture));
|
s_hires_texture_cache.try_emplace(hires_texture->GetId(), hires_texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,7 +164,7 @@ void HiresTexture::Clear()
|
|||||||
|
|
||||||
std::shared_ptr<HiresTexture> HiresTexture::Search(const TextureInfo& texture_info)
|
std::shared_ptr<HiresTexture> HiresTexture::Search(const TextureInfo& texture_info)
|
||||||
{
|
{
|
||||||
const auto [base_filename, has_arb_mipmaps] = GetNameArbPair(texture_info);
|
auto [base_filename, has_arb_mipmaps] = GetNameArbPair(texture_info);
|
||||||
if (base_filename == "")
|
if (base_filename == "")
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@ -177,24 +174,27 @@ std::shared_ptr<HiresTexture> HiresTexture::Search(const TextureInfo& texture_in
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto hires_texture = std::make_shared<HiresTexture>(has_arb_mipmaps, std::move(base_filename));
|
||||||
auto hires_texture = std::make_shared<HiresTexture>(
|
|
||||||
has_arb_mipmaps,
|
|
||||||
system.GetCustomAssetLoader().LoadGameTexture(base_filename, s_file_library));
|
|
||||||
if (g_ActiveConfig.bCacheHiresTextures)
|
if (g_ActiveConfig.bCacheHiresTextures)
|
||||||
{
|
{
|
||||||
s_hires_texture_cache.try_emplace(base_filename, hires_texture);
|
s_hires_texture_cache.try_emplace(hires_texture->GetId(), hires_texture);
|
||||||
}
|
}
|
||||||
return hires_texture;
|
return hires_texture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HiresTexture::HiresTexture(bool has_arbitrary_mipmaps,
|
HiresTexture::HiresTexture(bool has_arbitrary_mipmaps, std::string id)
|
||||||
std::shared_ptr<VideoCommon::GameTextureAsset> asset)
|
: m_has_arbitrary_mipmaps(has_arbitrary_mipmaps), m_id(std::move(id))
|
||||||
: m_has_arbitrary_mipmaps(has_arbitrary_mipmaps), m_game_texture(std::move(asset))
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VideoCommon::CustomResourceManager::TextureTimePair HiresTexture::LoadTexture() const
|
||||||
|
{
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& custom_resource_manager = system.GetCustomResourceManager();
|
||||||
|
return custom_resource_manager.GetTextureDataFromAsset(m_id, s_file_library);
|
||||||
|
}
|
||||||
|
|
||||||
std::set<std::string> GetTextureDirectoriesWithGameId(const std::string& root_directory,
|
std::set<std::string> GetTextureDirectoriesWithGameId(const std::string& root_directory,
|
||||||
const std::string& game_id)
|
const std::string& game_id)
|
||||||
{
|
{
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "VideoCommon/Assets/CustomResourceManager.h"
|
||||||
#include "VideoCommon/Assets/CustomTextureData.h"
|
#include "VideoCommon/Assets/CustomTextureData.h"
|
||||||
#include "VideoCommon/Assets/TextureAsset.h"
|
|
||||||
#include "VideoCommon/TextureConfig.h"
|
#include "VideoCommon/TextureConfig.h"
|
||||||
#include "VideoCommon/TextureInfo.h"
|
#include "VideoCommon/TextureInfo.h"
|
||||||
|
|
||||||
@ -27,12 +27,13 @@ public:
|
|||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
static std::shared_ptr<HiresTexture> Search(const TextureInfo& texture_info);
|
static std::shared_ptr<HiresTexture> Search(const TextureInfo& texture_info);
|
||||||
|
|
||||||
HiresTexture(bool has_arbitrary_mipmaps, std::shared_ptr<VideoCommon::GameTextureAsset> asset);
|
HiresTexture(bool has_arbitrary_mipmaps, std::string id);
|
||||||
|
|
||||||
bool HasArbitraryMipmaps() const { return m_has_arbitrary_mipmaps; }
|
bool HasArbitraryMipmaps() const { return m_has_arbitrary_mipmaps; }
|
||||||
const std::shared_ptr<VideoCommon::GameTextureAsset>& GetAsset() const { return m_game_texture; }
|
VideoCommon::CustomResourceManager::TextureTimePair LoadTexture() const;
|
||||||
|
const std::string& GetId() const { return m_id; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_has_arbitrary_mipmaps = false;
|
bool m_has_arbitrary_mipmaps = false;
|
||||||
std::shared_ptr<VideoCommon::GameTextureAsset> m_game_texture;
|
std::string m_id;
|
||||||
};
|
};
|
||||||
|
@ -37,13 +37,14 @@
|
|||||||
#include "VideoCommon/AbstractFramebuffer.h"
|
#include "VideoCommon/AbstractFramebuffer.h"
|
||||||
#include "VideoCommon/AbstractGfx.h"
|
#include "VideoCommon/AbstractGfx.h"
|
||||||
#include "VideoCommon/AbstractStagingTexture.h"
|
#include "VideoCommon/AbstractStagingTexture.h"
|
||||||
|
#include "VideoCommon/Assets/CustomResourceManager.h"
|
||||||
#include "VideoCommon/Assets/CustomTextureData.h"
|
#include "VideoCommon/Assets/CustomTextureData.h"
|
||||||
|
#include "VideoCommon/Assets/TextureAssetUtils.h"
|
||||||
#include "VideoCommon/BPMemory.h"
|
#include "VideoCommon/BPMemory.h"
|
||||||
#include "VideoCommon/FramebufferManager.h"
|
#include "VideoCommon/FramebufferManager.h"
|
||||||
#include "VideoCommon/GraphicsModSystem/Runtime/FBInfo.h"
|
#include "VideoCommon/GraphicsModSystem/Runtime/FBInfo.h"
|
||||||
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionData.h"
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionData.h"
|
||||||
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h"
|
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h"
|
||||||
#include "VideoCommon/HiresTextures.h"
|
|
||||||
#include "VideoCommon/OpcodeDecoding.h"
|
#include "VideoCommon/OpcodeDecoding.h"
|
||||||
#include "VideoCommon/PixelShaderManager.h"
|
#include "VideoCommon/PixelShaderManager.h"
|
||||||
#include "VideoCommon/Present.h"
|
#include "VideoCommon/Present.h"
|
||||||
@ -262,25 +263,12 @@ void TextureCacheBase::SetBackupConfig(const VideoConfig& config)
|
|||||||
|
|
||||||
bool TextureCacheBase::DidLinkedAssetsChange(const TCacheEntry& entry)
|
bool TextureCacheBase::DidLinkedAssetsChange(const TCacheEntry& entry)
|
||||||
{
|
{
|
||||||
for (const auto& cached_asset : entry.linked_game_texture_assets)
|
if (!entry.hires_texture)
|
||||||
{
|
|
||||||
if (cached_asset.m_asset)
|
|
||||||
{
|
|
||||||
if (cached_asset.m_asset->GetLastLoadedTime() > cached_asset.m_cached_write_time)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& cached_asset : entry.linked_asset_dependencies)
|
|
||||||
{
|
|
||||||
if (cached_asset.m_asset)
|
|
||||||
{
|
|
||||||
if (cached_asset.m_asset->GetLastLoadedTime() > cached_asset.m_cached_write_time)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const auto [texture_data, load_time] = entry.hires_texture->LoadTexture();
|
||||||
|
|
||||||
|
return load_time > entry.last_load_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
RcTcacheEntry TextureCacheBase::ApplyPaletteToEntry(RcTcacheEntry& entry, const u8* palette,
|
RcTcacheEntry TextureCacheBase::ApplyPaletteToEntry(RcTcacheEntry& entry, const u8* palette,
|
||||||
@ -1566,80 +1554,50 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp
|
|||||||
InvalidateTexture(oldest_entry);
|
InvalidateTexture(oldest_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VideoCommon::CachedAsset<VideoCommon::GameTextureAsset>> cached_game_assets;
|
std::shared_ptr<HiresTexture> hires_texture;
|
||||||
std::vector<std::shared_ptr<VideoCommon::TextureData>> data_for_assets;
|
|
||||||
bool has_arbitrary_mipmaps = false;
|
bool has_arbitrary_mipmaps = false;
|
||||||
bool skip_texture_dump = false;
|
bool skip_texture_dump = false;
|
||||||
std::shared_ptr<HiresTexture> hires_texture;
|
std::shared_ptr<VideoCommon::CustomTextureData> custom_texture_data = nullptr;
|
||||||
|
VideoCommon::CustomAsset::TimeType load_time = {};
|
||||||
if (g_ActiveConfig.bHiresTextures)
|
if (g_ActiveConfig.bHiresTextures)
|
||||||
{
|
{
|
||||||
hires_texture = HiresTexture::Search(texture_info);
|
hires_texture = HiresTexture::Search(texture_info);
|
||||||
if (hires_texture)
|
if (hires_texture)
|
||||||
{
|
{
|
||||||
auto asset = hires_texture->GetAsset();
|
|
||||||
const auto loaded_time = asset->GetLastLoadedTime();
|
|
||||||
cached_game_assets.push_back(
|
|
||||||
VideoCommon::CachedAsset<VideoCommon::GameTextureAsset>{std::move(asset), loaded_time});
|
|
||||||
has_arbitrary_mipmaps = hires_texture->HasArbitraryMipmaps();
|
has_arbitrary_mipmaps = hires_texture->HasArbitraryMipmaps();
|
||||||
|
std::tie(custom_texture_data, load_time) = hires_texture->LoadTexture();
|
||||||
|
if (custom_texture_data && !VideoCommon::ValidateTextureData(
|
||||||
|
hires_texture->GetId(), *custom_texture_data,
|
||||||
|
texture_info.GetRawWidth(), texture_info.GetRawHeight()))
|
||||||
|
{
|
||||||
|
custom_texture_data = nullptr;
|
||||||
|
load_time = {};
|
||||||
|
}
|
||||||
skip_texture_dump = true;
|
skip_texture_dump = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VideoCommon::CachedAsset<VideoCommon::CustomAsset>> additional_dependencies;
|
|
||||||
|
|
||||||
std::string texture_name = "";
|
std::string texture_name = "";
|
||||||
|
|
||||||
if (g_ActiveConfig.bGraphicMods)
|
if (g_ActiveConfig.bGraphicMods)
|
||||||
{
|
{
|
||||||
u32 height = texture_info.GetRawHeight();
|
u32 height = texture_info.GetRawHeight();
|
||||||
u32 width = texture_info.GetRawWidth();
|
u32 width = texture_info.GetRawWidth();
|
||||||
if (hires_texture)
|
|
||||||
{
|
|
||||||
auto asset = hires_texture->GetAsset();
|
|
||||||
if (asset)
|
|
||||||
{
|
|
||||||
auto data = asset->GetData();
|
|
||||||
if (data)
|
|
||||||
{
|
|
||||||
if (!data->m_texture.m_slices.empty())
|
|
||||||
{
|
|
||||||
if (!data->m_texture.m_slices[0].m_levels.empty())
|
|
||||||
{
|
|
||||||
height = data->m_texture.m_slices[0].m_levels[0].height;
|
|
||||||
width = data->m_texture.m_slices[0].m_levels[0].width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
texture_name = texture_info.CalculateTextureName().GetFullName();
|
texture_name = texture_info.CalculateTextureName().GetFullName();
|
||||||
GraphicsModActionData::TextureCreate texture_create{
|
GraphicsModActionData::TextureCreate texture_create{texture_name, width, height, nullptr,
|
||||||
texture_name, width, height, &cached_game_assets, &additional_dependencies};
|
nullptr};
|
||||||
for (const auto& action : g_graphics_mod_manager->GetTextureCreateActions(texture_name))
|
for (const auto& action : g_graphics_mod_manager->GetTextureCreateActions(texture_name))
|
||||||
{
|
{
|
||||||
action->OnTextureCreate(&texture_create);
|
action->OnTextureCreate(&texture_create);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data_for_assets.reserve(cached_game_assets.size());
|
|
||||||
for (auto& cached_asset : cached_game_assets)
|
|
||||||
{
|
|
||||||
auto data = cached_asset.m_asset->GetData();
|
|
||||||
if (data)
|
|
||||||
{
|
|
||||||
if (cached_asset.m_asset->Validate(texture_info.GetRawWidth(), texture_info.GetRawHeight()))
|
|
||||||
{
|
|
||||||
data_for_assets.push_back(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto entry =
|
auto entry =
|
||||||
CreateTextureEntry(TextureCreationInfo{base_hash, full_hash, bytes_per_block, palette_size},
|
CreateTextureEntry(TextureCreationInfo{base_hash, full_hash, bytes_per_block, palette_size},
|
||||||
texture_info, textureCacheSafetyColorSampleSize,
|
texture_info, textureCacheSafetyColorSampleSize, custom_texture_data.get(),
|
||||||
std::move(data_for_assets), has_arbitrary_mipmaps, skip_texture_dump);
|
has_arbitrary_mipmaps, skip_texture_dump);
|
||||||
entry->linked_game_texture_assets = std::move(cached_game_assets);
|
entry->hires_texture = std::move(hires_texture);
|
||||||
entry->linked_asset_dependencies = std::move(additional_dependencies);
|
entry->last_load_time = load_time;
|
||||||
entry->texture_info_name = std::move(texture_name);
|
entry->texture_info_name = std::move(texture_name);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
@ -1649,8 +1607,7 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp
|
|||||||
// expected because each texture is loaded into a texture array
|
// expected because each texture is loaded into a texture array
|
||||||
RcTcacheEntry TextureCacheBase::CreateTextureEntry(
|
RcTcacheEntry TextureCacheBase::CreateTextureEntry(
|
||||||
const TextureCreationInfo& creation_info, const TextureInfo& texture_info,
|
const TextureCreationInfo& creation_info, const TextureInfo& texture_info,
|
||||||
const int safety_color_sample_size,
|
const int safety_color_sample_size, VideoCommon::CustomTextureData* custom_texture_data,
|
||||||
std::vector<std::shared_ptr<VideoCommon::TextureData>> assets_data,
|
|
||||||
const bool custom_arbitrary_mipmaps, bool skip_texture_dump)
|
const bool custom_arbitrary_mipmaps, bool skip_texture_dump)
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@ -1660,33 +1617,22 @@ RcTcacheEntry TextureCacheBase::CreateTextureEntry(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
RcTcacheEntry entry;
|
RcTcacheEntry entry;
|
||||||
if (!assets_data.empty())
|
if (custom_texture_data)
|
||||||
{
|
{
|
||||||
const auto calculate_max_levels = [&]() {
|
const u32 texLevels = no_mips ? 1 : (u32)custom_texture_data->m_slices[0].m_levels.size();
|
||||||
const auto max_element = std::ranges::max_element(
|
const auto& first_level = custom_texture_data->m_slices[0].m_levels[0];
|
||||||
assets_data, {}, [](const auto& v) { return v->m_texture.m_slices[0].m_levels.size(); });
|
const TextureConfig config(first_level.width, first_level.height, texLevels, 1, 1,
|
||||||
return (*max_element)->m_texture.m_slices[0].m_levels.size();
|
first_level.format, 0, AbstractTextureType::Texture_2DArray);
|
||||||
};
|
|
||||||
const u32 texLevels = no_mips ? 1 : (u32)calculate_max_levels();
|
|
||||||
const auto& first_level = assets_data[0]->m_texture.m_slices[0].m_levels[0];
|
|
||||||
const TextureConfig config(first_level.width, first_level.height, texLevels,
|
|
||||||
static_cast<u32>(assets_data.size()), 1, first_level.format, 0,
|
|
||||||
AbstractTextureType::Texture_2DArray);
|
|
||||||
entry = AllocateCacheEntry(config);
|
entry = AllocateCacheEntry(config);
|
||||||
if (!entry) [[unlikely]]
|
if (!entry) [[unlikely]]
|
||||||
return entry;
|
return entry;
|
||||||
for (u32 data_index = 0; data_index < static_cast<u32>(assets_data.size()); data_index++)
|
const auto& slice = custom_texture_data->m_slices[0];
|
||||||
{
|
|
||||||
const auto& asset = assets_data[data_index];
|
|
||||||
const auto& slice = asset->m_texture.m_slices[0];
|
|
||||||
for (u32 level_index = 0;
|
for (u32 level_index = 0;
|
||||||
level_index < std::min(texLevels, static_cast<u32>(slice.m_levels.size()));
|
level_index < std::min(texLevels, static_cast<u32>(slice.m_levels.size())); ++level_index)
|
||||||
++level_index)
|
|
||||||
{
|
{
|
||||||
const auto& level = slice.m_levels[level_index];
|
const auto& level = slice.m_levels[level_index];
|
||||||
entry->texture->Load(level_index, level.width, level.height, level.row_length,
|
entry->texture->Load(level_index, level.width, level.height, level.row_length,
|
||||||
level.data.data(), level.data.size(), data_index);
|
level.data.data(), level.data.size());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->has_arbitrary_mips = custom_arbitrary_mipmaps;
|
entry->has_arbitrary_mips = custom_arbitrary_mipmaps;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "VideoCommon/AbstractTexture.h"
|
#include "VideoCommon/AbstractTexture.h"
|
||||||
#include "VideoCommon/Assets/CustomAsset.h"
|
#include "VideoCommon/Assets/CustomAsset.h"
|
||||||
#include "VideoCommon/BPMemory.h"
|
#include "VideoCommon/BPMemory.h"
|
||||||
|
#include "VideoCommon/HiresTextures.h"
|
||||||
#include "VideoCommon/TextureConfig.h"
|
#include "VideoCommon/TextureConfig.h"
|
||||||
#include "VideoCommon/TextureDecoder.h"
|
#include "VideoCommon/TextureDecoder.h"
|
||||||
#include "VideoCommon/TextureInfo.h"
|
#include "VideoCommon/TextureInfo.h"
|
||||||
@ -167,8 +168,8 @@ struct TCacheEntry
|
|||||||
|
|
||||||
std::string texture_info_name = "";
|
std::string texture_info_name = "";
|
||||||
|
|
||||||
std::vector<VideoCommon::CachedAsset<VideoCommon::GameTextureAsset>> linked_game_texture_assets;
|
VideoCommon::CustomAsset::TimeType last_load_time;
|
||||||
std::vector<VideoCommon::CachedAsset<VideoCommon::CustomAsset>> linked_asset_dependencies;
|
std::shared_ptr<HiresTexture> hires_texture;
|
||||||
|
|
||||||
explicit TCacheEntry(std::unique_ptr<AbstractTexture> tex,
|
explicit TCacheEntry(std::unique_ptr<AbstractTexture> tex,
|
||||||
std::unique_ptr<AbstractFramebuffer> fb);
|
std::unique_ptr<AbstractFramebuffer> fb);
|
||||||
@ -351,10 +352,9 @@ private:
|
|||||||
|
|
||||||
void SetBackupConfig(const VideoConfig& config);
|
void SetBackupConfig(const VideoConfig& config);
|
||||||
|
|
||||||
RcTcacheEntry
|
RcTcacheEntry CreateTextureEntry(const TextureCreationInfo& creation_info,
|
||||||
CreateTextureEntry(const TextureCreationInfo& creation_info, const TextureInfo& texture_info,
|
const TextureInfo& texture_info, int safety_color_sample_size,
|
||||||
int safety_color_sample_size,
|
VideoCommon::CustomTextureData* custom_texture_data,
|
||||||
std::vector<std::shared_ptr<VideoCommon::TextureData>> assets_data,
|
|
||||||
bool custom_arbitrary_mipmaps, bool skip_texture_dump);
|
bool custom_arbitrary_mipmaps, bool skip_texture_dump);
|
||||||
|
|
||||||
RcTcacheEntry GetXFBFromCache(u32 address, u32 width, u32 height, u32 stride);
|
RcTcacheEntry GetXFBFromCache(u32 address, u32 width, u32 height, u32 stride);
|
||||||
|
Reference in New Issue
Block a user