mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-04-25 20:04:56 +02:00
[TEST] Adjustments to compareEnable detection for depth samplers
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include "shader_recompiler/backend/spirv/emit_spirv.h"
|
||||
#include "shader_recompiler/shader_info.h"
|
||||
#include "video_core/renderer_vulkan/vk_texture_cache.h"
|
||||
#include "video_core/renderer_vulkan/maxwell_to_vk.h"
|
||||
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
|
||||
#include "video_core/texture_cache/types.h"
|
||||
#include "video_core/vulkan_common/vulkan_device.h"
|
||||
@@ -197,8 +198,29 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
|
||||
const Sampler& sampler{texture_cache.GetSampler(sampler_id)};
|
||||
const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
|
||||
!image_view.SupportsAnisotropy()};
|
||||
const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy()
|
||||
: sampler.Handle()};
|
||||
|
||||
// In case sampler requires depth comparison but the format doesn't support it.
|
||||
bool need_no_compare = false;
|
||||
if (sampler.HasCompareEnabled()) {
|
||||
const auto& device = texture_cache.runtime.device;
|
||||
const auto fmt_info = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true,
|
||||
image_view.format);
|
||||
if (!device.IsFormatSupported(fmt_info.format,
|
||||
VK_FORMAT_FEATURE_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT,
|
||||
FormatType::Optimal)) {
|
||||
need_no_compare = true;
|
||||
}
|
||||
}
|
||||
|
||||
VkSampler vk_sampler;
|
||||
if (need_no_compare) {
|
||||
vk_sampler = use_fallback_sampler ?
|
||||
sampler.HandleNoCompareWithDefaultAnisotropy()
|
||||
: sampler.HandleNoCompare();
|
||||
} else {
|
||||
vk_sampler = use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy()
|
||||
: sampler.Handle();
|
||||
}
|
||||
guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler);
|
||||
rescaling.PushTexture(texture_cache.IsRescaling(image_view));
|
||||
}
|
||||
|
||||
@@ -2284,8 +2284,28 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type,
|
||||
storage_views.emplace();
|
||||
auto& views{is_signed ? storage_views->signeds : storage_views->unsigneds};
|
||||
auto& view{views[size_t(texture_type)]};
|
||||
if (!view)
|
||||
view = MakeView(Format(image_format), VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
if (!view) {
|
||||
static constexpr VkImageViewUsageCreateInfo storage_image_view_usage_create_info{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.usage = VK_IMAGE_USAGE_STORAGE_BIT,
|
||||
};
|
||||
view = device->GetLogical().CreateImageView({
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.pNext = &storage_image_view_usage_create_info,
|
||||
.flags = 0,
|
||||
.image = image_handle,
|
||||
.viewType = ImageViewType(type),
|
||||
.format = Format(image_format),
|
||||
.components{
|
||||
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
},
|
||||
.subresourceRange = MakeSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, range),
|
||||
});
|
||||
}
|
||||
return *view;
|
||||
}
|
||||
return VK_NULL_HANDLE;
|
||||
@@ -2350,7 +2370,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||
// Some games have samplers with garbage. Sanitize them here.
|
||||
const f32 max_anisotropy = std::clamp(tsc.MaxAnisotropy(), 1.0f, 16.0f);
|
||||
|
||||
const auto create_sampler = [&](const f32 anisotropy) {
|
||||
const auto create_sampler = [&](const f32 anisotropy, bool compare_enable) {
|
||||
return device.GetLogical().CreateSampler(VkSamplerCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
.pNext = pnext,
|
||||
@@ -2364,7 +2384,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||
.mipLodBias = tsc.LodBias(),
|
||||
.anisotropyEnable = static_cast<VkBool32>(anisotropy > 1.0f ? VK_TRUE : VK_FALSE),
|
||||
.maxAnisotropy = anisotropy,
|
||||
.compareEnable = tsc.depth_compare_enabled,
|
||||
.compareEnable = compare_enable ? VK_TRUE : VK_FALSE,
|
||||
.compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func),
|
||||
.minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(),
|
||||
.maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(),
|
||||
@@ -2374,11 +2394,23 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||
});
|
||||
};
|
||||
|
||||
sampler = create_sampler(max_anisotropy);
|
||||
compare_enable = static_cast<bool>(tsc.depth_compare_enabled);
|
||||
|
||||
sampler = create_sampler(max_anisotropy, compare_enable);
|
||||
if (compare_enable) {
|
||||
sampler_no_compare = create_sampler(max_anisotropy, false);
|
||||
} else {
|
||||
sampler_no_compare = sampler;
|
||||
}
|
||||
|
||||
const f32 max_anisotropy_default = static_cast<f32>(1U << tsc.max_anisotropy);
|
||||
if (max_anisotropy > max_anisotropy_default) {
|
||||
sampler_default_anisotropy = create_sampler(max_anisotropy_default);
|
||||
sampler_default_anisotropy = create_sampler(max_anisotropy_default, compare_enable);
|
||||
if (compare_enable) {
|
||||
sampler_no_compare_default_anisotropy = create_sampler(max_anisotropy_default, false);
|
||||
} else {
|
||||
sampler_no_compare_default_anisotropy = sampler_default_anisotropy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
@@ -408,9 +408,28 @@ public:
|
||||
return static_cast<bool>(sampler_default_anisotropy);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool HasCompareEnabled() const noexcept {
|
||||
return compare_enable;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkSampler HandleNoCompare() const noexcept {
|
||||
return sampler_no_compare ? *sampler_no_compare : *sampler;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkSampler HandleNoCompareWithDefaultAnisotropy() const noexcept {
|
||||
if (sampler_no_compare_default_anisotropy)
|
||||
return *sampler_no_compare_default_anisotropy;
|
||||
if (sampler_default_anisotropy)
|
||||
return *sampler_default_anisotropy;
|
||||
return *sampler;
|
||||
}
|
||||
|
||||
private:
|
||||
vk::Sampler sampler;
|
||||
vk::Sampler sampler_default_anisotropy;
|
||||
vk::Sampler sampler_no_compare;
|
||||
vk::Sampler sampler_no_compare_default_anisotropy;
|
||||
bool compare_enable = false;
|
||||
};
|
||||
|
||||
struct TextureCacheParams {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging.h"
|
||||
#include "common/settings.h"
|
||||
#include "video_core/surface.h"
|
||||
#include "video_core/texture_cache/format_lookup_table.h"
|
||||
@@ -130,6 +131,23 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
|
||||
size.width *= NumSamplesX(config.msaa_mode);
|
||||
size.height *= NumSamplesY(config.msaa_mode);
|
||||
}
|
||||
|
||||
{
|
||||
u32 max_dim = std::max({size.width, size.height, size.depth});
|
||||
if (max_dim == 0) {
|
||||
max_dim = 1;
|
||||
}
|
||||
u32 max_mip_levels = 1;
|
||||
while (max_dim > 1) {
|
||||
max_dim >>= 1;
|
||||
++max_mip_levels;
|
||||
}
|
||||
if (resources.levels > static_cast<s32>(max_mip_levels)) {
|
||||
LOG_WARNING(HW_GPU, "Clamping mip levels from {} to {} for size {}x{}x{}",
|
||||
resources.levels, max_mip_levels, size.width, size.height, size.depth);
|
||||
resources.levels = static_cast<s32>(max_mip_levels);
|
||||
}
|
||||
}
|
||||
if (type != ImageType::Linear) {
|
||||
// FIXME: Call this without passing *this
|
||||
layer_stride = CalculateLayerStride(*this);
|
||||
|
||||
Reference in New Issue
Block a user