diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index ddd52e9426..48b7247061 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include "video_core/renderer_vulkan/vk_texture_cache.h" @@ -158,15 +159,18 @@ VkPipelineInputAssemblyStateCreateInfo GetPipelineInputAssemblyStateCreateInfo(c .primitiveRestartEnable = device.IsMoltenVK() ? VK_TRUE : VK_FALSE, }; } -constexpr VkPipelineViewportStateCreateInfo PIPELINE_VIEWPORT_STATE_CREATE_INFO{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .viewportCount = 1, - .pViewports = nullptr, - .scissorCount = 1, - .pScissors = nullptr, -}; +VkPipelineViewportStateCreateInfo GetPipelineViewportStateCreateInfo(const Device& device) { + const u32 viewport_count = device.GetViewportCount(); + return VkPipelineViewportStateCreateInfo{ + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .viewportCount = viewport_count, + .pViewports = nullptr, + .scissorCount = viewport_count, + .pScissors = nullptr, + }; +} constexpr VkPipelineRasterizationStateCreateInfo PIPELINE_RASTERIZATION_STATE_CREATE_INFO{ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pNext = nullptr, @@ -399,7 +403,7 @@ void UpdateTwoTexturesDescriptorSet(const Device& device, VkDescriptorSet descri device.GetLogical().UpdateDescriptorSets(write_descriptor_sets, nullptr); } -void BindBlitState(vk::CommandBuffer cmdbuf, const Region2D& dst_region) { +void BindBlitState(const Device& device, vk::CommandBuffer cmdbuf, const Region2D& dst_region) { const VkOffset2D offset{ .x = (std::min)(dst_region.start.x, dst_region.end.x), .y = (std::min)(dst_region.start.y, dst_region.end.y), @@ -421,13 +425,17 @@ void BindBlitState(vk::CommandBuffer cmdbuf, const Region2D& dst_region) { .offset = offset, .extent = extent, }; - cmdbuf.SetViewport(0, viewport); - cmdbuf.SetScissor(0, scissor); + const u32 viewport_count = device.GetViewportCount(); + const std::array viewports{viewport, viewport}; + const std::array scissors{scissor, scissor}; + cmdbuf.SetViewport(0, vk::Span(viewports.data(), viewport_count)); + cmdbuf.SetScissor(0, vk::Span(scissors.data(), viewport_count)); } -void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, const Region2D& dst_region, - const Region2D& src_region, const Extent3D& src_size = {1, 1, 1}) { - BindBlitState(cmdbuf, dst_region); +void BindBlitState(const Device& device, vk::CommandBuffer cmdbuf, VkPipelineLayout layout, + const Region2D& dst_region, const Region2D& src_region, + const Extent3D& src_size = {1, 1, 1}) { + BindBlitState(device, cmdbuf, dst_region); const float scale_x = static_cast(src_region.end.x - src_region.start.x) / static_cast(src_size.width); const float scale_y = static_cast(src_region.end.y - src_region.start.y) / @@ -696,7 +704,7 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, nullptr); - BindBlitState(cmdbuf, layout, dst_region, src_region, src_size); + BindBlitState(device, cmdbuf, layout, dst_region, src_region, src_size); cmdbuf.Draw(3, 1, 0, 0); cmdbuf.EndRenderPass(); }); @@ -728,7 +736,7 @@ void BlitImageHelper::BlitImpl(const Framebuffer* dst_framebuffer, cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, nullptr); - BindBlitState(cmdbuf, layout, dst_region, src_region); + BindBlitState(device, cmdbuf, layout, dst_region, src_region); cmdbuf.Draw(3, 1, 0, 0); }); scheduler.InvalidateState(); @@ -885,13 +893,13 @@ void BlitImageHelper::ClearColor(const Framebuffer* dst_framebuffer, u8 color_ma const VkPipelineLayout layout = *clear_color_pipeline_layout; scheduler.RequestRenderpass(dst_framebuffer); scheduler.Record( - [pipeline, layout, color_mask, clear_color, dst_region](vk::CommandBuffer cmdbuf) { + [pipeline, layout, color_mask, clear_color, dst_region, this](vk::CommandBuffer cmdbuf) { cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); const std::array blend_color = { (color_mask & 0x1) ? 1.0f : 0.0f, (color_mask & 0x2) ? 1.0f : 0.0f, (color_mask & 0x4) ? 1.0f : 0.0f, (color_mask & 0x8) ? 1.0f : 0.0f}; cmdbuf.SetBlendConstants(blend_color.data()); - BindBlitState(cmdbuf, dst_region); + BindBlitState(device, cmdbuf, dst_region); cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, clear_color); cmdbuf.Draw(3, 1, 0, 0); }); @@ -911,11 +919,11 @@ void BlitImageHelper::ClearDepthStencil(const Framebuffer* dst_framebuffer, bool const VkPipeline pipeline = FindOrEmplaceClearStencilPipeline(key); const VkPipelineLayout layout = *clear_color_pipeline_layout; scheduler.RequestRenderpass(dst_framebuffer); - scheduler.Record([pipeline, layout, clear_depth, dst_region](vk::CommandBuffer cmdbuf) { + scheduler.Record([pipeline, layout, clear_depth, dst_region, this](vk::CommandBuffer cmdbuf) { constexpr std::array blend_constants{0.0f, 0.0f, 0.0f, 0.0f}; cmdbuf.SetBlendConstants(blend_constants.data()); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - BindBlitState(cmdbuf, dst_region); + BindBlitState(device, cmdbuf, dst_region); cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, clear_depth); cmdbuf.Draw(3, 1, 0, 0); }); @@ -1176,8 +1184,11 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, nullptr); - cmdbuf.SetViewport(0, viewport); - cmdbuf.SetScissor(0, scissor); + const u32 viewport_count = device.GetViewportCount(); + const std::array viewports{viewport, viewport}; + const std::array scissors{scissor, scissor}; + cmdbuf.SetViewport(0, vk::Span(viewports.data(), viewport_count)); + cmdbuf.SetScissor(0, vk::Span(scissors.data(), viewport_count)); cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); cmdbuf.Draw(3, 1, 0, 0); }); @@ -1222,8 +1233,11 @@ void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, nullptr); - cmdbuf.SetViewport(0, viewport); - cmdbuf.SetScissor(0, scissor); + const u32 viewport_count = device.GetViewportCount(); + const std::array viewports{viewport, viewport}; + const std::array scissors{scissor, scissor}; + cmdbuf.SetViewport(0, vk::Span(viewports.data(), viewport_count)); + cmdbuf.SetScissor(0, vk::Span(scissors.data(), viewport_count)); cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); cmdbuf.Draw(3, 1, 0, 0); }); @@ -1261,6 +1275,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKe .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f}, }; const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); + const VkPipelineViewportStateCreateInfo viewport_ci = GetPipelineViewportStateCreateInfo(device); blit_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .pNext = nullptr, @@ -1270,7 +1285,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKe .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .pInputAssemblyState = &input_assembly_ci, .pTessellationState = nullptr, - .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pViewportState = &viewport_ci, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pDepthStencilState = nullptr, @@ -1293,6 +1308,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip blit_depth_stencil_keys.push_back(key); const std::array stages = MakeStages(*full_screen_vert, *blit_depth_stencil_frag); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); + const VkPipelineViewportStateCreateInfo viewport_ci = GetPipelineViewportStateCreateInfo(device); blit_depth_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .pNext = nullptr, @@ -1302,7 +1318,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .pInputAssemblyState = &input_assembly_ci, .pTessellationState = nullptr, - .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pViewportState = &viewport_ci, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, @@ -1346,6 +1362,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipel .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f}, }; const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); + const VkPipelineViewportStateCreateInfo viewport_ci = GetPipelineViewportStateCreateInfo(device); clear_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .pNext = nullptr, @@ -1355,7 +1372,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipel .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .pInputAssemblyState = &input_assembly_ci, .pTessellationState = nullptr, - .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pViewportState = &viewport_ci, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, @@ -1402,6 +1419,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline( .maxDepthBounds = 0.0f, }; const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); + const VkPipelineViewportStateCreateInfo viewport_ci = GetPipelineViewportStateCreateInfo(device); clear_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .pNext = nullptr, @@ -1411,7 +1429,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline( .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .pInputAssemblyState = &input_assembly_ci, .pTessellationState = nullptr, - .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pViewportState = &viewport_ci, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pDepthStencilState = &depth_stencil_ci, @@ -1526,6 +1544,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceBlitDepthPipeline(VkRenderPass renderpa blit_depth_keys.push_back(renderpass); const std::array stages = MakeStages(*full_screen_vert, *blit_depth_frag); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); + const VkPipelineViewportStateCreateInfo viewport_ci = GetPipelineViewportStateCreateInfo(device); blit_depth_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .pNext = nullptr, @@ -1535,7 +1554,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceBlitDepthPipeline(VkRenderPass renderpa .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .pInputAssemblyState = &input_assembly_ci, .pTessellationState = nullptr, - .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pViewportState = &viewport_ci, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pDepthStencilState = &PIPELINE_DEPTH_ONLY_STATE_CREATE_INFO, @@ -1563,6 +1582,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceResolveDepthStencilPipeline(VkRenderPas MakeStages(*full_screen_vert, resolve_stencil ? *blit_depth_stencil_msaa_frag : *blit_depth_msaa_frag); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); + const VkPipelineViewportStateCreateInfo viewport_ci = GetPipelineViewportStateCreateInfo(device); pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .pNext = nullptr, @@ -1572,7 +1592,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceResolveDepthStencilPipeline(VkRenderPas .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .pInputAssemblyState = &input_assembly_ci, .pTessellationState = nullptr, - .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pViewportState = &viewport_ci, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pDepthStencilState = resolve_stencil ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO @@ -1796,6 +1816,7 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass ren } const std::array stages = MakeStages(*full_screen_vert, *module); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); + const VkPipelineViewportStateCreateInfo viewport_ci = GetPipelineViewportStateCreateInfo(device); pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .pNext = nullptr, @@ -1805,7 +1826,7 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass ren .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .pInputAssemblyState = &input_assembly_ci, .pTessellationState = nullptr, - .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pViewportState = &viewport_ci, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pDepthStencilState = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr, @@ -1839,6 +1860,7 @@ void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass rende is_target_depth ? *convert_float_to_depth_frag : *convert_depth_to_float_frag; const std::array stages = MakeStages(*full_screen_vert, frag_shader); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); + const VkPipelineViewportStateCreateInfo viewport_ci = GetPipelineViewportStateCreateInfo(device); pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .pNext = nullptr, @@ -1848,7 +1870,7 @@ void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass rende .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .pInputAssemblyState = &input_assembly_ci, .pTessellationState = nullptr, - .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pViewportState = &viewport_ci, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pDepthStencilState = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr, diff --git a/src/video_core/renderer_vulkan/present/fsr.cpp b/src/video_core/renderer_vulkan/present/fsr.cpp index 894fb144f0..ef6766e24b 100644 --- a/src/video_core/renderer_vulkan/present/fsr.cpp +++ b/src/video_core/renderer_vulkan/present/fsr.cpp @@ -183,10 +183,10 @@ VkImageView FSR::Draw(const Device& device, Scheduler& scheduler, size_t image_i UpdateDescriptorSets(device, source_image_view, image_index); scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([=](vk::CommandBuffer cmdbuf) { + scheduler.Record([=, &device](vk::CommandBuffer cmdbuf) { TransitionImageLayout(cmdbuf, source_image, VK_IMAGE_LAYOUT_GENERAL); TransitionImageLayout(cmdbuf, easu_image, VK_IMAGE_LAYOUT_GENERAL); - BeginRenderPass(cmdbuf, renderpass, easu_framebuffer, extent); + BeginRenderPass(device, cmdbuf, renderpass, easu_framebuffer, extent); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, easu_pipeline); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, easu_descriptor_set, {}); @@ -196,7 +196,7 @@ VkImageView FSR::Draw(const Device& device, Scheduler& scheduler, size_t image_i TransitionImageLayout(cmdbuf, easu_image, VK_IMAGE_LAYOUT_GENERAL); TransitionImageLayout(cmdbuf, rcas_image, VK_IMAGE_LAYOUT_GENERAL); - BeginRenderPass(cmdbuf, renderpass, rcas_framebuffer, extent); + BeginRenderPass(device, cmdbuf, renderpass, rcas_framebuffer, extent); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, rcas_pipeline); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, rcas_descriptor_set, {}); diff --git a/src/video_core/renderer_vulkan/present/fxaa.cpp b/src/video_core/renderer_vulkan/present/fxaa.cpp index 62f79d490c..b77c3d6fef 100644 --- a/src/video_core/renderer_vulkan/present/fxaa.cpp +++ b/src/video_core/renderer_vulkan/present/fxaa.cpp @@ -129,10 +129,10 @@ void FXAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index, UpdateDescriptorSets(device, *inout_image_view, image_index); scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([=](vk::CommandBuffer cmdbuf) { + scheduler.Record([=, &device](vk::CommandBuffer cmdbuf) { TransitionImageLayout(cmdbuf, input_image, VK_IMAGE_LAYOUT_GENERAL); TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL); - BeginRenderPass(cmdbuf, renderpass, framebuffer, extent); + BeginRenderPass(device, cmdbuf, renderpass, framebuffer, extent); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, {}); cmdbuf.Draw(3, 1, 0, 0); diff --git a/src/video_core/renderer_vulkan/present/sgsr.cpp b/src/video_core/renderer_vulkan/present/sgsr.cpp index fa37225e43..1816907719 100644 --- a/src/video_core/renderer_vulkan/present/sgsr.cpp +++ b/src/video_core/renderer_vulkan/present/sgsr.cpp @@ -129,10 +129,10 @@ VkImageView SGSR::Draw(const Device& device, Scheduler& scheduler, size_t image_ UpdateDescriptorSets(device, source_image_view, image_index); scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([=](vk::CommandBuffer cmdbuf) { + scheduler.Record([=, &device](vk::CommandBuffer cmdbuf) { TransitionImageLayout(cmdbuf, source_image, VK_IMAGE_LAYOUT_GENERAL); TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL); - BeginRenderPass(cmdbuf, renderpass, framebuffer, extent); + BeginRenderPass(device, cmdbuf, renderpass, framebuffer, extent); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, {}); cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, viewport_con); diff --git a/src/video_core/renderer_vulkan/present/smaa.cpp b/src/video_core/renderer_vulkan/present/smaa.cpp index 28b0427fa0..54d5c55ddd 100644 --- a/src/video_core/renderer_vulkan/present/smaa.cpp +++ b/src/video_core/renderer_vulkan/present/smaa.cpp @@ -237,10 +237,10 @@ void SMAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index, UpdateDescriptorSets(device, *inout_image_view, image_index); scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([=, this](vk::CommandBuffer cmdbuf) { + scheduler.Record([=, this, &device](vk::CommandBuffer cmdbuf) { TransitionImageLayout(cmdbuf, input_image, VK_IMAGE_LAYOUT_GENERAL); TransitionImageLayout(cmdbuf, edges_image, VK_IMAGE_LAYOUT_GENERAL); - BeginRenderPass(cmdbuf, *m_renderpasses[EdgeDetection], edge_detection_framebuffer, + BeginRenderPass(device, cmdbuf, *m_renderpasses[EdgeDetection], edge_detection_framebuffer, m_extent); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelines[EdgeDetection]); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, @@ -251,7 +251,7 @@ void SMAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index, TransitionImageLayout(cmdbuf, edges_image, VK_IMAGE_LAYOUT_GENERAL); TransitionImageLayout(cmdbuf, blend_image, VK_IMAGE_LAYOUT_GENERAL); - BeginRenderPass(cmdbuf, *m_renderpasses[BlendingWeightCalculation], + BeginRenderPass(device, cmdbuf, *m_renderpasses[BlendingWeightCalculation], blending_weight_calculation_framebuffer, m_extent); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelines[BlendingWeightCalculation]); @@ -263,7 +263,7 @@ void SMAA::Draw(const Device& device, Scheduler& scheduler, size_t image_index, TransitionImageLayout(cmdbuf, blend_image, VK_IMAGE_LAYOUT_GENERAL); TransitionImageLayout(cmdbuf, output_image, VK_IMAGE_LAYOUT_GENERAL); - BeginRenderPass(cmdbuf, *m_renderpasses[NeighborhoodBlending], + BeginRenderPass(device, cmdbuf, *m_renderpasses[NeighborhoodBlending], neighborhood_blending_framebuffer, m_extent); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelines[NeighborhoodBlending]); cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, diff --git a/src/video_core/renderer_vulkan/present/util.cpp b/src/video_core/renderer_vulkan/present/util.cpp index 2ea7870f01..0dc108f9d9 100644 --- a/src/video_core/renderer_vulkan/present/util.cpp +++ b/src/video_core/renderer_vulkan/present/util.cpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/assert.h" +#include #include #include #include "video_core/renderer_vulkan/present/util.h" @@ -438,14 +439,14 @@ static vk::Pipeline CreateWrappedPipelineImpl( .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, .primitiveRestartEnable = device.IsMoltenVK() ? VK_TRUE : VK_FALSE, }; - - constexpr VkPipelineViewportStateCreateInfo viewport_state_ci{ + const u32 viewport_count = device.GetViewportCount(); + const VkPipelineViewportStateCreateInfo viewport_state_ci{ .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, .pNext = nullptr, .flags = 0, - .viewportCount = 1, + .viewportCount = viewport_count, .pViewports = nullptr, - .scissorCount = 1, + .scissorCount = viewport_count, .pScissors = nullptr, }; @@ -699,8 +700,8 @@ void ClearColorImage(vk::CommandBuffer& cmdbuf, VkImage image) { cmdbuf.ClearColorImage(image, VK_IMAGE_LAYOUT_GENERAL, {}, subresources); } -void BeginRenderPass(vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, VkFramebuffer framebuffer, - VkExtent2D extent) { +void BeginRenderPass(const Device& device, vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, + VkFramebuffer framebuffer, VkExtent2D extent) { const VkRenderPassBeginInfo renderpass_bi{ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, .pNext = nullptr, @@ -727,8 +728,11 @@ void BeginRenderPass(vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, VkFram .offset = {0, 0}, .extent = extent, }; - cmdbuf.SetViewport(0, viewport); - cmdbuf.SetScissor(0, scissor); + const u32 viewport_count = device.GetViewportCount(); + const std::array viewports{viewport, viewport}; + const std::array scissors{scissor, scissor}; + cmdbuf.SetViewport(0, vk::Span(viewports.data(), viewport_count)); + cmdbuf.SetScissor(0, vk::Span(scissors.data(), viewport_count)); } } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/util.h b/src/video_core/renderer_vulkan/present/util.h index ecc263286d..4ceaf374a3 100644 --- a/src/video_core/renderer_vulkan/present/util.h +++ b/src/video_core/renderer_vulkan/present/util.h @@ -65,7 +65,7 @@ vk::Sampler CreateBilinearSampler(const Device& device); vk::Sampler CreateNearestNeighborSampler(const Device& device); vk::Sampler CreateCubicSampler(const Device& device, VkCubicFilterWeightsQCOM qcom_weights); -void BeginRenderPass(vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, VkFramebuffer framebuffer, - VkExtent2D extent); +void BeginRenderPass(const Device& device, vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, + VkFramebuffer framebuffer, VkExtent2D extent); } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/present/window_adapt_pass.cpp b/src/video_core/renderer_vulkan/present/window_adapt_pass.cpp index 549b0660c1..257df24c81 100644 --- a/src/video_core/renderer_vulkan/present/window_adapt_pass.cpp +++ b/src/video_core/renderer_vulkan/present/window_adapt_pass.cpp @@ -69,7 +69,7 @@ void WindowAdaptPass::Draw(const Device& device, RasterizerVulkan& rasterizer, S layer_it++; } - scheduler.Record([=](vk::CommandBuffer cmdbuf) { + scheduler.Record([=, &device](vk::CommandBuffer cmdbuf) { const f32 bg_red = Settings::values.bg_red.GetValue() / 255.0f; const f32 bg_green = Settings::values.bg_green.GetValue() / 255.0f; const f32 bg_blue = Settings::values.bg_blue.GetValue() / 255.0f; @@ -91,7 +91,7 @@ void WindowAdaptPass::Draw(const Device& device, RasterizerVulkan& rasterizer, S .layerCount = 1, }; - BeginRenderPass(cmdbuf, renderpass, host_framebuffer, render_area); + BeginRenderPass(device, cmdbuf, renderpass, host_framebuffer, render_area); cmdbuf.ClearAttachments({clear_attachment}, {clear_rect}); for (size_t i = 0; i < layer_count; i++) { diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index fb3a9c4e7a..34023eb2a9 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -469,6 +469,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP; + const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; if (!is_suitable) LOG_WARNING(Render_Vulkan, "Unsuitable driver - continuing anyways"); @@ -661,6 +662,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR properties.properties.limits.maxVertexInputBindings = 32; } + if (is_arm && SupportsMultiViewport()) { + LOG_WARNING(Render_Vulkan, "ARM driver requires setting multiple viewports on command buffer reuse"); + requires_setting_multi_viewports_on_cmdbuf_reuse = true; + } + const auto dyna_state = Settings::values.dyna_state.GetValue(); switch (dyna_state) { case Settings::ExtendedDynamicState::Disabled: diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index c53bd6443e..cab7274fbf 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -1000,6 +1000,10 @@ FN_MAX_LIMIT_LIST return features2.features.multiViewport; } + u32 GetViewportCount() const noexcept { + return requires_setting_multi_viewports_on_cmdbuf_reuse ? 2U : 1U; + } + /// Returns true if the device supports VK_KHR_maintenance1. bool IsKhrMaintenance1Supported() const { return extensions.maintenance1; @@ -1220,6 +1224,7 @@ private: bool has_radeon_gpu_profiler{}; ///< Has Radeon GPU Profiler attached. bool supports_d24_depth{}; ///< Supports D24 depth buffers. bool must_emulate_scaled_formats{}; ///< Requires scaled vertex format emulation + bool requires_setting_multi_viewports_on_cmdbuf_reuse{}; ///< ARM workaround to always set 2+ viewports. bool dynamic_state3_blending{}; ///< Has blending features of dynamic_state3. bool dynamic_state3_enables{}; ///< Has at least one enable feature of dynamic_state3. bool dynamic_state3_depth_clamp_enable{};