2026-08-12 16:08:50 -04:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
2025-09-21 21:58:59 +02:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
2022-04-23 04:59:50 -04:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2020-04-07 20:38:14 -03:00
|
|
|
|
|
|
|
|
#include <array>
|
2026-08-12 16:08:50 -04:00
|
|
|
#include <cmath>
|
2020-04-07 20:38:14 -03:00
|
|
|
|
2020-12-30 02:25:23 -03:00
|
|
|
#include "common/cityhash.h"
|
2021-11-16 23:07:17 +01:00
|
|
|
#include "common/settings.h"
|
2020-04-07 20:38:14 -03:00
|
|
|
#include "video_core/textures/texture.h"
|
|
|
|
|
|
2020-12-30 02:25:23 -03:00
|
|
|
using Tegra::Texture::TICEntry;
|
|
|
|
|
using Tegra::Texture::TSCEntry;
|
|
|
|
|
|
2020-04-07 20:38:14 -03:00
|
|
|
namespace Tegra::Texture {
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
2026-08-12 16:08:50 -04:00
|
|
|
float SrgbToLinear(u32 value) {
|
|
|
|
|
const float encoded = static_cast<float>(value) / 255.0f;
|
|
|
|
|
if (encoded <= 0.04045f) {
|
|
|
|
|
return encoded / 12.92f;
|
|
|
|
|
}
|
|
|
|
|
return std::pow((encoded + 0.055f) / 1.055f, 2.4f);
|
|
|
|
|
}
|
2020-04-07 20:38:14 -03:00
|
|
|
|
|
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
2020-12-30 02:25:23 -03:00
|
|
|
std::array<float, 4> TSCEntry::BorderColor() const noexcept {
|
2026-08-16 18:57:37 -04:00
|
|
|
return border_color;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::array<float, 4> TSCEntry::SrgbBorderColor() const noexcept {
|
2026-08-12 16:08:50 -04:00
|
|
|
return {SrgbToLinear(srgb_border_color_r), SrgbToLinear(srgb_border_color_g),
|
|
|
|
|
SrgbToLinear(srgb_border_color_b), border_color[3]};
|
2020-04-07 20:38:14 -03:00
|
|
|
}
|
|
|
|
|
|
2020-12-30 02:25:23 -03:00
|
|
|
float TSCEntry::MaxAnisotropy() const noexcept {
|
2023-06-17 11:19:39 +02:00
|
|
|
const bool is_suitable_mipmap_filter = mipmap_filter != TextureMipmapFilter::None;
|
2023-06-14 13:27:27 +02:00
|
|
|
const bool has_regular_lods = min_lod_clamp == 0 && max_lod_clamp >= 256;
|
2023-06-15 18:19:32 +02:00
|
|
|
const bool is_bilinear_filter = min_filter == TextureFilter::Linear &&
|
|
|
|
|
reduction_filter == SamplerReduction::WeightedAverage;
|
2025-11-26 02:16:37 +01:00
|
|
|
if (max_anisotropy == 0 && (!is_suitable_mipmap_filter || !has_regular_lods || !is_bilinear_filter || depth_compare_enabled))
|
2021-11-16 23:07:17 +01:00
|
|
|
return 1.0f;
|
2025-11-26 02:16:37 +01:00
|
|
|
|
2022-12-10 20:54:45 -05:00
|
|
|
s32 added_anisotropic{};
|
2025-11-26 02:16:37 +01:00
|
|
|
auto const anisotropic_settings = Settings::values.max_anisotropy.GetValue();
|
|
|
|
|
switch (anisotropic_settings) {
|
|
|
|
|
case Settings::AnisotropyMode::Default:
|
|
|
|
|
case Settings::AnisotropyMode::X2:
|
|
|
|
|
case Settings::AnisotropyMode::X4:
|
|
|
|
|
case Settings::AnisotropyMode::X8:
|
|
|
|
|
case Settings::AnisotropyMode::X16:
|
2026-08-12 15:11:41 -04:00
|
|
|
added_anisotropic = s32(anisotropic_settings) - 1;
|
2025-11-26 02:16:37 +01:00
|
|
|
break;
|
2026-08-12 15:11:41 -04:00
|
|
|
case Settings::AnisotropyMode::Automatic: {
|
|
|
|
|
const u32 resolution_scale = Settings::values.resolution_info.up_scale >>
|
|
|
|
|
Settings::values.resolution_info.down_shift;
|
|
|
|
|
if (resolution_scale > 1U) {
|
|
|
|
|
added_anisotropic = static_cast<s32>(resolution_scale - 1U);
|
|
|
|
|
}
|
2025-11-26 02:16:37 +01:00
|
|
|
break;
|
2026-08-12 15:11:41 -04:00
|
|
|
}
|
2021-11-16 23:07:17 +01:00
|
|
|
}
|
2025-11-26 02:16:37 +01:00
|
|
|
return float(1U << (max_anisotropy + added_anisotropic));
|
2020-04-07 20:47:31 -03:00
|
|
|
}
|
|
|
|
|
|
2020-04-07 20:38:14 -03:00
|
|
|
} // namespace Tegra::Texture
|
2020-12-30 02:25:23 -03:00
|
|
|
|
|
|
|
|
size_t std::hash<TICEntry>::operator()(const TICEntry& tic) const noexcept {
|
|
|
|
|
return Common::CityHash64(reinterpret_cast<const char*>(&tic), sizeof tic);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t std::hash<TSCEntry>::operator()(const TSCEntry& tsc) const noexcept {
|
|
|
|
|
return Common::CityHash64(reinterpret_cast<const char*>(&tsc), sizeof tsc);
|
|
|
|
|
}
|