diff --git a/rpcs3/Emu/RSX/VK/VKFormats.cpp b/rpcs3/Emu/RSX/VK/VKFormats.cpp index a0cd23748d..195ffdff39 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.cpp +++ b/rpcs3/Emu/RSX/VK/VKFormats.cpp @@ -48,17 +48,17 @@ namespace vk fmt::throw_exception("Invalid format (0x%x)" HERE, (u32)format); } - std::tuple 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; diff --git a/rpcs3/Emu/RSX/VK/VKFormats.h b/rpcs3/Emu/RSX/VK/VKFormats.h index c26472f053..86c0bfbedd 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.h +++ b/rpcs3/Emu/RSX/VK/VKFormats.h @@ -1,9 +1,16 @@ -#pragma once +#pragma once #include "VKHelpers.h" #include 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 get_format_convert_flags(VkFormat format); bool formats_are_bitcast_compatible(VkFormat format1, VkFormat format2); - std::tuple 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); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 3d67f17dad..625e2d97dd 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -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