From d0dd989238addf353d7435dfdb3d26049f1b08f8 Mon Sep 17 00:00:00 2001 From: bomabomabomaboma <69987043+goldislead@users.noreply.github.com> Date: Fri, 31 Jul 2026 23:17:27 +0000 Subject: [PATCH] [GPU] Honor force_bc_w_to_max: force sampler border color alpha to 1.0 Co-authored-by: Herman S. <429230+has207@users.noreply.github.com> --- src/xenia/gpu/d3d12/d3d12_texture_cache.cc | 4 ++++ src/xenia/gpu/d3d12/d3d12_texture_cache.h | 3 +++ src/xenia/gpu/vulkan/vulkan_texture_cache.cc | 12 +++++++++--- src/xenia/gpu/vulkan/vulkan_texture_cache.h | 3 +++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/xenia/gpu/d3d12/d3d12_texture_cache.cc b/src/xenia/gpu/d3d12/d3d12_texture_cache.cc index a4de12e35..5226f5696 100644 --- a/src/xenia/gpu/d3d12/d3d12_texture_cache.cc +++ b/src/xenia/gpu/d3d12/d3d12_texture_cache.cc @@ -765,6 +765,7 @@ D3D12TextureCache::SamplerParameters D3D12TextureCache::GetSamplerParameters( xenos::ClampModeUsesBorder(parameters.clamp_y) || xenos::ClampModeUsesBorder(parameters.clamp_z)) { parameters.border_color = fetch.border_color; + parameters.force_bc_w_to_max = fetch.force_bc_w_to_max; } else { parameters.border_color = xenos::BorderColor::k_ABGR_Black; } @@ -891,6 +892,9 @@ void D3D12TextureCache::WriteSampler(SamplerParameters parameters, desc.BorderColor[3] = 0.0f; break; } + if (parameters.force_bc_w_to_max) { + desc.BorderColor[3] = 1.0f; + } desc.MinLOD = float(parameters.mip_min_level); if (parameters.mip_base_map) { // "It is undefined whether LOD clamping based on MinLOD and MaxLOD Sampler diff --git a/src/xenia/gpu/d3d12/d3d12_texture_cache.h b/src/xenia/gpu/d3d12/d3d12_texture_cache.h index c97e71586..599d42fb1 100644 --- a/src/xenia/gpu/d3d12/d3d12_texture_cache.h +++ b/src/xenia/gpu/d3d12/d3d12_texture_cache.h @@ -59,6 +59,9 @@ class D3D12TextureCache final : public TextureCache { xenos::AnisoFilter aniso_filter : 3; // 17 uint32_t mip_min_level : 4; // 21 uint32_t mip_base_map : 1; // 22 + // Force the border color alpha to 1.0 (only meaningful with a border + // clamp mode). + uint32_t force_bc_w_to_max : 1; // 23 // Maximum mip level is in the texture resource itself, but mip_base_map // can be used to limit fetching to mip_min_level. }; diff --git a/src/xenia/gpu/vulkan/vulkan_texture_cache.cc b/src/xenia/gpu/vulkan/vulkan_texture_cache.cc index 54ba79664..1ad7ab2e0 100644 --- a/src/xenia/gpu/vulkan/vulkan_texture_cache.cc +++ b/src/xenia/gpu/vulkan/vulkan_texture_cache.cc @@ -668,6 +668,7 @@ VulkanTextureCache::SamplerParameters VulkanTextureCache::GetSamplerParameters( xenos::ClampModeUsesBorder(parameters.clamp_y) || xenos::ClampModeUsesBorder(parameters.clamp_z)) { parameters.border_color = fetch.border_color; + parameters.force_bc_w_to_max = fetch.force_bc_w_to_max; } else { parameters.border_color = xenos::BorderColor::k_ABGR_Black; } @@ -889,18 +890,23 @@ VkSampler VulkanTextureCache::UseSampler(SamplerParameters parameters, color[1] = 0.5f; color[2] = 0.5f; } - color[3] = 0.0f; + color[3] = parameters.force_bc_w_to_max ? 1.0f : 0.0f; custom_border_color.format = VK_FORMAT_UNDEFINED; custom_border_color.pNext = sampler_create_info.pNext; sampler_create_info.pNext = &custom_border_color; sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_CUSTOM_EXT; } else { sampler_create_info.borderColor = - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + parameters.force_bc_w_to_max + ? VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK + : VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; } break; default: - sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + sampler_create_info.borderColor = + parameters.force_bc_w_to_max + ? VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK + : VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; break; } VkSampler vulkan_sampler; diff --git a/src/xenia/gpu/vulkan/vulkan_texture_cache.h b/src/xenia/gpu/vulkan/vulkan_texture_cache.h index fc9a0deb8..6cc0496cd 100644 --- a/src/xenia/gpu/vulkan/vulkan_texture_cache.h +++ b/src/xenia/gpu/vulkan/vulkan_texture_cache.h @@ -44,6 +44,9 @@ class VulkanTextureCache final : public TextureCache { xenos::AnisoFilter aniso_filter : 3; // 17 uint32_t mip_min_level : 4; // 21 uint32_t mip_base_map : 1; // 22 + // Force the border color alpha to 1.0 (only meaningful with a border + // clamp mode). + uint32_t force_bc_w_to_max : 1; // 23 // Maximum mip level is in the texture resource itself, but mip_base_map // can be used to limit fetching to mip_min_level. };