diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 404ffa8990..34ba98e71d 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -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()) diff --git a/rpcs3/Emu/RSX/VK/VKResourceManager.h b/rpcs3/Emu/RSX/VK/VKResourceManager.h index 1e2b8e69d1..6db8b3ece7 100644 --- a/rpcs3/Emu/RSX/VK/VKResourceManager.h +++ b/rpcs3/Emu/RSX/VK/VKResourceManager.h @@ -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) diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.cpp b/rpcs3/Emu/RSX/VK/vkutils/device.cpp index 086d8e0a0f..2c3cd327fc 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/device.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/device.cpp @@ -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; diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.h b/rpcs3/Emu/RSX/VK/vkutils/device.h index d945290bd0..e92ce779eb 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/device.h +++ b/rpcs3/Emu/RSX/VK/vkutils/device.h @@ -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; diff --git a/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp b/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp index fdaa69d960..9a7f6ddb93 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp @@ -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; diff --git a/rpcs3/Emu/RSX/VK/vkutils/sampler.h b/rpcs3/Emu/RSX/VK/vkutils/sampler.h index f55cea07fd..8fa3cc2232 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/sampler.h +++ b/rpcs3/Emu/RSX/VK/vkutils/sampler.h @@ -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);