From 75a0a1ed67cd173e378dfbc34b02a52716caa639 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Fri, 31 May 2024 23:29:08 -0500 Subject: [PATCH 1/3] VideoCommon: update texture asset to properly set near sampler state value --- Source/Core/VideoCommon/Assets/TextureAsset.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Core/VideoCommon/Assets/TextureAsset.cpp b/Source/Core/VideoCommon/Assets/TextureAsset.cpp index 484e89c19d..b7781d4667 100644 --- a/Source/Core/VideoCommon/Assets/TextureAsset.cpp +++ b/Source/Core/VideoCommon/Assets/TextureAsset.cpp @@ -78,11 +78,11 @@ bool ParseSampler(const VideoCommon::CustomAssetLibrary::AssetID& asset_id, sampler->tm0.mag_filter = FilterMode::Linear; sampler->tm0.mipmap_filter = FilterMode::Linear; } - else if (sampler_state_filter == "point") + else if (sampler_state_filter == "near") { - sampler->tm0.min_filter = FilterMode::Linear; - sampler->tm0.mag_filter = FilterMode::Linear; - sampler->tm0.mipmap_filter = FilterMode::Linear; + sampler->tm0.min_filter = FilterMode::Near; + sampler->tm0.mag_filter = FilterMode::Near; + sampler->tm0.mipmap_filter = FilterMode::Near; } else { From 1c3402502b5483e86e0253fe044e5a3ed95f801a Mon Sep 17 00:00:00 2001 From: iwubcode Date: Fri, 31 May 2024 23:31:10 -0500 Subject: [PATCH 2/3] VideoCommon: set individual texture asset filter/wrap values when loading from json --- .../Core/VideoCommon/Assets/TextureAsset.cpp | 191 ++++++++++++------ 1 file changed, 124 insertions(+), 67 deletions(-) diff --git a/Source/Core/VideoCommon/Assets/TextureAsset.cpp b/Source/Core/VideoCommon/Assets/TextureAsset.cpp index b7781d4667..425b84207c 100644 --- a/Source/Core/VideoCommon/Assets/TextureAsset.cpp +++ b/Source/Core/VideoCommon/Assets/TextureAsset.cpp @@ -3,6 +3,9 @@ #include "VideoCommon/Assets/TextureAsset.h" +#include + +#include "Common/JsonUtil.h" #include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "VideoCommon/BPMemory.h" @@ -11,6 +14,45 @@ namespace VideoCommon { namespace { +std::optional ReadWrapModeFromJSON(const picojson::object& json, const std::string& uv) +{ + auto uv_mode = ReadStringFromJson(json, uv).value_or(""); + Common::ToLower(&uv_mode); + + if (uv_mode == "clamp") + { + return WrapMode::Clamp; + } + else if (uv_mode == "repeat") + { + return WrapMode::Repeat; + } + else if (uv_mode == "mirror") + { + return WrapMode::Mirror; + } + + return std::nullopt; +} + +std::optional ReadFilterModeFromJSON(const picojson::object& json, + const std::string& filter) +{ + auto filter_mode = ReadStringFromJson(json, filter).value_or(""); + Common::ToLower(&filter_mode); + + if (filter_mode == "linear") + { + return FilterMode::Linear; + } + else if (filter_mode == "near") + { + return FilterMode::Near; + } + + return std::nullopt; +} + bool ParseSampler(const VideoCommon::CustomAssetLibrary::AssetID& asset_id, const picojson::object& json, SamplerState* sampler) { @@ -19,78 +61,93 @@ bool ParseSampler(const VideoCommon::CustomAssetLibrary::AssetID& asset_id, *sampler = RenderState::GetLinearSamplerState(); - const auto sampler_state_mode_iter = json.find("texture_mode"); - if (sampler_state_mode_iter == json.end()) + const auto sampler_state_wrap_iter = json.find("wrap_mode"); + if (sampler_state_wrap_iter != json.end()) { - ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_mode' not found", asset_id); - return false; - } - if (!sampler_state_mode_iter->second.is()) - { - ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_mode' is not the right type", - asset_id); - return false; - } - std::string sampler_state_mode = sampler_state_mode_iter->second.to_str(); - Common::ToLower(&sampler_state_mode); + if (!sampler_state_wrap_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'wrap_mode' is not the right type", + asset_id); + return false; + } + const auto sampler_state_wrap_obj = sampler_state_wrap_iter->second.get(); - if (sampler_state_mode == "clamp") - { - sampler->tm0.wrap_u = WrapMode::Clamp; - sampler->tm0.wrap_v = WrapMode::Clamp; - } - else if (sampler_state_mode == "repeat") - { - sampler->tm0.wrap_u = WrapMode::Repeat; - sampler->tm0.wrap_v = WrapMode::Repeat; - } - else if (sampler_state_mode == "mirrored_repeat") - { - sampler->tm0.wrap_u = WrapMode::Mirror; - sampler->tm0.wrap_v = WrapMode::Mirror; - } - else - { - ERROR_LOG_FMT(VIDEO, - "Asset '{}' failed to parse json, 'texture_mode' has an invalid " - "value '{}'", - asset_id, sampler_state_mode); - return false; + if (const auto mode = ReadWrapModeFromJSON(sampler_state_wrap_obj, "u")) + { + sampler->tm0.wrap_u = *mode; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'wrap_mode[u]' has an invalid " + "value", + asset_id); + return false; + } + + if (const auto mode = ReadWrapModeFromJSON(sampler_state_wrap_obj, "v")) + { + sampler->tm0.wrap_v = *mode; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'wrap_mode[v]' has an invalid " + "value", + asset_id); + return false; + } } - const auto sampler_state_filter_iter = json.find("texture_filter"); - if (sampler_state_filter_iter == json.end()) + const auto sampler_state_filter_iter = json.find("filter_mode"); + if (sampler_state_filter_iter != json.end()) { - ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_filter' not found", asset_id); - return false; - } - if (!sampler_state_filter_iter->second.is()) - { - ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'texture_filter' is not the right type", - asset_id); - return false; - } - std::string sampler_state_filter = sampler_state_filter_iter->second.to_str(); - Common::ToLower(&sampler_state_filter); - if (sampler_state_filter == "linear") - { - sampler->tm0.min_filter = FilterMode::Linear; - sampler->tm0.mag_filter = FilterMode::Linear; - sampler->tm0.mipmap_filter = FilterMode::Linear; - } - else if (sampler_state_filter == "near") - { - sampler->tm0.min_filter = FilterMode::Near; - sampler->tm0.mag_filter = FilterMode::Near; - sampler->tm0.mipmap_filter = FilterMode::Near; - } - else - { - ERROR_LOG_FMT(VIDEO, - "Asset '{}' failed to parse json, 'texture_filter' has an invalid " - "value '{}'", - asset_id, sampler_state_filter); - return false; + if (!sampler_state_filter_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'filter_mode' is not the right type", + asset_id); + return false; + } + const auto sampler_state_filter_obj = sampler_state_filter_iter->second.get(); + + if (const auto mode = ReadFilterModeFromJSON(sampler_state_filter_obj, "min")) + { + sampler->tm0.min_filter = *mode; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'filter_mode[min]' has an invalid " + "value", + asset_id); + return false; + } + + if (const auto mode = ReadFilterModeFromJSON(sampler_state_filter_obj, "mag")) + { + sampler->tm0.mag_filter = *mode; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'filter_mode[mag]' has an invalid " + "value", + asset_id); + return false; + } + + if (const auto mode = ReadFilterModeFromJSON(sampler_state_filter_obj, "mipmap")) + { + sampler->tm0.mipmap_filter = *mode; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'filter_mode[mipmap]' has an invalid " + "value", + asset_id); + return false; + } } return true; From 36ccbbc06edd6130948feef58fb8c1433719711c Mon Sep 17 00:00:00 2001 From: iwubcode Date: Tue, 11 Jun 2024 20:25:40 -0500 Subject: [PATCH 3/3] VideoCommon: add ability to serialize a texture asset metadata to json --- .../Core/VideoCommon/Assets/TextureAsset.cpp | 55 +++++++++++++++++++ Source/Core/VideoCommon/Assets/TextureAsset.h | 1 + 2 files changed, 56 insertions(+) diff --git a/Source/Core/VideoCommon/Assets/TextureAsset.cpp b/Source/Core/VideoCommon/Assets/TextureAsset.cpp index 425b84207c..335ed73b33 100644 --- a/Source/Core/VideoCommon/Assets/TextureAsset.cpp +++ b/Source/Core/VideoCommon/Assets/TextureAsset.cpp @@ -199,6 +199,61 @@ bool TextureData::FromJson(const CustomAssetLibrary::AssetID& asset_id, return true; } +void TextureData::ToJson(picojson::object* obj, const TextureData& data) +{ + if (!obj) [[unlikely]] + return; + + auto& json_obj = *obj; + switch (data.m_type) + { + case TextureData::Type::Type_Texture2D: + json_obj.emplace("type", "texture2d"); + break; + case TextureData::Type::Type_TextureCube: + json_obj.emplace("type", "texturecube"); + break; + case TextureData::Type::Type_Undefined: + break; + }; + + auto wrap_mode_to_string = [](WrapMode mode) { + switch (mode) + { + case WrapMode::Clamp: + return "clamp"; + case WrapMode::Mirror: + return "mirror"; + case WrapMode::Repeat: + return "repeat"; + }; + + return ""; + }; + auto filter_mode_to_string = [](FilterMode mode) { + switch (mode) + { + case FilterMode::Linear: + return "linear"; + case FilterMode::Near: + return "near"; + }; + + return ""; + }; + + picojson::object wrap_mode; + wrap_mode.emplace("u", wrap_mode_to_string(data.m_sampler.tm0.wrap_u)); + wrap_mode.emplace("v", wrap_mode_to_string(data.m_sampler.tm0.wrap_v)); + json_obj.emplace("wrap_mode", wrap_mode); + + picojson::object filter_mode; + filter_mode.emplace("min", filter_mode_to_string(data.m_sampler.tm0.min_filter)); + filter_mode.emplace("mag", filter_mode_to_string(data.m_sampler.tm0.mag_filter)); + filter_mode.emplace("mipmap", filter_mode_to_string(data.m_sampler.tm0.mipmap_filter)); + json_obj.emplace("filter_mode", filter_mode); +} + CustomAssetLibrary::LoadInfo GameTextureAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id) { auto potential_data = std::make_shared(); diff --git a/Source/Core/VideoCommon/Assets/TextureAsset.h b/Source/Core/VideoCommon/Assets/TextureAsset.h index fc9e3166df..e0929a79f0 100644 --- a/Source/Core/VideoCommon/Assets/TextureAsset.h +++ b/Source/Core/VideoCommon/Assets/TextureAsset.h @@ -17,6 +17,7 @@ struct TextureData { static bool FromJson(const CustomAssetLibrary::AssetID& asset_id, const picojson::object& json, TextureData* data); + static void ToJson(picojson::object* obj, const TextureData& data); enum class Type { Type_Undefined,