[D3D12] Fall back to point sampling for non-filterable formats

Matches Vulkan.

Co-authored-by: Herman S. <429230+has207@users.noreply.github.com>
This commit is contained in:
goldislead
2026-08-09 18:34:00 -07:00
committed by Radosław Gliński
parent 61a8aa3607
commit 197929d967
2 changed files with 51 additions and 1 deletions

View File

@@ -140,6 +140,32 @@ bool D3D12TextureCache::Initialize() {
}
scaled_resolve_heap_count_ = 0;
// GetSamplerParameters drops samplers for non-filterable formats.
for (uint32_t i = 0; i < xe::countof(host_formats_); ++i) {
const HostFormat& host_format = host_formats_[i];
uint64_t format_bit = uint64_t(1) << i;
if (host_format.dxgi_format_unsigned != DXGI_FORMAT_UNKNOWN) {
D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = {
host_format.dxgi_format_unsigned};
if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT,
&format_support,
sizeof(format_support))) &&
(format_support.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE)) {
host_filterable_unsigned_ |= format_bit;
}
}
if (host_format.dxgi_format_signed != DXGI_FORMAT_UNKNOWN) {
D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support = {
host_format.dxgi_format_signed};
if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT,
&format_support,
sizeof(format_support))) &&
(format_support.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE)) {
host_filterable_signed_ |= format_bit;
}
}
}
// Create the loading root signature.
D3D12_ROOT_PARAMETER root_parameters[3];
// Parameter 0 is constants (changed multiple times when untiling).
@@ -795,7 +821,6 @@ D3D12TextureCache::SamplerParameters D3D12TextureCache::GetSamplerParameters(
mip_filter == xenos::TextureFilter::kLinear;
bool mip_base_map = mip_filter == xenos::TextureFilter::kBaseMap;
// high cache miss count here, prefetch fetch earlier
// TODO(Triang3l): Disable filtering for texture formats not supporting it.
xenos::AnisoFilter aniso_filter =
binding.aniso_filter == xenos::AnisoFilter::kUseFetchConst
? fetch.aniso_filter
@@ -820,6 +845,27 @@ D3D12TextureCache::SamplerParameters D3D12TextureCache::GetSamplerParameters(
}
parameters.mip_base_map = mip_base_map;
// Fall back to point sampling if the host formats don't report
// D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE.
if (parameters.mag_linear || parameters.min_linear || parameters.mip_linear ||
parameters.aniso_filter != xenos::AnisoFilter::kDisabled) {
TextureKey texture_key;
uint8_t texture_swizzled_signs;
BindingInfoFromFetchConstant(fetch, texture_key, &texture_swizzled_signs);
uint64_t format_bit =
texture_key.is_valid ? uint64_t(1) << uint32_t(texture_key.format) : 0;
if (!texture_key.is_valid ||
(texture_util::IsAnySignNotSigned(texture_swizzled_signs) &&
(host_filterable_unsigned_ & format_bit) == 0) ||
(texture_util::IsAnySignSigned(texture_swizzled_signs) &&
(host_filterable_signed_ & format_bit) == 0)) {
parameters.mag_linear = 0;
parameters.min_linear = 0;
parameters.mip_linear = 0;
parameters.aniso_filter = xenos::AnisoFilter::kDisabled;
}
}
return parameters;
}

View File

@@ -821,6 +821,10 @@ class D3D12TextureCache final : public TextureCache {
D3D12CommandProcessor& command_processor_;
bool bindless_resources_used_;
// Bits per format, for checking if the host format should be point-filtered.
uint64_t host_filterable_unsigned_ = 0;
uint64_t host_filterable_signed_ = 0;
Microsoft::WRL::ComPtr<ID3D12RootSignature> load_root_signature_;
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>, kLoadShaderCount>
load_pipelines_;