diff --git a/src/common/rendering/vulkan/samplers/vk_samplers.cpp b/src/common/rendering/vulkan/samplers/vk_samplers.cpp index 9e480dd12..a81e18200 100644 --- a/src/common/rendering/vulkan/samplers/vk_samplers.cpp +++ b/src/common/rendering/vulkan/samplers/vk_samplers.cpp @@ -32,6 +32,7 @@ #include "hw_material.h" #include "i_interface.h" #include "hwrenderer/postprocessing/hw_postprocess.h" +#include struct VkTexFilter { @@ -66,6 +67,63 @@ static VkTexClamp TexClamp[] = { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE }, }; +std::unordered_set CurrentDriverIntelDeviceIDs = +{ + // Devices out now that may have an older driver still + 0x0BDA, 0x0BD9, 0x0BDB, 0x0BD7, 0x0BD6, 0x0BD0, 0x0BD5, 0x56C0, + 0x56C1, 0x56B3, 0x56B2, 0x56A4, 0x56A3, 0x5697, 0x5696, 0x5695, + 0x56B1, 0x56B0, 0x56A6, 0x56A5, 0x56A1, 0x56A0, 0x5694, 0x5693, + 0x5692, 0x5691, 0x5690, 0xA7A9, 0xA7A8, 0xA7A1, 0xA7A0, 0xA721, + 0xA720, 0xA78B, 0xA78A, 0xA789, 0xA788, 0xA783, 0xA782, 0xA781, + 0xA780, 0x4907, 0x4905, 0x4680, 0x4682, 0x4688, 0x468A, 0x468B, + 0x4690, 0x4692, 0x4693, 0x46D0, 0x46D1, 0x46D2, 0x4626, 0x4628, + 0x462A, 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8, 0x46AA, + 0x46B0, 0x46B1, 0x46B2, 0x46B3, 0x46C0, 0x46C1, 0x46C2, 0x46C3, + 0x4C8A, 0x4C8B, 0x4C90, 0x4C9A, 0x4C8C, 0x4C80, 0x4E71, 0x4E61, + 0x4E57, 0x4E55, 0x4E51, 0x4571, 0x4557, 0x4555, 0x4551, 0x4541, + 0x9A59, 0x9A60, 0x9A68, 0x9A70, 0x9A40, 0x9A49, 0x9A78, 0x9AC0, + 0x9AC9, 0x9AD9, 0x9AF8 +}; + +std::unordered_set LegacyIntelDeviceIDs = +{ + // Not under active development as of 2024 + 0x8A70, 0x8A71, 0x8A56, 0x8A58, 0x8A5B, 0x8A5D, 0x8A54, 0x8A5A, + 0x8A5C, 0x8A57, 0x8A59, 0x8A50, 0x8A51, 0x8A52, 0x8A53, 0x3EA5, + 0x3EA8, 0x3EA6, 0x3EA7, 0x3EA2, 0x3E90, 0x3E93, 0x3E99, 0x3E9C, + 0x3EA1, 0x9BA5, 0x9BA8, 0x3EA4, 0x9B21, 0x9BA0, 0x9BA2, 0x9BA4, + 0x9BAA, 0x9BAB, 0x9BAC, 0x87CA, 0x3EA3, 0x9B41, 0x9BC0, 0x9BC2, + 0x9BC4, 0x9BCA, 0x9BCB, 0x9BCC, 0x3E91, 0x3E92, 0x3E98, 0x3E9B, + 0x9BC5, 0x9BC8, 0x3E96, 0x3E9A, 0x3E94, 0x9BC6, 0x9BE6, 0x9BF6, + 0x3EA9, 0x3EA0, 0x593B, 0x5923, 0x5926, 0x5927, 0x5917, 0x5912, + 0x591B, 0x5916, 0x5921, 0x591A, 0x591D, 0x591E, 0x591C, 0x87C0, + 0x5913, 0x5915, 0x5902, 0x5906, 0x590B, 0x590A, 0x5908, 0x590E, + 0x3185, 0x3184, 0x1A85, 0x5A85, 0x0A84, 0x1A84, 0x5A84, 0x192A, + 0x1932, 0x193B, 0x193A, 0x193D, 0x1923, 0x1926, 0x1927, 0x192B, + 0x192D, 0x1912, 0x191B, 0x1913, 0x1915, 0x1917, 0x191A, 0x1916, + 0x1921, 0x191D, 0x191E, 0x1902, 0x1906, 0x190B, 0x190A, 0x190E, + + // Hardware completely out of support. Generally only seen in Linux now: + 0x163D, 0x163A, 0x1632, 0x163E, 0x163B, 0x1636, 0x1622, 0x1626, + 0x162A, 0x162B, 0x162D, 0x162E, 0x1612, 0x1616, 0x161A, 0x161B, + 0x161D, 0x161E, 0x1602, 0x1606, 0x160A, 0x160B, 0x160D, 0x160E, + 0x22B0, 0x22B2, 0x22B3, 0x22B1, 0x0F30, 0x0F31, 0x0F32, 0x0F33, + 0x0157, 0x0155, 0x0422, 0x0426, 0x042A, 0x042B, 0x042E, 0x0C22, + 0x0C26, 0x0C2A, 0x0C2B, 0x0C2E, 0x0A22, 0x0A2A, 0x0A2B, 0x0D2A, + 0x0D2B, 0x0D2E, 0x0A26, 0x0A2E, 0x0D22, 0x0D26, 0x0412, 0x0416, + 0x0D12, 0x041A, 0x041B, 0x0C12, 0x0C16, 0x0C1A, 0x0C1B, 0x0C1E, + 0x0A12, 0x0A1A, 0x0A1B, 0x0D16, 0x0D1A, 0x0D1B, 0x0D1E, 0x041E, + 0x0A16, 0x0A1E, 0x0402, 0x0406, 0x040A, 0x040B, 0x040E, 0x0C02, + 0x0C06, 0x0C0A, 0x0C0B, 0x0C0E, 0x0A02, 0x0A06, 0x0A0A, 0x0A0B, + 0x0A0E, 0x0D02, 0x0D06, 0x0D0A, 0x0D0B, 0x0D0E, 0x0162, 0x0166, + 0x016A, 0x0152, 0x0156, 0x015A, 0x0112, 0x0122, 0x0116, 0x0126, + 0x0102, 0x0106, 0x010A, 0x0042, 0x0046, 0x2A42, 0x2E02, 0x2E12, + 0x2E22, 0x2E32, 0x2E42, 0x2E92, 0x29A2, 0x2982, 0x2992, 0x2972, + 0x2A02, 0x2A12, 0xA001, 0xA011, 0x29D2, 0x29C2, 0x29B2, 0x27AE, + 0x27A2, 0x2772, 0x2592, 0x258A, 0x2582, 0x2572, 0x3582, 0x358E, + 0x2562, 0x3577 +}; + VkSamplerManager::VkSamplerManager(VulkanRenderDevice* fb) : fb(fb) { CreateHWSamplers(); @@ -96,19 +154,43 @@ void VkSamplerManager::CreateHWSamplers() builder.MipmapMode(TexFilter[filter].mipfilter); if (TexFilter[filter].mipmapping) { + const auto& properties = fb->GetDevice()->PhysicalDevice.Properties.Properties; + // Anisotropy puts extra load on the memory architecture. // Unless the user explicitly chose their own filter value, default to lower filtering for integrated GPUs as they are generally slow. float maxAnisotropy = gl_texture_filter_anisotropic; if (maxAnisotropy < 1.0f) { - if (fb->GetDevice()->PhysicalDevice.Properties.Properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + if (properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) maxAnisotropy = 4.0f; else maxAnisotropy = 8.0f; } - // Intel has consistently been fucking up anisotropic filtering for a decade now. Time to punish them. If they now finally implement it in their hardware/drivers it will stay disabled! - if (maxAnisotropy > 1.0f && (fb->GetDevice()->PhysicalDevice.Properties.Properties.vendorID != 0x8086 || (TexFilter[filter].magFilter == VK_FILTER_LINEAR && TexFilter[filter].minFilter == VK_FILTER_LINEAR))) + // Intel devices handles anisotropic filtering differently than what we want. + if (properties.vendorID == 0x8086) + { + if (LegacyIntelDeviceIDs.find(properties.deviceID) != LegacyIntelDeviceIDs.end() || + (CurrentDriverIntelDeviceIDs.find(properties.deviceID) != CurrentDriverIntelDeviceIDs.end() && + (VK_VERSION_MAJOR(properties.driverVersion) > 0 || VK_VERSION_MINOR(properties.driverVersion) >= 405))) + { + // Old hardware and old drivers have to turn AF off if we want any nearest filtering. + if (TexFilter[filter].magFilter != VK_FILTER_LINEAR || TexFilter[filter].minFilter != VK_FILTER_LINEAR) + { + maxAnisotropy = 1.0f; + } + } + else + { + // Current driver still doesn't support trilinear min filtering. Use bilinear instead. + if (TexFilter[filter].mipfilter == VK_SAMPLER_MIPMAP_MODE_LINEAR) + { + builder.MipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST); + } + } + } + + if (maxAnisotropy > 1.0f) builder.Anisotropy(maxAnisotropy); builder.MaxLod(100.0f); // According to the spec this value is clamped so something high makes it usable for all textures. }