mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-11-13 12:12:08 +01:00
[TEST] Return Xenoblade workaround + extend srgb handling on border colors
This commit is contained in:
parent
8e687924b8
commit
3379556d89
5 changed files with 53 additions and 6 deletions
|
|
@ -383,6 +383,10 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
|
||||||
!image_view.SupportsDepthComparison()) {
|
!image_view.SupportsDepthComparison()) {
|
||||||
vk_sampler = sampler.HandleWithoutDepthComparison();
|
vk_sampler = sampler.HandleWithoutDepthComparison();
|
||||||
}
|
}
|
||||||
|
if (sampler.HasSrgbBorderColor() &&
|
||||||
|
VideoCore::Surface::IsPixelFormatSRGB(image_view.format)) {
|
||||||
|
vk_sampler = sampler.HandleWithSrgbBorderColor();
|
||||||
|
}
|
||||||
if (sampler.HasMinmaxReduction() && !image_view.SupportsMinmaxFilter()) {
|
if (sampler.HasMinmaxReduction() && !image_view.SupportsMinmaxFilter()) {
|
||||||
vk_sampler = sampler.HandleWithDefaultReduction();
|
vk_sampler = sampler.HandleWithDefaultReduction();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2607,6 +2607,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||||
const auto& device = runtime.device;
|
const auto& device = runtime.device;
|
||||||
const bool has_custom_border_colors = runtime.device.IsCustomBorderColorUsable();
|
const bool has_custom_border_colors = runtime.device.IsCustomBorderColorUsable();
|
||||||
const auto color = tsc.BorderColor();
|
const auto color = tsc.BorderColor();
|
||||||
|
const auto srgb_color = tsc.SrgbBorderColor();
|
||||||
|
|
||||||
const VkSamplerCustomBorderColorCreateInfoEXT border_ci{
|
const VkSamplerCustomBorderColorCreateInfoEXT border_ci{
|
||||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT,
|
||||||
|
|
@ -2614,9 +2615,17 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||||
.customBorderColor = std::bit_cast<VkClearColorValue>(color),
|
.customBorderColor = std::bit_cast<VkClearColorValue>(color),
|
||||||
.format = VK_FORMAT_UNDEFINED,
|
.format = VK_FORMAT_UNDEFINED,
|
||||||
};
|
};
|
||||||
|
const VkSamplerCustomBorderColorCreateInfoEXT srgb_border_ci{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.customBorderColor = std::bit_cast<VkClearColorValue>(srgb_color),
|
||||||
|
.format = VK_FORMAT_UNDEFINED,
|
||||||
|
};
|
||||||
const void* pnext = nullptr;
|
const void* pnext = nullptr;
|
||||||
|
const void* srgb_pnext = nullptr;
|
||||||
if (has_custom_border_colors) {
|
if (has_custom_border_colors) {
|
||||||
pnext = &border_ci;
|
pnext = &border_ci;
|
||||||
|
srgb_pnext = &srgb_border_ci;
|
||||||
if (GPU::Logging::IsActive()) {
|
if (GPU::Logging::IsActive()) {
|
||||||
GPU::Logging::GPULogger::GetInstance().LogExtensionUsage(
|
GPU::Logging::GPULogger::GetInstance().LogExtensionUsage(
|
||||||
"VK_EXT_custom_border_color", "Sampler::Sampler");
|
"VK_EXT_custom_border_color", "Sampler::Sampler");
|
||||||
|
|
@ -2631,6 +2640,11 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||||
.pNext = pnext,
|
.pNext = pnext,
|
||||||
.reductionMode = MaxwellToVK::SamplerReduction(tsc.reduction_filter),
|
.reductionMode = MaxwellToVK::SamplerReduction(tsc.reduction_filter),
|
||||||
};
|
};
|
||||||
|
const VkSamplerReductionModeCreateInfoEXT reduction_ci_srgb{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT,
|
||||||
|
.pNext = srgb_pnext,
|
||||||
|
.reductionMode = MaxwellToVK::SamplerReduction(tsc.reduction_filter),
|
||||||
|
};
|
||||||
const VkSamplerReductionModeCreateInfoEXT reduction_ci_without_border{
|
const VkSamplerReductionModeCreateInfoEXT reduction_ci_without_border{
|
||||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
|
|
@ -2642,6 +2656,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||||
reduction_ci.reductionMode != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT;
|
reduction_ci.reductionMode != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT;
|
||||||
if (runtime.device.IsExtSamplerFilterMinmaxSupported()) {
|
if (runtime.device.IsExtSamplerFilterMinmaxSupported()) {
|
||||||
pnext = &reduction_ci;
|
pnext = &reduction_ci;
|
||||||
|
srgb_pnext = &reduction_ci_srgb;
|
||||||
pnext_without_border = &reduction_ci_without_border;
|
pnext_without_border = &reduction_ci_without_border;
|
||||||
} else if (reduction_ci.reductionMode != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT) {
|
} else if (reduction_ci.reductionMode != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT) {
|
||||||
LOG_WARNING(Render_Vulkan, "VK_EXT_sampler_filter_minmax is required");
|
LOG_WARNING(Render_Vulkan, "VK_EXT_sampler_filter_minmax is required");
|
||||||
|
|
@ -2659,16 +2674,29 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||||
const auto create_sampler = [&](const f32 anisotropy, bool force_nearest,
|
const auto create_sampler = [&](const f32 anisotropy, bool force_nearest,
|
||||||
bool disable_compare = false,
|
bool disable_compare = false,
|
||||||
bool disable_custom_border = false,
|
bool disable_custom_border = false,
|
||||||
bool disable_minmax = false) {
|
bool disable_minmax = false, bool use_srgb_border = false) {
|
||||||
const bool custom_border = has_custom_border_colors && !disable_custom_border;
|
const bool custom_border = has_custom_border_colors && !disable_custom_border;
|
||||||
const bool minmax = has_minmax_reduction && !disable_minmax;
|
const bool minmax = has_minmax_reduction && !disable_minmax;
|
||||||
const void* chain = nullptr;
|
const void* chain = nullptr;
|
||||||
if (custom_border && minmax) {
|
if (custom_border && minmax) {
|
||||||
chain = pnext;
|
chain = pnext;
|
||||||
|
if (use_srgb_border) {
|
||||||
|
chain = srgb_pnext;
|
||||||
|
}
|
||||||
} else if (minmax) {
|
} else if (minmax) {
|
||||||
chain = pnext_without_border;
|
chain = pnext_without_border;
|
||||||
} else if (custom_border) {
|
} else if (custom_border) {
|
||||||
chain = &border_ci;
|
chain = &border_ci;
|
||||||
|
if (use_srgb_border) {
|
||||||
|
chain = &srgb_border_ci;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VkBorderColor fixed_border = VK_BORDER_COLOR_FLOAT_CUSTOM_EXT;
|
||||||
|
if (!custom_border) {
|
||||||
|
fixed_border = ConvertBorderColor(color);
|
||||||
|
if (use_srgb_border) {
|
||||||
|
fixed_border = ConvertBorderColor(srgb_color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return device.GetLogical().CreateSampler(VkSamplerCreateInfo{
|
return device.GetLogical().CreateSampler(VkSamplerCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||||
|
|
@ -2689,8 +2717,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||||
.compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func),
|
.compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func),
|
||||||
.minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(),
|
.minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(),
|
||||||
.maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(),
|
.maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(),
|
||||||
.borderColor = custom_border ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT
|
.borderColor = fixed_border,
|
||||||
: ConvertBorderColor(color),
|
|
||||||
.unnormalizedCoordinates = VK_FALSE,
|
.unnormalizedCoordinates = VK_FALSE,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -2713,6 +2740,10 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||||
if (has_minmax_reduction) {
|
if (has_minmax_reduction) {
|
||||||
sampler_default_reduction = create_sampler(max_anisotropy, false, false, false, true);
|
sampler_default_reduction = create_sampler(max_anisotropy, false, false, false, true);
|
||||||
}
|
}
|
||||||
|
if (tsc.srgb_conversion && srgb_color != color) {
|
||||||
|
sampler_srgb_border =
|
||||||
|
create_sampler(max_anisotropy, false, false, false, false, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers,
|
Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers,
|
||||||
|
|
|
||||||
|
|
@ -509,6 +509,14 @@ public:
|
||||||
return static_cast<bool>(sampler_default_reduction);
|
return static_cast<bool>(sampler_default_reduction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] VkSampler HandleWithSrgbBorderColor() const noexcept {
|
||||||
|
return *sampler_srgb_border;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool HasSrgbBorderColor() const noexcept {
|
||||||
|
return static_cast<bool>(sampler_srgb_border);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vk::Sampler sampler;
|
vk::Sampler sampler;
|
||||||
vk::Sampler sampler_default_anisotropy;
|
vk::Sampler sampler_default_anisotropy;
|
||||||
|
|
@ -516,6 +524,7 @@ private:
|
||||||
vk::Sampler sampler_noncompare;
|
vk::Sampler sampler_noncompare;
|
||||||
vk::Sampler sampler_default_border;
|
vk::Sampler sampler_default_border;
|
||||||
vk::Sampler sampler_default_reduction;
|
vk::Sampler sampler_default_reduction;
|
||||||
|
vk::Sampler sampler_srgb_border;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureCacheParams {
|
struct TextureCacheParams {
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,10 @@ float SrgbToLinear(u32 value) {
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
std::array<float, 4> TSCEntry::BorderColor() const noexcept {
|
std::array<float, 4> TSCEntry::BorderColor() const noexcept {
|
||||||
if (!srgb_conversion) {
|
return border_color;
|
||||||
return border_color;
|
}
|
||||||
}
|
|
||||||
|
std::array<float, 4> TSCEntry::SrgbBorderColor() const noexcept {
|
||||||
return {SrgbToLinear(srgb_border_color_r), SrgbToLinear(srgb_border_color_g),
|
return {SrgbToLinear(srgb_border_color_r), SrgbToLinear(srgb_border_color_g),
|
||||||
SrgbToLinear(srgb_border_color_b), border_color[3]};
|
SrgbToLinear(srgb_border_color_b), border_color[3]};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -378,6 +378,8 @@ struct TSCEntry {
|
||||||
|
|
||||||
std::array<float, 4> BorderColor() const noexcept;
|
std::array<float, 4> BorderColor() const noexcept;
|
||||||
|
|
||||||
|
std::array<float, 4> SrgbBorderColor() const noexcept;
|
||||||
|
|
||||||
float MaxAnisotropy() const noexcept;
|
float MaxAnisotropy() const noexcept;
|
||||||
|
|
||||||
float MinLod() const {
|
float MinLod() const {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue