diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 6301b1aae4..a9a9529f30 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -263,6 +263,7 @@ GraphicsPipeline::GraphicsPipeline( std::ranges::copy(info->constant_buffer_used_sizes, uniform_buffer_sizes[stage].begin()); num_textures += Shader::NumDescriptors(info->texture_descriptors); } + fragment_has_color0_output = stage_infos[NUM_STAGES - 1].stores_frag_color[0]; auto func{[this, shader_notify, &render_pass_cache, &descriptor_pool, pipeline_statistics] { DescriptorLayoutBuilder builder{MakeBuilder(device, stage_infos)}; uses_push_descriptor = builder.CanUsePushDescriptor(); @@ -739,6 +740,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex); } + const bool supports_alpha_output = fragment_has_color0_output; const VkPipelineMultisampleStateCreateInfo multisample_ci{ .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pNext = nullptr, @@ -747,8 +749,10 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .sampleShadingEnable = Settings::values.sample_shading.GetValue() ? VK_TRUE : VK_FALSE, .minSampleShading = static_cast(Settings::values.sample_shading_fraction.GetValue()) / 100.0f, .pSampleMask = nullptr, - .alphaToCoverageEnable = key.state.alpha_to_coverage_enabled != 0 ? VK_TRUE : VK_FALSE, - .alphaToOneEnable = key.state.alpha_to_one_enabled != 0 ? VK_TRUE : VK_FALSE, + .alphaToCoverageEnable = + supports_alpha_output && key.state.alpha_to_coverage_enabled != 0 ? VK_TRUE : VK_FALSE, + .alphaToOneEnable = + supports_alpha_output && key.state.alpha_to_one_enabled != 0 ? VK_TRUE : VK_FALSE, }; const VkPipelineDepthStencilStateCreateInfo depth_stencil_ci{ .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index c8e89d60a4..80f44643e2 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -82,6 +82,13 @@ public: const std::array& infos); bool HasDynamicVertexInput() const noexcept { return key.state.dynamic_vertex_input; } + bool SupportsAlphaToCoverage() const noexcept { + return fragment_has_color0_output; + } + + bool SupportsAlphaToOne() const noexcept { + return fragment_has_color0_output; + } GraphicsPipeline& operator=(GraphicsPipeline&&) noexcept = delete; GraphicsPipeline(GraphicsPipeline&&) noexcept = delete; @@ -149,6 +156,7 @@ private: std::array enabled_uniform_buffer_masks{}; VideoCommon::UniformBufferSizes uniform_buffer_sizes{}; u32 num_textures{}; + bool fragment_has_color0_output{}; vk::DescriptorSetLayout descriptor_set_layout; DescriptorAllocator descriptor_allocator; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 1891983bbc..a12382fc05 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1443,9 +1443,11 @@ void RasterizerVulkan::UpdateAlphaToCoverageEnable(Tegra::Engines::Maxwell3D::Re if (!state_tracker.TouchAlphaToCoverageEnable()) { return; } - scheduler.Record([enable = regs.anti_alias_alpha_control.alpha_to_coverage]( - vk::CommandBuffer cmdbuf) { - cmdbuf.SetAlphaToCoverageEnableEXT(enable != 0); + GraphicsPipeline* const pipeline = pipeline_cache.CurrentGraphicsPipeline(); + const bool enable = pipeline != nullptr && pipeline->SupportsAlphaToCoverage() && + regs.anti_alias_alpha_control.alpha_to_coverage != 0; + scheduler.Record([enable](vk::CommandBuffer cmdbuf) { + cmdbuf.SetAlphaToCoverageEnableEXT(enable ? VK_TRUE : VK_FALSE); }); } @@ -1453,9 +1455,11 @@ void RasterizerVulkan::UpdateAlphaToOneEnable(Tegra::Engines::Maxwell3D::Regs& r if (!state_tracker.TouchAlphaToOneEnable()) { return; } - scheduler.Record([enable = regs.anti_alias_alpha_control.alpha_to_one]( - vk::CommandBuffer cmdbuf) { - cmdbuf.SetAlphaToOneEnableEXT(enable != 0); + GraphicsPipeline* const pipeline = pipeline_cache.CurrentGraphicsPipeline(); + const bool enable = pipeline != nullptr && pipeline->SupportsAlphaToOne() && + regs.anti_alias_alpha_control.alpha_to_one != 0; + scheduler.Record([enable](vk::CommandBuffer cmdbuf) { + cmdbuf.SetAlphaToOneEnableEXT(enable ? VK_TRUE : VK_FALSE); }); }