From 15513f08011b92e5cfe12107e197547978e49c93 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 13 Dec 2019 02:38:34 -0300 Subject: maxwell_to_vk: Approach GL_CLAMP closer to the GL spec The OpenGL spec defines GL_CLAMP's formula similarly to CLAMP_TO_EDGE and CLAMP_TO_BORDER depending on the filter mode used. It doesn't exactly behave like this, but it's the closest we can get with what Vulkan offers without emulating it by injecting shader code. --- src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 16 +++++++++++----- src/video_core/renderer_vulkan/maxwell_to_vk.h | 3 ++- src/video_core/renderer_vulkan/vk_sampler_cache.cpp | 7 ++++--- 3 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 5263dd768..a1dc8dfd8 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -44,7 +44,8 @@ vk::SamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filt return {}; } -vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode) { +vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode, + Tegra::Texture::TextureFilter filter) { switch (wrap_mode) { case Tegra::Texture::WrapMode::Wrap: return vk::SamplerAddressMode::eRepeat; @@ -55,10 +56,15 @@ vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode) { case Tegra::Texture::WrapMode::Border: return vk::SamplerAddressMode::eClampToBorder; case Tegra::Texture::WrapMode::Clamp: - // TODO(Rodrigo): GL_CLAMP was removed as of OpenGL 3.1, to implement GL_CLAMP, we can use - // eClampToBorder to get the border color of the texture, and then sample the edge to - // manually mix them. However the shader part of this is not yet implemented. - return vk::SamplerAddressMode::eClampToBorder; + // TODO(Rodrigo): Emulate GL_CLAMP properly + switch (filter) { + case Tegra::Texture::TextureFilter::Nearest: + return vk::SamplerAddressMode::eClampToEdge; + case Tegra::Texture::TextureFilter::Linear: + return vk::SamplerAddressMode::eClampToBorder; + } + UNREACHABLE(); + return vk::SamplerAddressMode::eClampToEdge; case Tegra::Texture::WrapMode::MirrorOnceClampToEdge: return vk::SamplerAddressMode::eMirrorClampToEdge; case Tegra::Texture::WrapMode::MirrorOnceBorder: diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h index 7dafdacf8..dd9de1d24 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.h +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h @@ -23,7 +23,8 @@ vk::Filter Filter(Tegra::Texture::TextureFilter filter); vk::SamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter); -vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode); +vk::SamplerAddressMode WrapMode(Tegra::Texture::WrapMode wrap_mode, + Tegra::Texture::TextureFilter filter); vk::CompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_func); diff --git a/src/video_core/renderer_vulkan/vk_sampler_cache.cpp b/src/video_core/renderer_vulkan/vk_sampler_cache.cpp index 801826d3d..1ce583f75 100644 --- a/src/video_core/renderer_vulkan/vk_sampler_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_sampler_cache.cpp @@ -46,9 +46,10 @@ UniqueSampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc) {}, MaxwellToVK::Sampler::Filter(tsc.mag_filter), MaxwellToVK::Sampler::Filter(tsc.min_filter), MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter), - MaxwellToVK::Sampler::WrapMode(tsc.wrap_u), MaxwellToVK::Sampler::WrapMode(tsc.wrap_v), - MaxwellToVK::Sampler::WrapMode(tsc.wrap_p), tsc.GetLodBias(), has_anisotropy, - max_anisotropy, tsc.depth_compare_enabled, + MaxwellToVK::Sampler::WrapMode(tsc.wrap_u, tsc.mag_filter), + MaxwellToVK::Sampler::WrapMode(tsc.wrap_v, tsc.mag_filter), + MaxwellToVK::Sampler::WrapMode(tsc.wrap_p, tsc.mag_filter), tsc.GetLodBias(), + has_anisotropy, max_anisotropy, tsc.depth_compare_enabled, MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func), tsc.GetMinLod(), tsc.GetMaxLod(), vk_border_color.value_or(vk::BorderColor::eFloatTransparentBlack), unnormalized_coords); -- cgit v1.2.3