vk: Disable mipmap sampling if sampling mode is does not have a mipmap filtering mode.

- GL_LINEAR and GL_NEAREST always sample LOD0 so make vulkan behave the same way
This commit is contained in:
kd-11 2019-10-18 14:07:30 +03:00 committed by kd-11
parent 404073c74a
commit 299b98b30a
3 changed files with 29 additions and 20 deletions

View File

@ -48,17 +48,17 @@ namespace vk
fmt::throw_exception("Invalid format (0x%x)" HERE, (u32)format);
}
std::tuple<VkFilter, VkSamplerMipmapMode> get_min_filter_and_mip(rsx::texture_minify_filter min_filter)
minification_filter get_min_filter(rsx::texture_minify_filter min_filter)
{
switch (min_filter)
{
case rsx::texture_minify_filter::nearest: return std::make_tuple(VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST);
case rsx::texture_minify_filter::linear: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST);
case rsx::texture_minify_filter::nearest_nearest: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST);
case rsx::texture_minify_filter::linear_nearest: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST);
case rsx::texture_minify_filter::nearest_linear: return std::make_tuple(VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_LINEAR);
case rsx::texture_minify_filter::linear_linear: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_LINEAR);
case rsx::texture_minify_filter::convolution_min: return std::make_tuple(VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_LINEAR);
case rsx::texture_minify_filter::nearest: return { VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, false };
case rsx::texture_minify_filter::linear: return { VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST, false };
case rsx::texture_minify_filter::nearest_nearest: return { VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST, true };
case rsx::texture_minify_filter::linear_nearest: return { VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST, true };
case rsx::texture_minify_filter::nearest_linear: return { VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_LINEAR, true };
case rsx::texture_minify_filter::linear_linear: return { VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_LINEAR, true };
case rsx::texture_minify_filter::convolution_min: return { VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_LINEAR, false };
default:
ASSUME(0);
break;

View File

@ -1,9 +1,16 @@
#pragma once
#pragma once
#include "VKHelpers.h"
#include <tuple>
namespace vk
{
struct minification_filter
{
VkFilter filter;
VkSamplerMipmapMode mipmap_mode;
bool sample_mipmaps;
};
VkBorderColor get_border_color(u32 color);
VkFormat get_compatible_depth_surface_format(const gpu_formats_support &support, rsx::surface_depth_format format);
@ -14,7 +21,7 @@ namespace vk
std::pair<bool, u32> get_format_convert_flags(VkFormat format);
bool formats_are_bitcast_compatible(VkFormat format1, VkFormat format2);
std::tuple<VkFilter, VkSamplerMipmapMode> get_min_filter_and_mip(rsx::texture_minify_filter min_filter);
minification_filter get_min_filter(rsx::texture_minify_filter min_filter);
VkFilter get_mag_filter(rsx::texture_magnify_filter mag_filter);
VkSamplerAddressMode vk_wrap_mode(rsx::texture_wrap_mode gcm_wrap);
float max_aniso(rsx::texture_max_anisotropy gcm_aniso);

View File

@ -1285,8 +1285,8 @@ void VKGSRender::end()
}
bool replace = !fs_sampler_handles[i];
VkFilter min_filter, mag_filter;
VkSamplerMipmapMode mip_mode;
VkFilter mag_filter;
vk::minification_filter min_filter;
f32 min_lod = 0.f, max_lod = 0.f;
f32 lod_bias = 0.f;
@ -1335,18 +1335,20 @@ void VKGSRender::end()
can_sample_linear = m_device->get_format_properties(vk_format).optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
}
const auto mipmap_count = rsx::method_registers.fragment_textures[i].get_exact_mipmap_count();
min_filter = vk::get_min_filter(rsx::method_registers.fragment_textures[i].min_filter());
if (can_sample_linear)
{
mag_filter = vk::get_mag_filter(rsx::method_registers.fragment_textures[i].mag_filter());
std::tie(min_filter, mip_mode) = vk::get_min_filter_and_mip(rsx::method_registers.fragment_textures[i].min_filter());
}
else
{
mag_filter = min_filter = VK_FILTER_NEAREST;
mip_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
mag_filter = VK_FILTER_NEAREST;
min_filter.filter = VK_FILTER_NEAREST;
}
if (rsx::method_registers.fragment_textures[i].get_exact_mipmap_count() > 1)
if (min_filter.sample_mipmaps && mipmap_count > 1)
{
min_lod = rsx::method_registers.fragment_textures[i].min_lod();
max_lod = rsx::method_registers.fragment_textures[i].max_lod();
@ -1355,7 +1357,7 @@ void VKGSRender::end()
f32 actual_mipmaps;
if (sampler_state->upload_context == rsx::texture_upload_context::shader_read)
{
actual_mipmaps = (f32)rsx::method_registers.fragment_textures[i].get_exact_mipmap_count();
actual_mipmaps = (f32)mipmap_count;
}
else if (sampler_state->external_subresource_desc.op == rsx::deferred_request_command::mipmap_gather)
{
@ -1375,14 +1377,14 @@ void VKGSRender::end()
else
{
min_lod = max_lod = lod_bias = 0.f;
mip_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
min_filter.mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
}
}
if (fs_sampler_handles[i] && m_textures_dirty[i])
{
if (!fs_sampler_handles[i]->matches(wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
min_filter, mag_filter, mip_mode, border_color, compare_enabled, depth_compare_mode))
min_filter.filter, mag_filter, min_filter.mipmap_mode, border_color, compare_enabled, depth_compare_mode))
{
replace = true;
}
@ -1391,7 +1393,7 @@ void VKGSRender::end()
if (replace)
{
fs_sampler_handles[i] = vk::get_resource_manager()->find_sampler(*m_device, wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
min_filter, mag_filter, mip_mode, border_color, compare_enabled, depth_compare_mode);
min_filter.filter, mag_filter, min_filter.mipmap_mode, border_color, compare_enabled, depth_compare_mode);
}
}
else