From 2bd91c66463d836cadf6d349ca3dceb98670e712 Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Wed, 28 Jan 2026 13:18:18 +0300 Subject: [PATCH] Handle nearest filtering modes in D3D12 driver when anisotropy is enabled. --- .../d3d12/rendering_device_driver_d3d12.cpp | 27 ++++++++++++++++--- drivers/d3d12/rendering_device_driver_d3d12.h | 5 ++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index e06f5f75e95..160b70f99ae 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -1933,8 +1933,23 @@ RDD::SamplerID RenderingDeviceDriverD3D12::sampler_create(const SamplerState &p_ D3D12_SAMPLER_DESC &sampler_desc = samplers[slot]; - if (p_state.use_anisotropy) { - sampler_desc.Filter = D3D12_ENCODE_ANISOTROPIC_FILTER(D3D12_FILTER_REDUCTION_TYPE_STANDARD); + // D3D12 does not support anisotropic nearest filtering. + bool use_anisotropy = p_state.use_anisotropy && p_state.min_filter == RDD::SAMPLER_FILTER_LINEAR && p_state.mag_filter == RDD::SAMPLER_FILTER_LINEAR; + + // Nearest mipmap is a separate D3D12 capability. + if (!sampler_capabilities.aniso_filter_with_point_mip_supported && p_state.mip_filter == RDD::SAMPLER_FILTER_NEAREST) { + use_anisotropy = false; + } + + D3D12_FILTER_REDUCTION_TYPE reduction_type = p_state.enable_compare ? D3D12_FILTER_REDUCTION_TYPE_COMPARISON : D3D12_FILTER_REDUCTION_TYPE_STANDARD; + + if (use_anisotropy) { + if (p_state.mip_filter == RDD::SAMPLER_FILTER_NEAREST) { + // This path is never going to be taken if the capability is unsupported. + sampler_desc.Filter = D3D12_ENCODE_MIN_MAG_ANISOTROPIC_MIP_POINT_FILTER(reduction_type); + } else { + sampler_desc.Filter = D3D12_ENCODE_ANISOTROPIC_FILTER(reduction_type); + } sampler_desc.MaxAnisotropy = p_state.anisotropy_max; } else { static const D3D12_FILTER_TYPE RD_FILTER_TYPE_TO_D3D12[] = { @@ -1945,7 +1960,7 @@ RDD::SamplerID RenderingDeviceDriverD3D12::sampler_create(const SamplerState &p_ RD_FILTER_TYPE_TO_D3D12[p_state.min_filter], RD_FILTER_TYPE_TO_D3D12[p_state.mag_filter], RD_FILTER_TYPE_TO_D3D12[p_state.mip_filter], - p_state.enable_compare ? D3D12_FILTER_REDUCTION_TYPE_COMPARISON : D3D12_FILTER_REDUCTION_TYPE_STANDARD); + reduction_type); } sampler_desc.AddressU = RD_REPEAT_MODE_TO_D3D12_ADDRESS_MODE[p_state.repeat_u]; @@ -6170,6 +6185,12 @@ Error RenderingDeviceDriverD3D12::_check_capabilities() { barrier_capabilities.enhanced_barriers_supported = options12.EnhancedBarriersSupported; } + D3D12_FEATURE_DATA_D3D12_OPTIONS19 options19 = {}; + res = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS19, &options19, sizeof(options19)); + if (SUCCEEDED(res)) { + sampler_capabilities.aniso_filter_with_point_mip_supported = options19.AnisoFilterWithPointMipSupported; + } + if (fsr_capabilities.pipeline_supported || fsr_capabilities.primitive_supported || fsr_capabilities.attachment_supported) { print_verbose("- D3D12 Variable Rate Shading supported:"); if (fsr_capabilities.pipeline_supported) { diff --git a/drivers/d3d12/rendering_device_driver_d3d12.h b/drivers/d3d12/rendering_device_driver_d3d12.h index db6d397cd7e..7b49b56d0a0 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.h +++ b/drivers/d3d12/rendering_device_driver_d3d12.h @@ -126,6 +126,10 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver { bool depth_bounds_supported = false; }; + struct SamplerCapabilities { + bool aniso_filter_with_point_mip_supported = false; + }; + RenderingContextDriverD3D12 *context_driver = nullptr; RenderingContextDriver::Device context_device; Microsoft::WRL::ComPtr adapter; @@ -141,6 +145,7 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver { FormatCapabilities format_capabilities; BarrierCapabilities barrier_capabilities; MiscFeaturesSupport misc_features_support; + SamplerCapabilities sampler_capabilities; RenderingShaderContainerFormatD3D12 shader_container_format; String pipeline_cache_id; D3D12_HEAP_TYPE dynamic_persistent_upload_heap = D3D12_HEAP_TYPE_UPLOAD;