mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 13:27:45 -07:00
VideoCommon: instead of using 'CustomTextureData' directly, use 'TextureData' for texture assets, this allows us to provide additional metadata for textures. Such as a sampler or type information (to distinguish cube maps)
This commit is contained in:
parent
1b7a590b4b
commit
0e8f8ea930
@ -6,7 +6,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "VideoCommon/Assets/CustomTextureData.h"
|
#include "VideoCommon/Assets/TextureAsset.h"
|
||||||
|
|
||||||
namespace VideoCommon
|
namespace VideoCommon
|
||||||
{
|
{
|
||||||
@ -26,16 +26,26 @@ std::size_t GetAssetSize(const CustomTextureData& data)
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
CustomAssetLibrary::LoadInfo CustomAssetLibrary::LoadGameTexture(const AssetID& asset_id,
|
CustomAssetLibrary::LoadInfo CustomAssetLibrary::LoadGameTexture(const AssetID& asset_id,
|
||||||
CustomTextureData* data)
|
TextureData* data)
|
||||||
{
|
{
|
||||||
const auto load_info = LoadTexture(asset_id, data);
|
const auto load_info = LoadTexture(asset_id, data);
|
||||||
if (load_info.m_bytes_loaded == 0)
|
if (load_info.m_bytes_loaded == 0)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
// Note: 'LoadTexture()' ensures we have a level loaded
|
if (data->m_type != TextureData::Type::Type_Texture2D)
|
||||||
for (std::size_t slice_index = 0; slice_index < data->m_slices.size(); slice_index++)
|
|
||||||
{
|
{
|
||||||
auto& slice = data->m_slices[slice_index];
|
ERROR_LOG_FMT(
|
||||||
|
VIDEO,
|
||||||
|
"Custom asset '{}' is not a valid game texture, it is expected to be a 2d texture "
|
||||||
|
"but was a '{}'.",
|
||||||
|
asset_id, data->m_type);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: 'LoadTexture()' ensures we have a level loaded
|
||||||
|
for (std::size_t slice_index = 0; slice_index < data->m_texture.m_slices.size(); slice_index++)
|
||||||
|
{
|
||||||
|
auto& slice = data->m_texture.m_slices[slice_index];
|
||||||
const auto& first_mip = slice.m_levels[0];
|
const auto& first_mip = slice.m_levels[0];
|
||||||
|
|
||||||
// Verify that each mip level is the correct size (divide by 2 each time).
|
// Verify that each mip level is the correct size (divide by 2 each time).
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
namespace VideoCommon
|
namespace VideoCommon
|
||||||
{
|
{
|
||||||
class CustomTextureData;
|
|
||||||
struct MaterialData;
|
struct MaterialData;
|
||||||
struct PixelShaderData;
|
struct PixelShaderData;
|
||||||
|
struct TextureData;
|
||||||
|
|
||||||
// This class provides functionality to load
|
// This class provides functionality to load
|
||||||
// specific data (like textures). Where this data
|
// specific data (like textures). Where this data
|
||||||
@ -32,14 +32,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Loads a texture, if there are no levels, bytes loaded will be empty
|
// Loads a texture, if there are no levels, bytes loaded will be empty
|
||||||
virtual LoadInfo LoadTexture(const AssetID& asset_id, CustomTextureData* data) = 0;
|
virtual LoadInfo LoadTexture(const AssetID& asset_id, TextureData* data) = 0;
|
||||||
|
|
||||||
// Gets the last write time for a given asset id
|
// Gets the last write time for a given asset id
|
||||||
virtual TimeType GetLastAssetWriteTime(const AssetID& asset_id) const = 0;
|
virtual TimeType GetLastAssetWriteTime(const AssetID& asset_id) const = 0;
|
||||||
|
|
||||||
// Loads a texture as a game texture, providing additional checks like confirming
|
// Loads a texture as a game texture, providing additional checks like confirming
|
||||||
// each mip level size is correct and that the format is consistent across the data
|
// each mip level size is correct and that the format is consistent across the data
|
||||||
LoadInfo LoadGameTexture(const AssetID& asset_id, CustomTextureData* data);
|
LoadInfo LoadGameTexture(const AssetID& asset_id, TextureData* data);
|
||||||
|
|
||||||
// Loads a pixel shader
|
// Loads a pixel shader
|
||||||
virtual LoadInfo LoadPixelShader(const AssetID& asset_id, PixelShaderData* data) = 0;
|
virtual LoadInfo LoadPixelShader(const AssetID& asset_id, PixelShaderData* data) = 0;
|
||||||
|
@ -77,13 +77,6 @@ void CustomAssetLoader ::Shutdown()
|
|||||||
m_total_bytes_loaded = 0;
|
m_total_bytes_loaded = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<RawTextureAsset>
|
|
||||||
CustomAssetLoader::LoadTexture(const CustomAssetLibrary::AssetID& asset_id,
|
|
||||||
std::shared_ptr<CustomAssetLibrary> library)
|
|
||||||
{
|
|
||||||
return LoadOrCreateAsset<RawTextureAsset>(asset_id, m_textures, std::move(library));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<GameTextureAsset>
|
std::shared_ptr<GameTextureAsset>
|
||||||
CustomAssetLoader::LoadGameTexture(const CustomAssetLibrary::AssetID& asset_id,
|
CustomAssetLoader::LoadGameTexture(const CustomAssetLibrary::AssetID& asset_id,
|
||||||
std::shared_ptr<CustomAssetLibrary> library)
|
std::shared_ptr<CustomAssetLibrary> library)
|
||||||
|
@ -38,9 +38,6 @@ public:
|
|||||||
// Loads happen asynchronously where the data will be set now or in the future
|
// Loads happen asynchronously where the data will be set now or in the future
|
||||||
// Callees are expected to query the underlying data with 'GetData()'
|
// Callees are expected to query the underlying data with 'GetData()'
|
||||||
// from the 'CustomLoadableAsset' class to determine if the data is ready for use
|
// from the 'CustomLoadableAsset' class to determine if the data is ready for use
|
||||||
std::shared_ptr<RawTextureAsset> LoadTexture(const CustomAssetLibrary::AssetID& asset_id,
|
|
||||||
std::shared_ptr<CustomAssetLibrary> library);
|
|
||||||
|
|
||||||
std::shared_ptr<GameTextureAsset> LoadGameTexture(const CustomAssetLibrary::AssetID& asset_id,
|
std::shared_ptr<GameTextureAsset> LoadGameTexture(const CustomAssetLibrary::AssetID& asset_id,
|
||||||
std::shared_ptr<CustomAssetLibrary> library);
|
std::shared_ptr<CustomAssetLibrary> library);
|
||||||
|
|
||||||
@ -80,7 +77,6 @@ private:
|
|||||||
|
|
||||||
static constexpr auto TIME_BETWEEN_ASSET_MONITOR_CHECKS = std::chrono::milliseconds{500};
|
static constexpr auto TIME_BETWEEN_ASSET_MONITOR_CHECKS = std::chrono::milliseconds{500};
|
||||||
|
|
||||||
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<RawTextureAsset>> m_textures;
|
|
||||||
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<GameTextureAsset>> m_game_textures;
|
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<GameTextureAsset>> m_game_textures;
|
||||||
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<PixelShaderAsset>> m_pixel_shaders;
|
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<PixelShaderAsset>> m_pixel_shaders;
|
||||||
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<MaterialAsset>> m_materials;
|
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<MaterialAsset>> m_materials;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
#include "VideoCommon/Assets/MaterialAsset.h"
|
#include "VideoCommon/Assets/MaterialAsset.h"
|
||||||
#include "VideoCommon/Assets/ShaderAsset.h"
|
#include "VideoCommon/Assets/ShaderAsset.h"
|
||||||
|
#include "VideoCommon/Assets/TextureAsset.h"
|
||||||
|
|
||||||
namespace VideoCommon
|
namespace VideoCommon
|
||||||
{
|
{
|
||||||
@ -219,66 +220,126 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadMaterial(const As
|
|||||||
}
|
}
|
||||||
|
|
||||||
CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const AssetID& asset_id,
|
CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const AssetID& asset_id,
|
||||||
CustomTextureData* data)
|
TextureData* data)
|
||||||
{
|
{
|
||||||
const auto asset_map = GetAssetMapForID(asset_id);
|
const auto asset_map = GetAssetMapForID(asset_id);
|
||||||
|
|
||||||
// Raw texture is expected to have one asset mapped
|
// Texture can optionally have a metadata file as well
|
||||||
if (asset_map.empty() || asset_map.size() > 1)
|
if (asset_map.empty() || asset_map.size() > 2)
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - raw texture expected to have one file mapped!",
|
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - raw texture expected to have one or two files mapped!",
|
||||||
asset_id);
|
asset_id);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const auto& asset_path = asset_map.begin()->second;
|
|
||||||
|
|
||||||
|
const auto metadata = asset_map.find("metadata");
|
||||||
|
const auto texture_path = asset_map.find("texture");
|
||||||
|
|
||||||
|
if (texture_path == asset_map.end())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(VIDEO, "Asset '{}' expected to have a texture entry mapped!", asset_id);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t metadata_size = 0;
|
||||||
|
if (metadata != asset_map.end())
|
||||||
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
const auto last_loaded_time = std::filesystem::last_write_time(asset_path, ec);
|
metadata_size = std::filesystem::file_size(metadata->second, ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to get last write time with error '{}'!",
|
ERROR_LOG_FMT(VIDEO,
|
||||||
|
"Asset '{}' error - failed to get texture metadata file size with error '{}'!",
|
||||||
asset_id, ec);
|
asset_id, ec);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto ext = PathToString(asset_path.extension());
|
|
||||||
|
std::string json_data;
|
||||||
|
if (!File::ReadFileToString(PathToString(metadata->second), json_data))
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to load the json file '{}',", asset_id,
|
||||||
|
PathToString(metadata->second));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
picojson::value root;
|
||||||
|
const auto error = picojson::parse(root, json_data);
|
||||||
|
|
||||||
|
if (!error.empty())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(VIDEO,
|
||||||
|
"Asset '{}' error - failed to load the json file '{}', due to parse error: {}",
|
||||||
|
asset_id, PathToString(metadata->second), error);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (!root.is<picojson::object>())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(
|
||||||
|
VIDEO,
|
||||||
|
"Asset '{}' error - failed to load the json file '{}', due to root not being an object!",
|
||||||
|
asset_id, PathToString(metadata->second));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& root_obj = root.get<picojson::object>();
|
||||||
|
if (!TextureData::FromJson(asset_id, root_obj, data))
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data->m_type = TextureData::Type::Type_Texture2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ext = PathToString(texture_path->second.extension());
|
||||||
Common::ToLower(&ext);
|
Common::ToLower(&ext);
|
||||||
if (ext == ".dds")
|
if (ext == ".dds")
|
||||||
{
|
{
|
||||||
if (!LoadDDSTexture(data, PathToString(asset_path)))
|
if (!LoadDDSTexture(&data->m_texture, PathToString(texture_path->second)))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - could not load dds texture!", asset_id);
|
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - could not load dds texture!", asset_id);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->m_slices.empty()) [[unlikely]]
|
if (data->m_texture.m_slices.empty()) [[unlikely]]
|
||||||
data->m_slices.push_back({});
|
data->m_texture.m_slices.push_back({});
|
||||||
|
|
||||||
if (!LoadMips(asset_path, &data->m_slices[0]))
|
if (!LoadMips(texture_path->second, &data->m_texture.m_slices[0]))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return LoadInfo{GetAssetSize(*data), FileTimeToSysTime(last_loaded_time)};
|
return LoadInfo{GetAssetSize(data->m_texture) + metadata_size, GetLastAssetWriteTime(asset_id)};
|
||||||
}
|
}
|
||||||
else if (ext == ".png")
|
else if (ext == ".png")
|
||||||
{
|
{
|
||||||
// If we have no slices, create one
|
// PNG could support more complicated texture types in the future
|
||||||
if (data->m_slices.empty())
|
// but for now just error
|
||||||
data->m_slices.push_back({});
|
if (data->m_type != TextureData::Type::Type_Texture2D)
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - PNG is not supported for texture type '{}'!",
|
||||||
|
asset_id, data->m_type);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
auto& slice = data->m_slices[0];
|
// If we have no slices, create one
|
||||||
|
if (data->m_texture.m_slices.empty())
|
||||||
|
data->m_texture.m_slices.push_back({});
|
||||||
|
|
||||||
|
auto& slice = data->m_texture.m_slices[0];
|
||||||
// If we have no levels, create one to pass into LoadPNGTexture
|
// If we have no levels, create one to pass into LoadPNGTexture
|
||||||
if (slice.m_levels.empty())
|
if (slice.m_levels.empty())
|
||||||
slice.m_levels.push_back({});
|
slice.m_levels.push_back({});
|
||||||
|
|
||||||
if (!LoadPNGTexture(&slice.m_levels[0], PathToString(asset_path)))
|
if (!LoadPNGTexture(&slice.m_levels[0], PathToString(texture_path->second)))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - could not load png texture!", asset_id);
|
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - could not load png texture!", asset_id);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LoadMips(asset_path, &slice))
|
if (!LoadMips(texture_path->second, &slice))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return LoadInfo{GetAssetSize(*data), FileTimeToSysTime(last_loaded_time)};
|
return LoadInfo{GetAssetSize(data->m_texture) + metadata_size, GetLastAssetWriteTime(asset_id)};
|
||||||
}
|
}
|
||||||
|
|
||||||
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - extension '{}' unknown!", asset_id, ext);
|
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - extension '{}' unknown!", asset_id, ext);
|
||||||
|
@ -20,7 +20,7 @@ class DirectFilesystemAssetLibrary final : public CustomAssetLibrary
|
|||||||
public:
|
public:
|
||||||
using AssetMap = std::map<std::string, std::filesystem::path>;
|
using AssetMap = std::map<std::string, std::filesystem::path>;
|
||||||
|
|
||||||
LoadInfo LoadTexture(const AssetID& asset_id, CustomTextureData* data) override;
|
LoadInfo LoadTexture(const AssetID& asset_id, TextureData* data) override;
|
||||||
LoadInfo LoadPixelShader(const AssetID& asset_id, PixelShaderData* data) override;
|
LoadInfo LoadPixelShader(const AssetID& asset_id, PixelShaderData* data) override;
|
||||||
LoadInfo LoadMaterial(const AssetID& asset_id, MaterialData* data) override;
|
LoadInfo LoadMaterial(const AssetID& asset_id, MaterialData* data) override;
|
||||||
|
|
||||||
|
@ -97,20 +97,6 @@ bool ParseSampler(const VideoCommon::CustomAssetLibrary::AssetID& asset_id,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
CustomAssetLibrary::LoadInfo RawTextureAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id)
|
|
||||||
{
|
|
||||||
auto potential_data = std::make_shared<CustomTextureData>();
|
|
||||||
const auto loaded_info = m_owning_library->LoadTexture(asset_id, potential_data.get());
|
|
||||||
if (loaded_info.m_bytes_loaded == 0)
|
|
||||||
return {};
|
|
||||||
{
|
|
||||||
std::lock_guard lk(m_data_lock);
|
|
||||||
m_loaded = true;
|
|
||||||
m_data = std::move(potential_data);
|
|
||||||
}
|
|
||||||
return loaded_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TextureData::FromJson(const CustomAssetLibrary::AssetID& asset_id,
|
bool TextureData::FromJson(const CustomAssetLibrary::AssetID& asset_id,
|
||||||
const picojson::object& json, TextureData* data)
|
const picojson::object& json, TextureData* data)
|
||||||
{
|
{
|
||||||
@ -160,7 +146,7 @@ bool TextureData::FromJson(const CustomAssetLibrary::AssetID& asset_id,
|
|||||||
|
|
||||||
CustomAssetLibrary::LoadInfo GameTextureAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id)
|
CustomAssetLibrary::LoadInfo GameTextureAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id)
|
||||||
{
|
{
|
||||||
auto potential_data = std::make_shared<CustomTextureData>();
|
auto potential_data = std::make_shared<TextureData>();
|
||||||
const auto loaded_info = m_owning_library->LoadGameTexture(asset_id, potential_data.get());
|
const auto loaded_info = m_owning_library->LoadGameTexture(asset_id, potential_data.get());
|
||||||
if (loaded_info.m_bytes_loaded == 0)
|
if (loaded_info.m_bytes_loaded == 0)
|
||||||
return {};
|
return {};
|
||||||
@ -184,7 +170,7 @@ bool GameTextureAsset::Validate(u32 native_width, u32 native_height) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_data->m_slices.empty())
|
if (m_data->m_texture.m_slices.empty())
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(VIDEO,
|
ERROR_LOG_FMT(VIDEO,
|
||||||
"Game texture can't be validated for asset '{}' because no data was available.",
|
"Game texture can't be validated for asset '{}' because no data was available.",
|
||||||
@ -192,7 +178,7 @@ bool GameTextureAsset::Validate(u32 native_width, u32 native_height) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_data->m_slices.size() > 1)
|
if (m_data->m_texture.m_slices.size() > 1)
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(
|
ERROR_LOG_FMT(
|
||||||
VIDEO,
|
VIDEO,
|
||||||
@ -201,7 +187,7 @@ bool GameTextureAsset::Validate(u32 native_width, u32 native_height) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& slice = m_data->m_slices[0];
|
const auto& slice = m_data->m_texture.m_slices[0];
|
||||||
if (slice.m_levels.empty())
|
if (slice.m_levels.empty())
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(
|
ERROR_LOG_FMT(
|
||||||
|
@ -3,23 +3,16 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
#include <picojson.h>
|
#include <picojson.h>
|
||||||
|
|
||||||
|
#include "Common/EnumFormatter.h"
|
||||||
#include "VideoCommon/Assets/CustomAsset.h"
|
#include "VideoCommon/Assets/CustomAsset.h"
|
||||||
#include "VideoCommon/Assets/CustomTextureData.h"
|
#include "VideoCommon/Assets/CustomTextureData.h"
|
||||||
#include "VideoCommon/RenderState.h"
|
#include "VideoCommon/RenderState.h"
|
||||||
|
|
||||||
namespace VideoCommon
|
namespace VideoCommon
|
||||||
{
|
{
|
||||||
class RawTextureAsset final : public CustomLoadableAsset<CustomTextureData>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using CustomLoadableAsset::CustomLoadableAsset;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TextureData
|
struct TextureData
|
||||||
{
|
{
|
||||||
static bool FromJson(const CustomAssetLibrary::AssetID& asset_id, const picojson::object& json,
|
static bool FromJson(const CustomAssetLibrary::AssetID& asset_id, const picojson::object& json,
|
||||||
@ -32,11 +25,11 @@ struct TextureData
|
|||||||
Type_Max = Type_TextureCube
|
Type_Max = Type_TextureCube
|
||||||
};
|
};
|
||||||
Type m_type;
|
Type m_type;
|
||||||
CustomTextureData m_data;
|
CustomTextureData m_texture;
|
||||||
SamplerState m_sampler;
|
SamplerState m_sampler;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameTextureAsset final : public CustomLoadableAsset<CustomTextureData>
|
class GameTextureAsset final : public CustomLoadableAsset<TextureData>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using CustomLoadableAsset::CustomLoadableAsset;
|
using CustomLoadableAsset::CustomLoadableAsset;
|
||||||
@ -49,3 +42,10 @@ private:
|
|||||||
CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override;
|
CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override;
|
||||||
};
|
};
|
||||||
} // namespace VideoCommon
|
} // namespace VideoCommon
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct fmt::formatter<VideoCommon::TextureData::Type>
|
||||||
|
: EnumFormatter<VideoCommon::TextureData::Type::Type_Max>
|
||||||
|
{
|
||||||
|
constexpr formatter() : EnumFormatter({"Undefined", "Texture2D", "TextureCube"}) {}
|
||||||
|
};
|
||||||
|
@ -423,7 +423,7 @@ void CustomPipelineAction::OnTextureCreate(GraphicsModActionData::TextureCreate*
|
|||||||
auto data = game_texture.m_asset->GetData();
|
auto data = game_texture.m_asset->GetData();
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
if (data->m_slices.empty() || data->m_slices[0].m_levels.empty())
|
if (data->m_texture.m_slices.empty() || data->m_texture.m_slices[0].m_levels.empty())
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(
|
ERROR_LOG_FMT(
|
||||||
VIDEO,
|
VIDEO,
|
||||||
@ -431,15 +431,16 @@ void CustomPipelineAction::OnTextureCreate(GraphicsModActionData::TextureCreate*
|
|||||||
create->texture_name, game_texture.m_asset->GetAssetId());
|
create->texture_name, game_texture.m_asset->GetAssetId());
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
}
|
}
|
||||||
else if (create->texture_width != data->m_slices[0].m_levels[0].width ||
|
else if (create->texture_width != data->m_texture.m_slices[0].m_levels[0].width ||
|
||||||
create->texture_height != data->m_slices[0].m_levels[0].height)
|
create->texture_height != data->m_texture.m_slices[0].m_levels[0].height)
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(VIDEO,
|
ERROR_LOG_FMT(VIDEO,
|
||||||
"Custom pipeline for texture '{}' has asset '{}' that does not match "
|
"Custom pipeline for texture '{}' has asset '{}' that does not match "
|
||||||
"the width/height of the texture loaded. Texture {}x{} vs asset {}x{}",
|
"the width/height of the texture loaded. Texture {}x{} vs asset {}x{}",
|
||||||
create->texture_name, game_texture.m_asset->GetAssetId(),
|
create->texture_name, game_texture.m_asset->GetAssetId(),
|
||||||
create->texture_width, create->texture_height,
|
create->texture_width, create->texture_height,
|
||||||
data->m_slices[0].m_levels[0].width, data->m_slices[0].m_levels[0].height);
|
data->m_texture.m_slices[0].m_levels[0].width,
|
||||||
|
data->m_texture.m_slices[0].m_levels[0].height);
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,8 +130,8 @@ void HiresTexture::Update()
|
|||||||
{
|
{
|
||||||
// Since this is just a texture (single file) the mapper doesn't really matter
|
// Since this is just a texture (single file) the mapper doesn't really matter
|
||||||
// just provide a string
|
// just provide a string
|
||||||
s_file_library->SetAssetIDMapData(
|
s_file_library->SetAssetIDMapData(filename, std::map<std::string, std::filesystem::path>{
|
||||||
filename, std::map<std::string, std::filesystem::path>{{"", StringToPath(path)}});
|
{"texture", StringToPath(path)}});
|
||||||
|
|
||||||
if (g_ActiveConfig.bCacheHiresTextures)
|
if (g_ActiveConfig.bCacheHiresTextures)
|
||||||
{
|
{
|
||||||
|
@ -1606,7 +1606,7 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VideoCommon::CachedAsset<VideoCommon::GameTextureAsset>> cached_game_assets;
|
std::vector<VideoCommon::CachedAsset<VideoCommon::GameTextureAsset>> cached_game_assets;
|
||||||
std::vector<std::shared_ptr<VideoCommon::CustomTextureData>> data_for_assets;
|
std::vector<VideoCommon::CustomTextureData*> 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<HiresTexture> hires_texture;
|
||||||
@ -1640,12 +1640,12 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp
|
|||||||
auto data = asset->GetData();
|
auto data = asset->GetData();
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
if (!data->m_slices.empty())
|
if (!data->m_texture.m_slices.empty())
|
||||||
{
|
{
|
||||||
if (!data->m_slices[0].m_levels.empty())
|
if (!data->m_texture.m_slices[0].m_levels.empty())
|
||||||
{
|
{
|
||||||
height = data->m_slices[0].m_levels[0].height;
|
height = data->m_texture.m_slices[0].m_levels[0].height;
|
||||||
width = data->m_slices[0].m_levels[0].width;
|
width = data->m_texture.m_slices[0].m_levels[0].width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1667,7 +1667,7 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp
|
|||||||
{
|
{
|
||||||
if (cached_asset.m_asset->Validate(texture_info.GetRawWidth(), texture_info.GetRawHeight()))
|
if (cached_asset.m_asset->Validate(texture_info.GetRawWidth(), texture_info.GetRawHeight()))
|
||||||
{
|
{
|
||||||
data_for_assets.push_back(std::move(data));
|
data_for_assets.push_back(&data->m_texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1687,8 +1687,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, std::vector<VideoCommon::CustomTextureData*> assets_data,
|
||||||
std::vector<std::shared_ptr<VideoCommon::CustomTextureData>> assets_data,
|
|
||||||
const bool custom_arbitrary_mipmaps, bool skip_texture_dump)
|
const bool custom_arbitrary_mipmaps, bool skip_texture_dump)
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@ -1705,7 +1704,7 @@ RcTcacheEntry TextureCacheBase::CreateTextureEntry(
|
|||||||
assets_data.begin(), assets_data.end(), [](const auto& lhs, const auto& rhs) {
|
assets_data.begin(), assets_data.end(), [](const auto& lhs, const auto& rhs) {
|
||||||
return lhs->m_slices[0].m_levels.size() < rhs->m_slices[0].m_levels.size();
|
return lhs->m_slices[0].m_levels.size() < rhs->m_slices[0].m_levels.size();
|
||||||
});
|
});
|
||||||
return max_element->get()->m_slices[0].m_levels.size();
|
return (*max_element)->m_slices[0].m_levels.size();
|
||||||
};
|
};
|
||||||
const u32 texLevels = no_mips ? 1 : (u32)calculate_max_levels();
|
const u32 texLevels = no_mips ? 1 : (u32)calculate_max_levels();
|
||||||
const auto& first_level = assets_data[0]->m_slices[0].m_levels[0];
|
const auto& first_level = assets_data[0]->m_slices[0].m_levels[0];
|
||||||
|
@ -346,10 +346,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,
|
std::vector<VideoCommon::CustomTextureData*> assets_data,
|
||||||
std::vector<std::shared_ptr<VideoCommon::CustomTextureData>> 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);
|
||||||
|
@ -44,7 +44,7 @@ A full example is given below:
|
|||||||
"name": "normal_texture",
|
"name": "normal_texture",
|
||||||
"data":
|
"data":
|
||||||
{
|
{
|
||||||
"": "normal_texture.png"
|
"texture": "normal_texture.png"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user