From 5901e55aa6678c6d17e713f03a6c276b045370dd Mon Sep 17 00:00:00 2001 From: MaranBr Date: Wed, 10 Dec 2025 08:53:25 -0400 Subject: [PATCH] Fix texture wrap modes for Vulkan and OpenGL --- src/video_core/renderer_opengl/maxwell_to_gl.h | 7 ++++--- src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 16 +--------------- src/video_core/renderer_vulkan/maxwell_to_vk.h | 3 +-- .../renderer_vulkan/vk_texture_cache.cpp | 6 +++--- 4 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 5ea9e23780..7bf28a327e 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h @@ -304,7 +304,7 @@ inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) { case Tegra::Texture::WrapMode::Border: return GL_CLAMP_TO_BORDER; case Tegra::Texture::WrapMode::Clamp: - return GL_CLAMP; + return GL_CLAMP_TO_EDGE; case Tegra::Texture::WrapMode::MirrorOnceClampToEdge: return GL_MIRROR_CLAMP_TO_EDGE; case Tegra::Texture::WrapMode::MirrorOnceBorder: @@ -319,9 +319,10 @@ inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) { } else { return GL_MIRROR_CLAMP_TO_EDGE; } + default: + UNIMPLEMENTED_MSG("Unimplemented texture wrap mode={}", wrap_mode); + return GL_REPEAT; } - UNIMPLEMENTED_MSG("Unimplemented texture wrap mode={}", wrap_mode); - return GL_REPEAT; } inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) { diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 6c79974481..87d62e9d62 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -50,8 +50,7 @@ VkSamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter return {}; } -VkSamplerAddressMode WrapMode(const Device& device, Tegra::Texture::WrapMode wrap_mode, - Tegra::Texture::TextureFilter filter) { +VkSamplerAddressMode WrapMode(const Device& device, Tegra::Texture::WrapMode wrap_mode) { switch (wrap_mode) { case Tegra::Texture::WrapMode::Wrap: return VK_SAMPLER_ADDRESS_MODE_REPEAT; @@ -62,19 +61,6 @@ VkSamplerAddressMode WrapMode(const Device& device, Tegra::Texture::WrapMode wra case Tegra::Texture::WrapMode::Border: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; case Tegra::Texture::WrapMode::Clamp: - if (device.GetDriverID() == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { - // Nvidia's Vulkan driver defaults to GL_CLAMP on invalid enumerations, we can hack this - // by sending an invalid enumeration. - return static_cast(0xcafe); - } - // TODO(Rodrigo): Emulate GL_CLAMP properly on other vendors - switch (filter) { - case Tegra::Texture::TextureFilter::Nearest: - return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - case Tegra::Texture::TextureFilter::Linear: - return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; - } - ASSERT(false); return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; case Tegra::Texture::WrapMode::MirrorOnceClampToEdge: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h index 22108a3769..b6e18fe61b 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.h +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h @@ -70,8 +70,7 @@ VkFilter Filter(Tegra::Texture::TextureFilter filter); VkSamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter); -VkSamplerAddressMode WrapMode(const Device& device, Tegra::Texture::WrapMode wrap_mode, - Tegra::Texture::TextureFilter filter); +VkSamplerAddressMode WrapMode(const Device& device, Tegra::Texture::WrapMode wrap_mode); VkCompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_func); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index f821c71b7b..675d58209f 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2257,9 +2257,9 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t .magFilter = MaxwellToVK::Sampler::Filter(tsc.mag_filter), .minFilter = MaxwellToVK::Sampler::Filter(tsc.min_filter), .mipmapMode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter), - .addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter), - .addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter), - .addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter), + .addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u), + .addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v), + .addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p), .mipLodBias = tsc.LodBias(), .anisotropyEnable = static_cast(anisotropy > 1.0f ? VK_TRUE : VK_FALSE), .maxAnisotropy = anisotropy,