VideoCommon: add TextureAndSamplerAsset, this asset contains both the raw texture data and data about how the texture should be sampled

This commit is contained in:
iwubcode 2025-08-20 19:17:37 -05:00
parent 90a137ffdc
commit 4489ea0ec2
5 changed files with 55 additions and 39 deletions

View File

@ -298,8 +298,8 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const Ass
return {}; return {};
} }
if (!LoadTextureDataFromFile(asset_id, texture_path->second, if (!LoadTextureDataFromFile(asset_id, texture_path->second, AbstractTextureType::Texture_2D,
TextureAndSamplerData::Type::Type_Texture2D, data)) data))
{ {
return {}; return {};
} }
@ -370,16 +370,16 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const Ass
} }
else else
{ {
data->m_sampler = RenderState::GetLinearSamplerState(); data->sampler = RenderState::GetLinearSamplerState();
data->m_type = TextureAndSamplerData::Type::Type_Texture2D; data->type = AbstractTextureType::Texture_2D;
} }
if (!LoadTextureDataFromFile(asset_id, texture_path->second, data->m_type, &data->m_texture)) if (!LoadTextureDataFromFile(asset_id, texture_path->second, data->type, &data->texture_data))
return {}; return {};
if (!PurgeInvalidMipsFromTextureData(asset_id, &data->m_texture)) if (!PurgeInvalidMipsFromTextureData(asset_id, &data->texture_data))
return {}; return {};
return LoadInfo{GetAssetSize(data->m_texture) + metadata_size}; return LoadInfo{GetAssetSize(data->texture_data) + metadata_size};
} }
void DirectFilesystemAssetLibrary::SetAssetIDMapData(const AssetID& asset_id, void DirectFilesystemAssetLibrary::SetAssetIDMapData(const AssetID& asset_id,

View File

@ -176,16 +176,20 @@ bool TextureAndSamplerData::FromJson(const CustomAssetLibrary::AssetID& asset_id
if (type == "texture2d") if (type == "texture2d")
{ {
data->m_type = TextureAndSamplerData::Type::Type_Texture2D; data->type = AbstractTextureType::Texture_2D;
if (!ParseSampler(asset_id, json, &data->m_sampler)) if (!ParseSampler(asset_id, json, &data->sampler))
{ {
return false; return false;
} }
} }
else if (type == "texturecube") else if (type == "texturecube")
{ {
data->m_type = TextureAndSamplerData::Type::Type_TextureCube; data->type = AbstractTextureType::Texture_CubeMap;
}
else if (type == "texture2darray")
{
data->type = AbstractTextureType::Texture_2DArray;
} }
else else
{ {
@ -205,15 +209,16 @@ void TextureAndSamplerData::ToJson(picojson::object* obj, const TextureAndSample
return; return;
auto& json_obj = *obj; auto& json_obj = *obj;
switch (data.m_type) switch (data.type)
{ {
case TextureAndSamplerData::Type::Type_Texture2D: case AbstractTextureType::Texture_2D:
json_obj.emplace("type", "texture2d"); json_obj.emplace("type", "texture2d");
break; break;
case TextureAndSamplerData::Type::Type_TextureCube: case AbstractTextureType::Texture_CubeMap:
json_obj.emplace("type", "texturecube"); json_obj.emplace("type", "texturecube");
break; break;
case TextureAndSamplerData::Type::Type_Undefined: case AbstractTextureType::Texture_2DArray:
json_obj.emplace("type", "texture2darray");
break; break;
}; };
@ -243,14 +248,14 @@ void TextureAndSamplerData::ToJson(picojson::object* obj, const TextureAndSample
}; };
picojson::object wrap_mode; picojson::object wrap_mode;
wrap_mode.emplace("u", wrap_mode_to_string(data.m_sampler.tm0.wrap_u)); wrap_mode.emplace("u", wrap_mode_to_string(data.sampler.tm0.wrap_u));
wrap_mode.emplace("v", wrap_mode_to_string(data.m_sampler.tm0.wrap_v)); wrap_mode.emplace("v", wrap_mode_to_string(data.sampler.tm0.wrap_v));
json_obj.emplace("wrap_mode", wrap_mode); json_obj.emplace("wrap_mode", wrap_mode);
picojson::object filter_mode; picojson::object filter_mode;
filter_mode.emplace("min", filter_mode_to_string(data.m_sampler.tm0.min_filter)); filter_mode.emplace("min", filter_mode_to_string(data.sampler.tm0.min_filter));
filter_mode.emplace("mag", filter_mode_to_string(data.m_sampler.tm0.mag_filter)); filter_mode.emplace("mag", filter_mode_to_string(data.sampler.tm0.mag_filter));
filter_mode.emplace("mipmap", filter_mode_to_string(data.m_sampler.tm0.mipmap_filter)); filter_mode.emplace("mipmap", filter_mode_to_string(data.sampler.tm0.mipmap_filter));
json_obj.emplace("filter_mode", filter_mode); json_obj.emplace("filter_mode", filter_mode);
} }
@ -267,4 +272,19 @@ CustomAssetLibrary::LoadInfo TextureAsset::LoadImpl(const CustomAssetLibrary::As
} }
return loaded_info; return loaded_info;
} }
CustomAssetLibrary::LoadInfo
TextureAndSamplerAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id)
{
auto potential_data = std::make_shared<TextureAndSamplerData>();
const auto loaded_info = m_owning_library->LoadTexture(asset_id, potential_data.get());
if (loaded_info.bytes_loaded == 0)
return {};
{
std::lock_guard lk(m_data_lock);
m_loaded = true;
m_data = std::move(potential_data);
}
return loaded_info;
}
} // namespace VideoCommon } // namespace VideoCommon

View File

@ -18,16 +18,9 @@ struct TextureAndSamplerData
static bool FromJson(const CustomAssetLibrary::AssetID& asset_id, const picojson::object& json, static bool FromJson(const CustomAssetLibrary::AssetID& asset_id, const picojson::object& json,
TextureAndSamplerData* data); TextureAndSamplerData* data);
static void ToJson(picojson::object* obj, const TextureAndSamplerData& data); static void ToJson(picojson::object* obj, const TextureAndSamplerData& data);
enum class Type AbstractTextureType type;
{ CustomTextureData texture_data;
Type_Undefined, SamplerState sampler;
Type_Texture2D,
Type_TextureCube,
Type_Max = Type_TextureCube
};
Type m_type;
CustomTextureData m_texture;
SamplerState m_sampler;
}; };
class TextureAsset final : public CustomLoadableAsset<CustomTextureData> class TextureAsset final : public CustomLoadableAsset<CustomTextureData>
@ -38,11 +31,13 @@ public:
private: private:
CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override; CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override;
}; };
} // namespace VideoCommon
template <> class TextureAndSamplerAsset final : public CustomLoadableAsset<TextureAndSamplerData>
struct fmt::formatter<VideoCommon::TextureAndSamplerData::Type>
: EnumFormatter<VideoCommon::TextureAndSamplerData::Type::Type_Max>
{ {
constexpr formatter() : EnumFormatter({"Undefined", "Texture2D", "TextureCube"}) {} public:
using CustomLoadableAsset::CustomLoadableAsset;
private:
CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override;
}; };
} // namespace VideoCommon

View File

@ -66,8 +66,8 @@ bool LoadMips(const std::filesystem::path& asset_path, CustomTextureData::ArrayS
} }
} // namespace } // namespace
bool LoadTextureDataFromFile(const CustomAssetLibrary::AssetID& asset_id, bool LoadTextureDataFromFile(const CustomAssetLibrary::AssetID& asset_id,
const std::filesystem::path& asset_path, const std::filesystem::path& asset_path, AbstractTextureType type,
TextureAndSamplerData::Type type, CustomTextureData* data) CustomTextureData* data)
{ {
auto ext = PathToString(asset_path.extension()); auto ext = PathToString(asset_path.extension());
Common::ToLower(&ext); Common::ToLower(&ext);
@ -92,7 +92,7 @@ bool LoadTextureDataFromFile(const CustomAssetLibrary::AssetID& asset_id,
{ {
// PNG could support more complicated texture types in the future // PNG could support more complicated texture types in the future
// but for now just error // but for now just error
if (type != TextureAndSamplerData::Type::Type_Texture2D) if (type != AbstractTextureType::Texture_2D)
{ {
ERROR_LOG_FMT(VIDEO, "Asset '{}' error - PNG is not supported for texture type '{}'!", ERROR_LOG_FMT(VIDEO, "Asset '{}' error - PNG is not supported for texture type '{}'!",
asset_id, type); asset_id, type);

View File

@ -7,12 +7,13 @@
#include "VideoCommon/Assets/CustomAssetLibrary.h" #include "VideoCommon/Assets/CustomAssetLibrary.h"
#include "VideoCommon/Assets/TextureAsset.h" #include "VideoCommon/Assets/TextureAsset.h"
#include "VideoCommon/TextureConfig.h"
namespace VideoCommon namespace VideoCommon
{ {
bool LoadTextureDataFromFile(const CustomAssetLibrary::AssetID& asset_id, bool LoadTextureDataFromFile(const CustomAssetLibrary::AssetID& asset_id,
const std::filesystem::path& asset_path, const std::filesystem::path& asset_path, AbstractTextureType type,
TextureAndSamplerData::Type type, CustomTextureData* data); CustomTextureData* data);
bool ValidateTextureData(const CustomAssetLibrary::AssetID& asset_id, const CustomTextureData& data, bool ValidateTextureData(const CustomAssetLibrary::AssetID& asset_id, const CustomTextureData& data,
u32 native_width, u32 native_height); u32 native_width, u32 native_height);