vk: Improve compatibility with sub-par drivers and hardware

- Adds workarounds for INTEL + MSAA
- Adds support for younger drivers where all features may not be
  implemented.
  Things that won't out-right break the emulation can be
disabled.
This commit is contained in:
kd-11 2021-05-29 14:54:11 +03:00 committed by kd-11
parent a49446c9e9
commit 9199b1b1d8
6 changed files with 54 additions and 33 deletions

View file

@ -70,7 +70,7 @@ void VKGSRender::update_draw_state()
{
m_profiler.start();
float actual_line_width = rsx::method_registers.line_width();
const float actual_line_width = m_device->get_wide_lines_support()? rsx::method_registers.line_width() : 1.f;
vkCmdSetLineWidth(*m_current_command_buffer, actual_line_width);
if (rsx::method_registers.poly_offset_fill_enabled())

View file

@ -98,7 +98,7 @@ namespace vk
m_sampler_pool.clear();
}
vk::sampler* find_sampler(VkDevice dev, VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
vk::sampler* find_sampler(const vk::render_device& dev, VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
VkBool32 unnormalized_coordinates, float mipLodBias, float max_anisotropy, float min_lod, float max_lod,
VkFilter min_filter, VkFilter mag_filter, VkSamplerMipmapMode mipmap_mode, VkBorderColor border_color,
VkBool32 depth_compare = VK_FALSE, VkCompareOp depth_compare_mode = VK_COMPARE_OP_NEVER)

View file

@ -192,7 +192,7 @@ namespace vk
return count;
}
VkQueueFamilyProperties physical_device::get_queue_properties(u32 queue)
const VkQueueFamilyProperties& physical_device::get_queue_properties(u32 queue)
{
if (queue_props.empty())
{
@ -208,12 +208,12 @@ namespace vk
return queue_props[queue];
}
VkPhysicalDeviceMemoryProperties physical_device::get_memory_properties() const
const VkPhysicalDeviceMemoryProperties& physical_device::get_memory_properties() const
{
return memory_properties;
}
VkPhysicalDeviceLimits physical_device::get_limits() const
const VkPhysicalDeviceLimits& physical_device::get_limits() const
{
return props.limits;
}
@ -320,14 +320,6 @@ namespace vk
if (g_cfg.video.antialiasing_level != msaa_level::none)
{
// MSAA features
if (!pgpu->features.shaderStorageImageMultisample || !pgpu->features.shaderStorageImageWriteWithoutFormat)
{
// TODO: Slow fallback to emulate this
// Just warn and let the driver decide whether to crash or not
rsx_log.fatal("Your GPU driver does not support some required MSAA features. Expect problems.");
message_on_error += "Your GPU driver does not support some required MSAA features.\nTry updating your GPU driver or disable Anti-Aliasing in the settings.";
}
enabled_features.sampleRateShading = VK_TRUE;
enabled_features.alphaToOne = VK_TRUE;
enabled_features.shaderStorageImageMultisample = VK_TRUE;
@ -344,43 +336,58 @@ namespace vk
enabled_features.shaderStorageBufferArrayDynamicIndexing = VK_TRUE;
// If we're on lavapipe / llvmpipe, disable unimplemented features:
// - samplerAnisotropy
// - shaderStorageBufferArrayDynamicIndexing
// - wideLines
// as of mesa 21.1.0-dev (aea36ee05e9, 2020-02-10)
// Several games work even if we disable these, testing purpose only
if (pgpu->get_name().find("llvmpipe") != umax)
{
if (!pgpu->features.samplerAnisotropy)
{
rsx_log.error("Running lavapipe without support for samplerAnisotropy");
enabled_features.samplerAnisotropy = VK_FALSE;
}
if (!pgpu->features.shaderStorageBufferArrayDynamicIndexing)
{
rsx_log.error("Running lavapipe without support for shaderStorageBufferArrayDynamicIndexing");
enabled_features.shaderStorageBufferArrayDynamicIndexing = VK_FALSE;
}
if (!pgpu->features.wideLines)
{
rsx_log.error("Running lavapipe without support for wideLines");
enabled_features.wideLines = VK_FALSE;
}
}
// Optionally disable unsupported stuff
if (!pgpu->features.shaderStorageImageMultisample || !pgpu->features.shaderStorageImageWriteWithoutFormat)
{
// Disable MSAA if any of these two features are unsupported
if (g_cfg.video.antialiasing_level != msaa_level::none)
{
rsx_log.error("Your GPU driver does not support some required MSAA features. MSAA will be disabled.");
g_cfg.video.antialiasing_level.set(msaa_level::none);
}
enabled_features.sampleRateShading = VK_FALSE;
enabled_features.alphaToOne = VK_FALSE;
enabled_features.shaderStorageImageMultisample = VK_FALSE;
enabled_features.shaderStorageImageWriteWithoutFormat = VK_FALSE;
}
if (!pgpu->features.samplerAnisotropy)
{
rsx_log.error("Your GPU does not support anisotropic filtering. Graphics may not render correctly.");
enabled_features.samplerAnisotropy = VK_FALSE;
}
if (!pgpu->features.shaderFloat64)
{
rsx_log.error("Your GPU does not support double precision floats in shaders. Graphics may not work correctly.");
rsx_log.error("Your GPU does not support double precision floats in shaders. Graphics may not render correctly.");
enabled_features.shaderFloat64 = VK_FALSE;
}
if (!pgpu->features.depthBounds)
{
rsx_log.error("Your GPU does not support depth bounds testing. Graphics may not work correctly.");
rsx_log.error("Your GPU does not support depth bounds testing. Graphics may not render correctly.");
enabled_features.depthBounds = VK_FALSE;
}
if (!pgpu->features.wideLines)
{
rsx_log.error("Your GPU does not support wide lines. Graphics may not render correctly.");
enabled_features.wideLines = VK_FALSE;
}
if (!pgpu->features.sampleRateShading && enabled_features.sampleRateShading)
{
rsx_log.error("Your GPU does not support sample rate shading for multisampling. Graphics may be inaccurate when MSAA is enabled.");
@ -585,6 +592,16 @@ namespace vk
return pgpu->features.alphaToOne != VK_FALSE;
}
bool render_device::get_anisotropic_filtering_support() const
{
return pgpu->features.samplerAnisotropy != VK_FALSE;
}
bool render_device::get_wide_lines_support() const
{
return pgpu->features.wideLines != VK_FALSE;
}
bool render_device::get_conditional_render_support() const
{
return pgpu->conditional_render_support;

View file

@ -73,9 +73,10 @@ namespace vk
u32 get_queue_count() const;
VkQueueFamilyProperties get_queue_properties(u32 queue);
VkPhysicalDeviceMemoryProperties get_memory_properties() const;
VkPhysicalDeviceLimits get_limits() const;
// Device properties. These structs can be large so use with care.
const VkQueueFamilyProperties& get_queue_properties(u32 queue);
const VkPhysicalDeviceMemoryProperties& get_memory_properties() const;
const VkPhysicalDeviceLimits& get_limits() const;
operator VkPhysicalDevice() const;
operator VkInstance() const;
@ -126,6 +127,8 @@ namespace vk
bool get_shader_stencil_export_support() const;
bool get_depth_bounds_support() const;
bool get_alpha_to_one_support() const;
bool get_anisotropic_filtering_support() const;
bool get_wide_lines_support() const;
bool get_conditional_render_support() const;
bool get_unrestricted_depth_range_support() const;
bool get_external_memory_host_support() const;

View file

@ -3,7 +3,7 @@
namespace vk
{
sampler::sampler(VkDevice dev, VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
sampler::sampler(const vk::render_device& dev, VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
VkBool32 unnormalized_coordinates, float mipLodBias, float max_anisotropy, float min_lod, float max_lod,
VkFilter min_filter, VkFilter mag_filter, VkSamplerMipmapMode mipmap_mode, VkBorderColor border_color,
VkBool32 depth_compare, VkCompareOp depth_compare_mode)
@ -13,7 +13,7 @@ namespace vk
info.addressModeU = clamp_u;
info.addressModeV = clamp_v;
info.addressModeW = clamp_w;
info.anisotropyEnable = VK_TRUE;
info.anisotropyEnable = dev.get_anisotropic_filtering_support();
info.compareEnable = depth_compare;
info.unnormalizedCoordinates = unnormalized_coordinates;
info.mipLodBias = mipLodBias;

View file

@ -1,5 +1,6 @@
#pragma once
#include "device.h"
#include "shared.h"
namespace vk
@ -9,7 +10,7 @@ namespace vk
VkSampler value;
VkSamplerCreateInfo info = {};
sampler(VkDevice dev, VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
sampler(const vk::render_device& dev, VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
VkBool32 unnormalized_coordinates, float mipLodBias, float max_anisotropy, float min_lod, float max_lod,
VkFilter min_filter, VkFilter mag_filter, VkSamplerMipmapMode mipmap_mode, VkBorderColor border_color,
VkBool32 depth_compare = false, VkCompareOp depth_compare_mode = VK_COMPARE_OP_NEVER);