diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index 789f4da2ed..9630e8bd45 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp @@ -37,7 +37,7 @@ namespace Vulkan { using VideoCommon::ImageViewType; namespace { - + [[nodiscard]] VkImageAspectFlags AspectMaskFromFormat(VideoCore::Surface::PixelFormat format) { using VideoCore::Surface::SurfaceType; switch (VideoCore::Surface::GetFormatType(format)) { @@ -516,16 +516,16 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, nullptr, PUSH_CONSTANT_RANGE))), full_screen_vert(BuildShader(device, FULL_SCREEN_TRIANGLE_VERT_SPV)), blit_color_to_color_frag(BuildShader(device, BLIT_COLOR_FLOAT_FRAG_SPV)), - blit_depth_stencil_frag(device.IsExtShaderStencilExportSupported() - ? BuildShader(device, VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV) + blit_depth_stencil_frag(device.IsExtShaderStencilExportSupported() + ? BuildShader(device, VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV) : vk::ShaderModule{}), clear_color_vert(BuildShader(device, VULKAN_COLOR_CLEAR_VERT_SPV)), clear_color_frag(BuildShader(device, VULKAN_COLOR_CLEAR_FRAG_SPV)), clear_stencil_frag(BuildShader(device, VULKAN_DEPTHSTENCIL_CLEAR_FRAG_SPV)), convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)), convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), - convert_abgr8_to_d24s8_frag(device.IsExtShaderStencilExportSupported() - ? BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV) + convert_abgr8_to_d24s8_frag(device.IsExtShaderStencilExportSupported() + ? BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV) : vk::ShaderModule{}), convert_abgr8_to_d32f_frag(BuildShader(device, CONVERT_ABGR8_TO_D32F_FRAG_SPV)), convert_d32f_to_abgr8_frag(BuildShader(device, CONVERT_D32F_TO_ABGR8_FRAG_SPV)), diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 43fbefe425..ea0cc5a5d0 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -867,20 +867,20 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { VK_DYNAMIC_STATE_STENCIL_OP_EXT, }; dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end()); - + // VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT is part of EDS1 // Only use it if VIDS is not active (VIDS replaces it with full vertex input control) if (!key.state.dynamic_vertex_input) { dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT); } } - + // VK_DYNAMIC_STATE_VERTEX_INPUT_EXT (VIDS) - Independent from EDS // Provides full dynamic vertex input control, replaces VERTEX_INPUT_BINDING_STRIDE if (key.state.dynamic_vertex_input) { dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT); } - + // EDS2 - Core (3 states) if (key.state.extended_dynamic_state_2) { static constexpr std::array extended2{ @@ -890,12 +890,12 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { }; dynamic_states.insert(dynamic_states.end(), extended2.begin(), extended2.end()); } - + // EDS2 - LogicOp (granular) if (key.state.extended_dynamic_state_2_logic_op) { dynamic_states.push_back(VK_DYNAMIC_STATE_LOGIC_OP_EXT); } - + // EDS3 - Blending (composite: 3 states) if (key.state.extended_dynamic_state_3_blend) { static constexpr std::array extended3{ @@ -905,7 +905,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { }; dynamic_states.insert(dynamic_states.end(), extended3.begin(), extended3.end()); } - + // EDS3 - Enables (composite: per-feature) if (key.state.extended_dynamic_state_3_enables) { if (device.SupportsDynamicState3DepthClampEnable()) { diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 817320c96c..ab423fb8f2 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -461,28 +461,28 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, } LOG_INFO(Render_Vulkan, "DynamicState setting value: {}", u32(Settings::values.dyna_state.GetValue())); - + dynamic_features = {}; - + // User granularity enforced in vulkan_device.cpp switch statement: // Level 0: Core Dynamic States only // Level 1: Core + EDS1 // Level 2: Core + EDS1 + EDS2 (accumulative) // Level 3: Core + EDS1 + EDS2 + EDS3 (accumulative) // Here we only verify if extensions were successfully loaded by the device - - dynamic_features.has_extended_dynamic_state = + + dynamic_features.has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported(); - - dynamic_features.has_extended_dynamic_state_2 = + + dynamic_features.has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported(); - dynamic_features.has_extended_dynamic_state_2_logic_op = + dynamic_features.has_extended_dynamic_state_2_logic_op = device.IsExtExtendedDynamicState2ExtrasSupported(); dynamic_features.has_extended_dynamic_state_2_patch_control_points = false; - - dynamic_features.has_extended_dynamic_state_3_blend = + + dynamic_features.has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported(); - dynamic_features.has_extended_dynamic_state_3_enables = + dynamic_features.has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported(); dynamic_features.has_dynamic_state3_depth_clamp_enable = device.SupportsDynamicState3DepthClampEnable(); @@ -492,8 +492,8 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, device.SupportsDynamicState3LineStippleEnable(); // VIDS: Independent toggle (not affected by dyna_state levels) - dynamic_features.has_dynamic_vertex_input = - device.IsExtVertexInputDynamicStateSupported() && + dynamic_features.has_dynamic_vertex_input = + device.IsExtVertexInputDynamicStateSupported() && Settings::values.vertex_input_dynamic_state.GetValue(); dynamic_features.has_provoking_vertex = device.IsExtProvokingVertexSupported(); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 78337b3ebe..6fdd4e5fef 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1028,7 +1028,7 @@ void RasterizerVulkan::UpdateDynamicStates() { UpdateDepthBounds(regs); UpdateStencilFaces(regs); UpdateLineWidth(regs); - + // EDS1: CullMode, DepthCompare, FrontFace, StencilOp, DepthBoundsTest, DepthTest, DepthWrite, StencilTest if (device.IsExtExtendedDynamicStateSupported()) { UpdateCullMode(regs); @@ -1042,19 +1042,19 @@ void RasterizerVulkan::UpdateDynamicStates() { UpdateStencilTestEnable(regs); } } - + // EDS2: PrimitiveRestart, RasterizerDiscard, DepthBias enable/disable if (device.IsExtExtendedDynamicState2Supported()) { UpdatePrimitiveRestartEnable(regs); UpdateRasterizerDiscardEnable(regs); UpdateDepthBiasEnable(regs); } - + // EDS2 Extras: LogicOp operation selection if (device.IsExtExtendedDynamicState2ExtrasSupported()) { UpdateLogicOp(regs); } - + // EDS3 Enables: LogicOpEnable, DepthClamp, LineStipple, ConservativeRaster if (device.IsExtExtendedDynamicState3EnablesSupported()) { using namespace Tegra::Engines; @@ -1079,12 +1079,12 @@ void RasterizerVulkan::UpdateDynamicStates() { UpdateAlphaToCoverageEnable(regs); UpdateAlphaToOneEnable(regs); } - + // EDS3 Blending: ColorBlendEnable, ColorBlendEquation, ColorWriteMask if (device.IsExtExtendedDynamicState3BlendingSupported()) { UpdateBlending(regs); } - + // Vertex Input Dynamic State: Independent from EDS levels if (device.IsExtVertexInputDynamicStateSupported()) { if (auto* gp = pipeline_cache.CurrentGraphicsPipeline(); gp && gp->HasDynamicVertexInput()) { @@ -1121,7 +1121,7 @@ void RasterizerVulkan::HandleTransformFeedback() { UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) || regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation)); } -} +} void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchViewports()) { diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index f099db74cb..cacc68d02f 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1186,7 +1186,7 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst const VkImageSubresourceLayers dst_layers = MakeSubresourceLayers(&dst); const VkImageSubresourceLayers src_layers = MakeSubresourceLayers(&src); const bool is_msaa_to_msaa = is_src_msaa && is_dst_msaa; - + // NVIDIA 510+ and Intel crash on MSAA->MSAA blits (scaling operations) // Fall back to 3D helpers for MSAA scaling if (is_msaa_to_msaa && device.CantBlitMSAA()) { diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 6e55306079..f92be1837e 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -561,7 +561,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR is_blit_depth24_stencil8_supported); LOG_INFO(Render_Vulkan, " D32S8 hardware blit support: {}", is_blit_depth32_stencil8_supported); - + if (!is_blit_depth24_stencil8_supported && !is_blit_depth32_stencil8_supported) { LOG_WARNING(Render_Vulkan, "NVIDIA: Neither shader export nor hardware blits available for " @@ -622,7 +622,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } if (is_intel_windows) { - LOG_WARNING(Render_Vulkan, + LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA->MSAA image blits. " "MSAA scaling will use 3D helpers. MSAA resolves work normally."); cant_blit_msaa = true; @@ -646,7 +646,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR properties.properties.limits.maxVertexInputBindings = 32; } - const auto dyna_state = Settings::values.dyna_state.GetValue(); + const auto dyna_state = u32(Settings::values.dyna_state.GetValue()); // Base dynamic states (VIEWPORT, SCISSOR, DEPTH_BIAS, etc.) are ALWAYS active in vk_graphics_pipeline.cpp // This slider controls EXTENDED dynamic states with accumulative levels per Vulkan specs: @@ -654,36 +654,36 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR // Level 1 = Core + VK_EXT_extended_dynamic_state // Level 2 = Core + VK_EXT_extended_dynamic_state + VK_EXT_extended_dynamic_state2 // Level 3 = Core + VK_EXT_extended_dynamic_state + VK_EXT_extended_dynamic_state2 + VK_EXT_extended_dynamic_state3 - + switch (dyna_state) { - case Settings::ExtendedDynamicState::Disabled: + case 0: // Level 0: Disable all extended dynamic state extensions - RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, + RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); - RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, + RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); - RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, + RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); dynamic_state3_blending = false; dynamic_state3_enables = false; break; - case Settings::ExtendedDynamicState::EDS1: + case 1: // Level 1: Enable EDS1, disable EDS2 and EDS3 - RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, + RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); - RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, + RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); dynamic_state3_blending = false; dynamic_state3_enables = false; break; - case Settings::ExtendedDynamicState::EDS2: + case 2: // Level 2: Enable EDS1 + EDS2, disable EDS3 - RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, + RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); dynamic_state3_blending = false; dynamic_state3_enables = false; break; - case Settings::ExtendedDynamicState::EDS3: + case 3: default: // Level 3: Enable all (EDS1 + EDS2 + EDS3) break; @@ -1114,24 +1114,21 @@ bool Device::GetSuitability(bool requires_swapchain) { } // VK_DYNAMIC_STATE - + // Driver detection variables for workarounds in GetSuitability const VkDriverId driver_id = properties.driver.driverID; - // VK_EXT_extended_dynamic_state2 below this will appear drivers that need workarounds. - // VK_EXT_extended_dynamic_state3 below this will appear drivers that need workarounds. - // Samsung: Broken extendedDynamicState3ColorBlendEquation // Disable blend equation dynamic state, force static pipeline state - if (extensions.extended_dynamic_state3 && + if (extensions.extended_dynamic_state3 && (driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) { LOG_WARNING(Render_Vulkan, "Samsung: Disabling broken extendedDynamicState3ColorBlendEquation"); features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; } - + // Intel Windows < 27.20.100.0: Broken VertexInputDynamicState // Same for NVIDIA Proprietary < 580.119.02, unknown when VIDS was first NOT broken // Disable VertexInputDynamicState on old Intel Windows drivers @@ -1143,7 +1140,7 @@ bool Device::GetSuitability(bool requires_swapchain) { RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } } - + if (u32(Settings::values.dyna_state.GetValue()) == 0) { LOG_INFO(Render_Vulkan, "Extended Dynamic State disabled by user setting, clearing all EDS features"); features.extended_dynamic_state.extendedDynamicState = false; diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index a8a89aee89..e99098364b 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -849,7 +849,7 @@ public: /// Returns true if early fragment tests optimizations are available. bool SupportsEarlyFragmentTests() const { - return extensions.maintenance5 && + return extensions.maintenance5 && properties.maintenance5.earlyFragmentMultisampleCoverageAfterSampleCounting && properties.maintenance5.earlyFragmentSampleMaskTestBeforeSampleCounting; }