aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan/blit_image.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_vulkan/blit_image.cpp')
-rw-r--r--src/video_core/renderer_vulkan/blit_image.cpp788
1 files changed, 553 insertions, 235 deletions
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp
index 89083d29fb..f9d9460c37 100644
--- a/src/video_core/renderer_vulkan/blit_image.cpp
+++ b/src/video_core/renderer_vulkan/blit_image.cpp
@@ -12,6 +12,7 @@
#include "common/settings.h"
#include "video_core/host_shaders/blit_color_float_frag_spv.h"
#include "video_core/host_shaders/blit_color_msaa_frag_spv.h"
+#include "video_core/host_shaders/blit_depth_frag_spv.h"
#include "video_core/host_shaders/blit_depth_msaa_frag_spv.h"
#include "video_core/host_shaders/blit_depth_stencil_msaa_frag_spv.h"
#include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h"
@@ -21,7 +22,15 @@
#include "video_core/host_shaders/convert_depth_to_float_frag_spv.h"
#include "video_core/host_shaders/convert_float_to_depth_frag_spv.h"
#include "video_core/host_shaders/convert_msaa_to_non_msaa_frag_spv.h"
+#include "video_core/host_shaders/convert_msaa_to_non_msaa_depth_frag_spv.h"
+#include "video_core/host_shaders/convert_msaa_to_non_msaa_depth_stencil_frag_spv.h"
+#include "video_core/host_shaders/convert_msaa_to_non_msaa_sint_frag_spv.h"
+#include "video_core/host_shaders/convert_msaa_to_non_msaa_uint_frag_spv.h"
#include "video_core/host_shaders/convert_non_msaa_to_msaa_frag_spv.h"
+#include "video_core/host_shaders/convert_non_msaa_to_msaa_sint_frag_spv.h"
+#include "video_core/host_shaders/convert_non_msaa_to_msaa_uint_frag_spv.h"
+#include "video_core/host_shaders/convert_non_msaa_to_msaa_depth_frag_spv.h"
+#include "video_core/host_shaders/convert_non_msaa_to_msaa_depth_stencil_frag_spv.h"
#include "video_core/host_shaders/convert_s8d24_to_abgr8_frag_spv.h"
#include "video_core/host_shaders/full_screen_triangle_vert_spv.h"
#include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h"
@@ -518,8 +527,19 @@ void RecordShaderReadBarrier(Scheduler& scheduler, const ImageView& image_view)
}
}
+[[nodiscard]] MSAACopyFormatClass FormatClass(VideoCore::Surface::PixelFormat format) {
+ if (!VideoCore::Surface::IsPixelFormatInteger(format)) {
+ return MSAACopyFormatClass::Float;
+ }
+ if (VideoCore::Surface::IsPixelFormatSignedInteger(format)) {
+ return MSAACopyFormatClass::SignedInteger;
+ }
+ return MSAACopyFormatClass::UnsignedInteger;
+}
+
[[nodiscard]] vk::ImageView MakeMSAACopyView(const vk::Device& device, VkImage image,
- VkFormat format, u32 base_level) {
+ VkFormat format, u32 base_level, u32 base_layer,
+ VkImageAspectFlags aspect_mask) {
return device.CreateImageView(VkImageViewCreateInfo{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = nullptr,
@@ -534,10 +554,10 @@ void RecordShaderReadBarrier(Scheduler& scheduler, const ImageView& image_view)
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
},
.subresourceRange{
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .aspectMask = aspect_mask,
.baseMipLevel = base_level,
.levelCount = 1,
- .baseArrayLayer = 0,
+ .baseArrayLayer = base_layer,
.layerCount = 1,
},
});
@@ -586,12 +606,17 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
msaa_copy_pipeline_layout(device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo(
one_texture_set_layout.address(),
PUSH_CONSTANT_RANGE<VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(MSAACopyPushConstants)>))),
+ msaa_copy_depth_stencil_pipeline_layout(
+ device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo(
+ two_textures_set_layout.address(),
+ PUSH_CONSTANT_RANGE<VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(MSAACopyPushConstants)>))),
full_screen_vert(BuildShader(device, FULL_SCREEN_TRIANGLE_VERT_SPV)),
blit_color_to_color_frag(BuildShader(device, BLIT_COLOR_FLOAT_FRAG_SPV)),
blit_color_msaa_frag(BuildShader(device, BLIT_COLOR_MSAA_FRAG_SPV)),
blit_depth_stencil_frag(device.IsExtShaderStencilExportSupported()
? BuildShader(device, VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV)
: vk::ShaderModule{}),
+ blit_depth_frag(BuildShader(device, BLIT_DEPTH_FRAG_SPV)),
blit_depth_msaa_frag(BuildShader(device, BLIT_DEPTH_MSAA_FRAG_SPV)),
blit_depth_stencil_msaa_frag(device.IsExtShaderStencilExportSupported()
? BuildShader(device, BLIT_DEPTH_STENCIL_MSAA_FRAG_SPV)
@@ -609,7 +634,25 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)),
convert_s8d24_to_abgr8_frag(BuildShader(device, CONVERT_S8D24_TO_ABGR8_FRAG_SPV)),
convert_msaa_to_non_msaa_frag(BuildShader(device, CONVERT_MSAA_TO_NON_MSAA_FRAG_SPV)),
+ convert_msaa_to_non_msaa_sint_frag(
+ BuildShader(device, CONVERT_MSAA_TO_NON_MSAA_SINT_FRAG_SPV)),
+ convert_msaa_to_non_msaa_uint_frag(
+ BuildShader(device, CONVERT_MSAA_TO_NON_MSAA_UINT_FRAG_SPV)),
+ convert_msaa_to_non_msaa_depth_frag(
+ BuildShader(device, CONVERT_MSAA_TO_NON_MSAA_DEPTH_FRAG_SPV)),
+ convert_msaa_to_non_msaa_depth_stencil_frag(
+ BuildShader(device, CONVERT_MSAA_TO_NON_MSAA_DEPTH_STENCIL_FRAG_SPV)),
convert_non_msaa_to_msaa_frag(BuildShader(device, CONVERT_NON_MSAA_TO_MSAA_FRAG_SPV)),
+ convert_non_msaa_to_msaa_sint_frag(
+ BuildShader(device, CONVERT_NON_MSAA_TO_MSAA_SINT_FRAG_SPV)),
+ convert_non_msaa_to_msaa_uint_frag(
+ BuildShader(device, CONVERT_NON_MSAA_TO_MSAA_UINT_FRAG_SPV)),
+ convert_non_msaa_to_msaa_depth_frag(
+ BuildShader(device, CONVERT_NON_MSAA_TO_MSAA_DEPTH_FRAG_SPV)),
+ convert_non_msaa_to_msaa_depth_stencil_frag(
+ device.IsExtShaderStencilExportSupported()
+ ? BuildShader(device, CONVERT_NON_MSAA_TO_MSAA_DEPTH_STENCIL_FRAG_SPV)
+ : vk::ShaderModule{}),
linear_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_LINEAR>)),
nearest_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_NEAREST>)) {}
@@ -624,24 +667,13 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, const ImageV
.renderpass = dst_framebuffer->RenderPass(),
.operation = operation,
};
- const VkPipelineLayout layout = *one_texture_pipeline_layout;
- const VkSampler sampler = is_linear ? *linear_sampler : *nearest_sampler;
- const VkPipeline pipeline = FindOrEmplaceColorPipeline(key);
- const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D);
-
- RecordShaderReadBarrier(scheduler, src_image_view);
- scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([this, dst_region, src_region, pipeline, layout, sampler,
- src_view](vk::CommandBuffer cmdbuf) {
- const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
- UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view);
- 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);
- cmdbuf.Draw(3, 1, 0, 0);
- });
- scheduler.InvalidateState();
+ VkSampler sampler = *nearest_sampler;
+ if (is_linear) {
+ sampler = *linear_sampler;
+ }
+ BlitImpl(dst_framebuffer, src_image_view, dst_region, src_region,
+ FindOrEmplaceColorPipeline(key), sampler,
+ src_image_view.Handle(Shader::TextureType::Color2D), VK_NULL_HANDLE, false);
}
void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView src_image_view,
@@ -670,24 +702,29 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView
});
}
-void BlitImageHelper::BlitColorMSAA(const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view, const Region2D& dst_region,
- const Region2D& src_region) {
- const BlitMSAAPipelineKey key{
- .renderpass = dst_framebuffer->RenderPass(),
- .samples = dst_framebuffer->Samples(),
- };
- const VkPipelineLayout layout = *one_texture_pipeline_layout;
- const VkSampler sampler = *nearest_sampler;
- const VkPipeline pipeline = FindOrEmplaceBlitColorMSAAPipeline(key);
- const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D);
+void BlitImageHelper::BlitImpl(const Framebuffer* dst_framebuffer,
+ const ImageView& src_image_view, const Region2D& dst_region,
+ const Region2D& src_region, VkPipeline pipeline, VkSampler sampler,
+ VkImageView src_view, VkImageView src_stencil_view,
+ bool blit_stencil) {
+ VkPipelineLayout layout = *one_texture_pipeline_layout;
+ if (blit_stencil) {
+ layout = *two_textures_pipeline_layout;
+ }
RecordShaderReadBarrier(scheduler, src_image_view);
scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([this, dst_region, src_region, pipeline, layout, sampler,
- src_view](vk::CommandBuffer cmdbuf) {
- const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
- UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view);
+ scheduler.Record([this, dst_region, src_region, pipeline, layout, sampler, src_view,
+ src_stencil_view, blit_stencil](vk::CommandBuffer cmdbuf) {
+ VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
+ if (blit_stencil) {
+ descriptor_set = two_textures_descriptor_allocator.Commit();
+ UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_view,
+ src_stencil_view);
+ } else {
+ descriptor_set = one_texture_descriptor_allocator.Commit();
+ UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view);
+ }
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
nullptr);
@@ -697,41 +734,56 @@ void BlitImageHelper::BlitColorMSAA(const Framebuffer* dst_framebuffer,
scheduler.InvalidateState();
}
+void BlitImageHelper::BlitColorMSAA(const Framebuffer* dst_framebuffer,
+ const ImageView& src_image_view, const Region2D& dst_region,
+ const Region2D& src_region) {
+ const BlitMSAAPipelineKey key{
+ .renderpass = dst_framebuffer->RenderPass(),
+ .samples = dst_framebuffer->Samples(),
+ };
+ BlitImpl(dst_framebuffer, src_image_view, dst_region, src_region,
+ FindOrEmplaceBlitColorMSAAPipeline(key), *nearest_sampler,
+ src_image_view.Handle(Shader::TextureType::Color2D), VK_NULL_HANDLE, false);
+}
+
+void BlitImageHelper::BlitDepthStencilMSAA(const Framebuffer* dst_framebuffer,
+ ImageView& src_image_view, const Region2D& dst_region,
+ const Region2D& src_region) {
+ const bool blit_stencil =
+ dst_framebuffer->HasAspectStencilBit() && device.IsExtShaderStencilExportSupported();
+ const BlitMSAAPipelineKey key{
+ .renderpass = dst_framebuffer->RenderPass(),
+ .samples = dst_framebuffer->Samples(),
+ };
+ VkImageView src_stencil_view = VK_NULL_HANDLE;
+ if (blit_stencil) {
+ src_stencil_view = src_image_view.StencilView();
+ }
+ BlitImpl(dst_framebuffer, src_image_view, dst_region, src_region,
+ FindOrEmplaceBlitDepthStencilMSAAPipeline(key, blit_stencil), *nearest_sampler,
+ src_image_view.DepthView(), src_stencil_view, blit_stencil);
+}
+
+void BlitImageHelper::BlitDepth(const Framebuffer* dst_framebuffer, ImageView& src_image_view,
+ const Region2D& dst_region, const Region2D& src_region) {
+ BlitImpl(dst_framebuffer, src_image_view, dst_region, src_region,
+ FindOrEmplaceBlitDepthPipeline(dst_framebuffer->RenderPass()), *nearest_sampler,
+ src_image_view.DepthView(), VK_NULL_HANDLE, false);
+}
+
void BlitImageHelper::ResolveDepthStencil(const Framebuffer* dst_framebuffer,
ImageView& src_image_view, const Region2D& dst_region,
const Region2D& src_region) {
const bool resolve_stencil =
dst_framebuffer->HasAspectStencilBit() && device.IsExtShaderStencilExportSupported();
- const VkPipeline pipeline =
- FindOrEmplaceResolveDepthStencilPipeline(dst_framebuffer->RenderPass(), resolve_stencil);
- const VkPipelineLayout layout =
- resolve_stencil ? *two_textures_pipeline_layout : *one_texture_pipeline_layout;
- const VkSampler sampler = *nearest_sampler;
- const VkImageView src_depth_view = src_image_view.DepthView();
- const VkImageView src_stencil_view =
- resolve_stencil ? src_image_view.StencilView() : VK_NULL_HANDLE;
-
- RecordShaderReadBarrier(scheduler, src_image_view);
- scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([this, dst_region, src_region, pipeline, layout, sampler, src_depth_view,
- src_stencil_view, resolve_stencil](vk::CommandBuffer cmdbuf) {
- if (resolve_stencil) {
- const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit();
- UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view,
- src_stencil_view);
- cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
- nullptr);
- } else {
- const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
- UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_depth_view);
- cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
- nullptr);
- }
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
- BindBlitState(cmdbuf, layout, dst_region, src_region);
- cmdbuf.Draw(3, 1, 0, 0);
- });
- scheduler.InvalidateState();
+ VkImageView src_stencil_view = VK_NULL_HANDLE;
+ if (resolve_stencil) {
+ src_stencil_view = src_image_view.StencilView();
+ }
+ BlitImpl(dst_framebuffer, src_image_view, dst_region, src_region,
+ FindOrEmplaceResolveDepthStencilPipeline(dst_framebuffer->RenderPass(),
+ resolve_stencil),
+ *nearest_sampler, src_image_view.DepthView(), src_stencil_view, resolve_stencil);
}
void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
@@ -739,35 +791,23 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
const Region2D& dst_region, const Region2D& src_region,
Tegra::Engines::Fermi2D::Filter filter,
Tegra::Engines::Fermi2D::Operation operation) {
- if (!device.IsExtShaderStencilExportSupported()) {
- return;
- }
ASSERT(filter == Tegra::Engines::Fermi2D::Filter::Point);
ASSERT(operation == Tegra::Engines::Fermi2D::Operation::SrcCopy);
+ const bool blit_stencil = device.IsExtShaderStencilExportSupported();
const BlitImagePipelineKey key{
.renderpass = dst_framebuffer->RenderPass(),
.operation = operation,
};
- const VkPipelineLayout layout = *two_textures_pipeline_layout;
- const VkSampler sampler = *nearest_sampler;
- const VkPipeline pipeline = FindOrEmplaceDepthStencilPipeline(key);
- const VkImageView src_depth_view = src_image_view.DepthView();
- const VkImageView src_stencil_view = src_image_view.StencilView();
-
- RecordShaderReadBarrier(scheduler, src_image_view);
- scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([dst_region, src_region, pipeline, layout, sampler, src_depth_view,
- src_stencil_view, this](vk::CommandBuffer cmdbuf) {
- const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit();
- UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view,
- src_stencil_view);
- 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);
- cmdbuf.Draw(3, 1, 0, 0);
- });
- scheduler.InvalidateState();
+ VkPipeline pipeline{};
+ VkImageView src_stencil_view = VK_NULL_HANDLE;
+ if (blit_stencil) {
+ pipeline = FindOrEmplaceDepthStencilPipeline(key);
+ src_stencil_view = src_image_view.StencilView();
+ } else {
+ pipeline = FindOrEmplaceBlitDepthPipeline(key.renderpass);
+ }
+ BlitImpl(dst_framebuffer, src_image_view, dst_region, src_region, pipeline, *nearest_sampler,
+ src_image_view.DepthView(), src_stencil_view, blit_stencil);
}
void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer,
@@ -882,19 +922,183 @@ void BlitImageHelper::ClearDepthStencil(const Framebuffer* dst_framebuffer, bool
scheduler.InvalidateState();
}
+void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
+ VkPipelineLayout layout, VkImage dst_image,
+ VkFormat dst_vk_format, VkImage src_image,
+ VkFormat src_vk_format, s32 scale_x, s32 scale_y,
+ std::span<const VideoCommon::ImageCopy> copies,
+ const MSAACopyAspectInfo& aspect_info, bool copy_stencil) {
+ while (!msaa_copy_resources.empty() && scheduler.IsFree(msaa_copy_resources.front().tick)) {
+ msaa_copy_resources.pop_front();
+ }
+ const VkSampler sampler = *nearest_sampler;
+ for (const VideoCommon::ImageCopy& copy : copies) {
+ const s32 num_layers = (std::min)(copy.src_subresource.num_layers,
+ copy.dst_subresource.num_layers);
+ for (s32 layer = 0; layer < num_layers; ++layer) {
+ const u32 src_level = static_cast<u32>(copy.src_subresource.base_level);
+ const u32 src_layer = static_cast<u32>(copy.src_subresource.base_layer + layer);
+ vk::ImageView src_view =
+ MakeMSAACopyView(device.GetLogical(), src_image, src_vk_format, src_level,
+ src_layer, aspect_info.src_view_aspect);
+ vk::ImageView src_stencil_view;
+ if (copy_stencil) {
+ src_stencil_view =
+ MakeMSAACopyView(device.GetLogical(), src_image, src_vk_format, src_level,
+ src_layer, VK_IMAGE_ASPECT_STENCIL_BIT);
+ }
+ vk::ImageView dst_view =
+ MakeMSAACopyView(device.GetLogical(), dst_image, dst_vk_format,
+ static_cast<u32>(copy.dst_subresource.base_level),
+ static_cast<u32>(copy.dst_subresource.base_layer + layer),
+ aspect_info.attachment_aspect);
+ const VkOffset2D dst_offset{copy.dst_offset.x, copy.dst_offset.y};
+ const VkExtent2D dst_extent{copy.extent.width, copy.extent.height};
+ const VkRect2D render_area{
+ .offset = dst_offset,
+ .extent = dst_extent,
+ };
+ vk::Framebuffer framebuffer = device.GetLogical().CreateFramebuffer(VkFramebufferCreateInfo{
+ .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .renderPass = renderpass,
+ .attachmentCount = 1,
+ .pAttachments = dst_view.address(),
+ .width = static_cast<u32>(dst_offset.x) + dst_extent.width,
+ .height = static_cast<u32>(dst_offset.y) + dst_extent.height,
+ .layers = 1,
+ });
+ const MSAACopyPushConstants push_constants{
+ .dst_offset = {dst_offset.x, dst_offset.y},
+ .src_offset = {copy.src_offset.x, copy.src_offset.y},
+ .scale = {scale_x, scale_y},
+ };
+ VkImageView src_stencil_handle = VK_NULL_HANDLE;
+ if (copy_stencil) {
+ src_stencil_handle = *src_stencil_view;
+ }
+ scheduler.RequestOutsideRenderPassOperationContext();
+ scheduler.Record([this, pipeline, layout, sampler, renderpass,
+ framebuffer_handle = *framebuffer, src_view_handle = *src_view,
+ src_stencil_handle, src = src_image, dst = dst_image, render_area,
+ aspect_info, push_constants](vk::CommandBuffer cmdbuf) {
+ const VkImageSubresourceRange barrier_range{
+ .aspectMask = aspect_info.barrier_aspect,
+ .baseMipLevel = 0,
+ .levelCount = VK_REMAINING_MIP_LEVELS,
+ .baseArrayLayer = 0,
+ .layerCount = VK_REMAINING_ARRAY_LAYERS,
+ };
+ const std::array pre_barriers{
+ VkImageMemoryBarrier{
+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+ .pNext = nullptr,
+ .srcAccessMask = aspect_info.pre_src_access,
+ .dstAccessMask = aspect_info.pre_src_dst_access,
+ .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
+ .newLayout = VK_IMAGE_LAYOUT_GENERAL,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = src,
+ .subresourceRange = barrier_range,
+ },
+ VkImageMemoryBarrier{
+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+ .pNext = nullptr,
+ .srcAccessMask = aspect_info.pre_src_access,
+ .dstAccessMask = aspect_info.pre_dst_dst_access,
+ .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
+ .newLayout = VK_IMAGE_LAYOUT_GENERAL,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = dst,
+ .subresourceRange = barrier_range,
+ },
+ };
+ cmdbuf.PipelineBarrier(aspect_info.pre_src_stages, aspect_info.pre_dst_stages, 0,
+ nullptr, nullptr, pre_barriers);
+ const VkRenderPassBeginInfo renderpass_bi{
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+ .pNext = nullptr,
+ .renderPass = renderpass,
+ .framebuffer = framebuffer_handle,
+ .renderArea = render_area,
+ .clearValueCount = 0,
+ .pClearValues = nullptr,
+ };
+ cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
+ VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
+ if (src_stencil_handle != VK_NULL_HANDLE) {
+ descriptor_set = two_textures_descriptor_allocator.Commit();
+ UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_view_handle,
+ src_stencil_handle);
+ } else {
+ descriptor_set = one_texture_descriptor_allocator.Commit();
+ UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view_handle);
+ }
+ cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
+ cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
+ nullptr);
+ const VkViewport viewport{
+ .x = static_cast<float>(render_area.offset.x),
+ .y = static_cast<float>(render_area.offset.y),
+ .width = static_cast<float>(render_area.extent.width),
+ .height = static_cast<float>(render_area.extent.height),
+ .minDepth = 0.0f,
+ .maxDepth = 1.0f,
+ };
+ cmdbuf.SetViewport(0, viewport);
+ cmdbuf.SetScissor(0, render_area);
+ cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, push_constants);
+ cmdbuf.Draw(3, 1, 0, 0);
+ cmdbuf.EndRenderPass();
+ const VkImageMemoryBarrier post_barrier{
+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+ .pNext = nullptr,
+ .srcAccessMask = aspect_info.post_src_access,
+ .dstAccessMask = aspect_info.post_dst_access,
+ .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
+ .newLayout = VK_IMAGE_LAYOUT_GENERAL,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = dst,
+ .subresourceRange = barrier_range,
+ };
+ cmdbuf.PipelineBarrier(aspect_info.post_src_stages, aspect_info.post_dst_stages, 0,
+ post_barrier);
+ });
+ msaa_copy_resources.push_back(MSAACopyResources{
+ .tick = scheduler.CurrentTick(),
+ .src_view = std::move(src_view),
+ .dst_view = std::move(dst_view),
+ .framebuffer = std::move(framebuffer),
+ });
+ if (copy_stencil) {
+ msaa_copy_resources.push_back(MSAACopyResources{
+ .tick = scheduler.CurrentTick(),
+ .src_view = std::move(src_stencil_view),
+ .dst_view = vk::ImageView{},
+ .framebuffer = vk::Framebuffer{},
+ });
+ }
+ }
+ }
+ scheduler.InvalidateState();
+}
+
void BlitImageHelper::CopyMSAA(RenderPassCache& render_pass_cache, VkImage dst_image,
VideoCore::Surface::PixelFormat dst_format, VkImage src_image,
VideoCore::Surface::PixelFormat src_format, u32 num_samples,
std::span<const VideoCommon::ImageCopy> copies,
bool msaa_to_non_msaa) {
- while (!msaa_copy_resources.empty() && scheduler.IsFree(msaa_copy_resources.front().tick)) {
- msaa_copy_resources.pop_front();
- }
const auto [samples_x, samples_y] = VideoCommon::SamplesLog2(static_cast<int>(num_samples));
const s32 scale_x = 1 << samples_x;
const s32 scale_y = 1 << samples_y;
- const VkSampleCountFlagBits samples =
- msaa_to_non_msaa ? VK_SAMPLE_COUNT_1_BIT : SampleCountFlag(num_samples);
+ VkSampleCountFlagBits samples = SampleCountFlag(num_samples);
+ if (msaa_to_non_msaa) {
+ samples = VK_SAMPLE_COUNT_1_BIT;
+ }
RenderPassKey renderpass_key{};
renderpass_key.color_formats.fill(VideoCore::Surface::PixelFormat::Invalid);
renderpass_key.color_formats[0] = dst_format;
@@ -905,149 +1109,35 @@ void BlitImageHelper::CopyMSAA(RenderPassCache& render_pass_cache, VkImage dst_i
.renderpass = renderpass,
.samples = samples,
.msaa_to_non_msaa = msaa_to_non_msaa,
+ .format_class = FormatClass(dst_format),
+ };
+ const MSAACopyAspectInfo aspect_info{
+ .src_view_aspect = VK_IMAGE_ASPECT_COLOR_BIT,
+ .attachment_aspect = VK_IMAGE_ASPECT_COLOR_BIT,
+ .barrier_aspect = VK_IMAGE_ASPECT_COLOR_BIT,
+ .pre_src_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT |
+ VK_ACCESS_TRANSFER_WRITE_BIT,
+ .pre_src_dst_access = VK_ACCESS_SHADER_READ_BIT,
+ .pre_dst_dst_access =
+ VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ .pre_src_stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
+ VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
+ .pre_dst_stages =
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ .post_src_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ .post_dst_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT,
+ .post_src_stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ .post_dst_stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
+ VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
};
- const VkPipeline pipeline = FindOrEmplaceMSAACopyPipeline(key);
- const VkPipelineLayout layout = *msaa_copy_pipeline_layout;
- const VkSampler sampler = *nearest_sampler;
const VkFormat src_vk_format =
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, src_format).format;
const VkFormat dst_vk_format =
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, dst_format).format;
- for (const VideoCommon::ImageCopy& copy : copies) {
- ASSERT(copy.src_subresource.base_layer == 0);
- ASSERT(copy.src_subresource.num_layers == 1);
- ASSERT(copy.dst_subresource.base_layer == 0);
- ASSERT(copy.dst_subresource.num_layers == 1);
- vk::ImageView src_view =
- MakeMSAACopyView(device.GetLogical(), src_image, src_vk_format,
- static_cast<u32>(copy.src_subresource.base_level));
- vk::ImageView dst_view =
- MakeMSAACopyView(device.GetLogical(), dst_image, dst_vk_format,
- static_cast<u32>(copy.dst_subresource.base_level));
- const VkOffset2D dst_offset{copy.dst_offset.x, copy.dst_offset.y};
- const VkExtent2D dst_extent{copy.extent.width, copy.extent.height};
- const VkRect2D render_area{
- .offset = dst_offset,
- .extent = dst_extent,
- };
- vk::Framebuffer framebuffer = device.GetLogical().CreateFramebuffer(VkFramebufferCreateInfo{
- .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .renderPass = renderpass,
- .attachmentCount = 1,
- .pAttachments = dst_view.address(),
- .width = static_cast<u32>(dst_offset.x) + dst_extent.width,
- .height = static_cast<u32>(dst_offset.y) + dst_extent.height,
- .layers = 1,
- });
- const MSAACopyPushConstants push_constants{
- .dst_offset = {dst_offset.x, dst_offset.y},
- .src_offset = {copy.src_offset.x, copy.src_offset.y},
- .scale = {scale_x, scale_y},
- };
- scheduler.RequestOutsideRenderPassOperationContext();
- scheduler.Record([this, pipeline, layout, sampler, renderpass,
- framebuffer_handle = *framebuffer, src_view_handle = *src_view,
- src = src_image, dst = dst_image, render_area,
- push_constants](vk::CommandBuffer cmdbuf) {
- constexpr VkImageSubresourceRange color_range{
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .baseMipLevel = 0,
- .levelCount = VK_REMAINING_MIP_LEVELS,
- .baseArrayLayer = 0,
- .layerCount = VK_REMAINING_ARRAY_LAYERS,
- };
- const std::array pre_barriers{
- VkImageMemoryBarrier{
- .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
- .pNext = nullptr,
- .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
- VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
- .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
- .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
- .newLayout = VK_IMAGE_LAYOUT_GENERAL,
- .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .image = src,
- .subresourceRange = color_range,
- },
- VkImageMemoryBarrier{
- .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
- .pNext = nullptr,
- .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
- VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
- .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
- VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
- .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
- .newLayout = VK_IMAGE_LAYOUT_GENERAL,
- .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .image = dst,
- .subresourceRange = color_range,
- },
- };
- cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
- VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
- VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
- VK_PIPELINE_STAGE_TRANSFER_BIT,
- VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- 0, nullptr, nullptr, pre_barriers);
- const VkRenderPassBeginInfo renderpass_bi{
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
- .pNext = nullptr,
- .renderPass = renderpass,
- .framebuffer = framebuffer_handle,
- .renderArea = render_area,
- .clearValueCount = 0,
- .pClearValues = nullptr,
- };
- cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
- const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
- UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view_handle);
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
- cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
- nullptr);
- const VkViewport viewport{
- .x = static_cast<float>(render_area.offset.x),
- .y = static_cast<float>(render_area.offset.y),
- .width = static_cast<float>(render_area.extent.width),
- .height = static_cast<float>(render_area.extent.height),
- .minDepth = 0.0f,
- .maxDepth = 1.0f,
- };
- cmdbuf.SetViewport(0, viewport);
- cmdbuf.SetScissor(0, render_area);
- cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, push_constants);
- cmdbuf.Draw(3, 1, 0, 0);
- cmdbuf.EndRenderPass();
- const VkImageMemoryBarrier post_barrier{
- .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
- .pNext = nullptr,
- .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
- .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT,
- .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
- .newLayout = VK_IMAGE_LAYOUT_GENERAL,
- .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .image = dst,
- .subresourceRange = color_range,
- };
- cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
- VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
- VK_PIPELINE_STAGE_TRANSFER_BIT,
- 0, post_barrier);
- });
- msaa_copy_resources.push_back(MSAACopyResources{
- .tick = scheduler.CurrentTick(),
- .src_view = std::move(src_view),
- .dst_view = std::move(dst_view),
- .framebuffer = std::move(framebuffer),
- });
- }
- scheduler.InvalidateState();
+ CopyMSAAImpl(renderpass, FindOrEmplaceMSAACopyPipeline(key), *msaa_copy_pipeline_layout,
+ dst_image, dst_vk_format, src_image, src_vk_format, scale_x, scale_y, copies,
+ aspect_info, false);
}
void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
@@ -1379,6 +1469,87 @@ VkPipeline BlitImageHelper::FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPip
return *blit_msaa_color_pipelines.back();
}
+VkPipeline BlitImageHelper::FindOrEmplaceBlitDepthStencilMSAAPipeline(
+ const BlitMSAAPipelineKey& key, bool blit_stencil) {
+ auto& keys = blit_stencil ? blit_msaa_depth_stencil_keys : blit_msaa_depth_keys;
+ auto& pipelines = blit_stencil ? blit_msaa_depth_stencil_pipelines : blit_msaa_depth_pipelines;
+ const auto it = std::ranges::find(keys, key);
+ if (it != keys.end()) {
+ return *pipelines[std::distance(keys.begin(), it)];
+ }
+ keys.push_back(key);
+ const std::array stages =
+ MakeStages(*full_screen_vert,
+ blit_stencil ? *blit_depth_stencil_msaa_frag : *blit_depth_msaa_frag);
+ const VkPipelineMultisampleStateCreateInfo multisample_ci{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .rasterizationSamples = key.samples,
+ .sampleShadingEnable = VK_TRUE,
+ .minSampleShading = 1.0f,
+ .pSampleMask = nullptr,
+ .alphaToCoverageEnable = VK_FALSE,
+ .alphaToOneEnable = VK_FALSE,
+ };
+ const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
+ pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
+ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .stageCount = static_cast<u32>(stages.size()),
+ .pStages = stages.data(),
+ .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+ .pInputAssemblyState = &input_assembly_ci,
+ .pTessellationState = nullptr,
+ .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+ .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+ .pMultisampleState = &multisample_ci,
+ .pDepthStencilState = blit_stencil ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
+ : &PIPELINE_DEPTH_ONLY_STATE_CREATE_INFO,
+ .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO,
+ .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+ .layout = blit_stencil ? *two_textures_pipeline_layout : *one_texture_pipeline_layout,
+ .renderPass = key.renderpass,
+ .subpass = 0,
+ .basePipelineHandle = VK_NULL_HANDLE,
+ .basePipelineIndex = 0,
+ }));
+ return *pipelines.back();
+}
+
+VkPipeline BlitImageHelper::FindOrEmplaceBlitDepthPipeline(VkRenderPass renderpass) {
+ const auto it = std::ranges::find(blit_depth_keys, renderpass);
+ if (it != blit_depth_keys.end()) {
+ return *blit_depth_pipelines[std::distance(blit_depth_keys.begin(), it)];
+ }
+ blit_depth_keys.push_back(renderpass);
+ const std::array stages = MakeStages(*full_screen_vert, *blit_depth_frag);
+ const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
+ blit_depth_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
+ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .stageCount = static_cast<u32>(stages.size()),
+ .pStages = stages.data(),
+ .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+ .pInputAssemblyState = &input_assembly_ci,
+ .pTessellationState = nullptr,
+ .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+ .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+ .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+ .pDepthStencilState = &PIPELINE_DEPTH_ONLY_STATE_CREATE_INFO,
+ .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO,
+ .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+ .layout = *one_texture_pipeline_layout,
+ .renderPass = renderpass,
+ .subpass = 0,
+ .basePipelineHandle = VK_NULL_HANDLE,
+ .basePipelineIndex = 0,
+ }));
+ return *blit_depth_pipelines.back();
+}
+
VkPipeline BlitImageHelper::FindOrEmplaceResolveDepthStencilPipeline(VkRenderPass renderpass,
bool resolve_stencil) {
auto& keys = resolve_stencil ? resolve_depth_stencil_keys : resolve_depth_keys;
@@ -1417,15 +1588,83 @@ VkPipeline BlitImageHelper::FindOrEmplaceResolveDepthStencilPipeline(VkRenderPas
return *pipelines.back();
}
+void BlitImageHelper::CopyMSAADepth(RenderPassCache& render_pass_cache, VkImage dst_image,
+ VideoCore::Surface::PixelFormat dst_format, VkImage src_image,
+ VideoCore::Surface::PixelFormat src_format, u32 num_samples,
+ std::span<const VideoCommon::ImageCopy> copies,
+ bool copy_stencil, bool msaa_to_non_msaa) {
+ const auto [samples_x, samples_y] = VideoCommon::SamplesLog2(static_cast<int>(num_samples));
+ const s32 scale_x = 1 << samples_x;
+ const s32 scale_y = 1 << samples_y;
+ VkSampleCountFlagBits samples = SampleCountFlag(num_samples);
+ if (msaa_to_non_msaa) {
+ samples = VK_SAMPLE_COUNT_1_BIT;
+ }
+ RenderPassKey renderpass_key{};
+ renderpass_key.color_formats.fill(VideoCore::Surface::PixelFormat::Invalid);
+ renderpass_key.depth_format = dst_format;
+ renderpass_key.samples = samples;
+ const VkRenderPass renderpass = render_pass_cache.Get(renderpass_key);
+ const MSAACopyPipelineKey key{
+ .renderpass = renderpass,
+ .samples = samples,
+ .msaa_to_non_msaa = msaa_to_non_msaa,
+ .format_class = MSAACopyFormatClass::Float,
+ };
+ VkImageAspectFlags attachment_aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
+ if (VideoCore::Surface::GetFormatType(dst_format) ==
+ VideoCore::Surface::SurfaceType::DepthStencil) {
+ attachment_aspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
+ }
+ VkPipelineLayout layout = *msaa_copy_pipeline_layout;
+ if (copy_stencil) {
+ layout = *msaa_copy_depth_stencil_pipeline_layout;
+ }
+ const MSAACopyAspectInfo aspect_info{
+ .src_view_aspect = VK_IMAGE_ASPECT_DEPTH_BIT,
+ .attachment_aspect = attachment_aspect,
+ .barrier_aspect = attachment_aspect,
+ .pre_src_access =
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
+ .pre_src_dst_access = VK_ACCESS_SHADER_READ_BIT,
+ .pre_dst_dst_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
+ .pre_src_stages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
+ VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ .pre_dst_stages =
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
+ .post_src_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
+ .post_dst_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT |
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
+ .post_src_stages = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
+ .post_dst_stages = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER,
+ };
+ const VkFormat src_vk_format =
+ MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, src_format).format;
+ const VkFormat dst_vk_format =
+ MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, dst_format).format;
+ CopyMSAAImpl(renderpass, FindOrEmplaceMSAACopyDepthPipeline(key, copy_stencil), layout,
+ dst_image, dst_vk_format, src_image, src_vk_format, scale_x, scale_y, copies,
+ aspect_info, copy_stencil);
+}
+
VkPipeline BlitImageHelper::FindOrEmplaceMSAACopyPipeline(const MSAACopyPipelineKey& key) {
const auto it = std::ranges::find(msaa_copy_keys, key);
if (it != msaa_copy_keys.end()) {
return *msaa_copy_pipelines[std::distance(msaa_copy_keys.begin(), it)];
}
msaa_copy_keys.push_back(key);
- const std::array stages = MakeStages(*clear_color_vert, key.msaa_to_non_msaa
- ? *convert_msaa_to_non_msaa_frag
- : *convert_non_msaa_to_msaa_frag);
+ VkShaderModule frag_module = key.msaa_to_non_msaa ? *convert_msaa_to_non_msaa_frag
+ : *convert_non_msaa_to_msaa_frag;
+ if (key.format_class == MSAACopyFormatClass::SignedInteger) {
+ frag_module = key.msaa_to_non_msaa ? *convert_msaa_to_non_msaa_sint_frag
+ : *convert_non_msaa_to_msaa_sint_frag;
+ } else if (key.format_class == MSAACopyFormatClass::UnsignedInteger) {
+ frag_module = key.msaa_to_non_msaa ? *convert_msaa_to_non_msaa_uint_frag
+ : *convert_non_msaa_to_msaa_uint_frag;
+ }
+ const std::array stages = MakeStages(*clear_color_vert, frag_module);
const VkPipelineMultisampleStateCreateInfo multisample_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.pNext = nullptr,
@@ -1462,6 +1701,85 @@ VkPipeline BlitImageHelper::FindOrEmplaceMSAACopyPipeline(const MSAACopyPipeline
return *msaa_copy_pipelines.back();
}
+VkPipeline BlitImageHelper::FindOrEmplaceMSAACopyDepthPipeline(const MSAACopyPipelineKey& key,
+ bool copy_stencil) {
+ auto& keys = copy_stencil ? msaa_copy_depth_stencil_keys : msaa_copy_depth_keys;
+ auto& pipelines = copy_stencil ? msaa_copy_depth_stencil_pipelines : msaa_copy_depth_pipelines;
+ const auto it = std::ranges::find(keys, key);
+ if (it != keys.end()) {
+ return *pipelines[std::distance(keys.begin(), it)];
+ }
+ keys.push_back(key);
+ VkShaderModule frag_module;
+ if (key.msaa_to_non_msaa) {
+ frag_module = copy_stencil ? *convert_msaa_to_non_msaa_depth_stencil_frag
+ : *convert_msaa_to_non_msaa_depth_frag;
+ } else {
+ frag_module = copy_stencil ? *convert_non_msaa_to_msaa_depth_stencil_frag
+ : *convert_non_msaa_to_msaa_depth_frag;
+ }
+ const std::array stages = MakeStages(*clear_color_vert, frag_module);
+ const VkPipelineMultisampleStateCreateInfo multisample_ci{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .rasterizationSamples = key.samples,
+ .sampleShadingEnable = key.msaa_to_non_msaa ? VK_FALSE : VK_TRUE,
+ .minSampleShading = key.msaa_to_non_msaa ? 0.0f : 1.0f,
+ .pSampleMask = nullptr,
+ .alphaToCoverageEnable = VK_FALSE,
+ .alphaToOneEnable = VK_FALSE,
+ };
+ static constexpr VkStencilOpState REPLACE_STENCIL_OP{
+ .failOp = VK_STENCIL_OP_REPLACE,
+ .passOp = VK_STENCIL_OP_REPLACE,
+ .depthFailOp = VK_STENCIL_OP_REPLACE,
+ .compareOp = VK_COMPARE_OP_ALWAYS,
+ .compareMask = 0xFF,
+ .writeMask = 0xFF,
+ .reference = 0,
+ };
+ const VkPipelineDepthStencilStateCreateInfo depth_stencil_ci{
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .depthTestEnable = VK_TRUE,
+ .depthWriteEnable = VK_TRUE,
+ .depthCompareOp = VK_COMPARE_OP_ALWAYS,
+ .depthBoundsTestEnable = VK_FALSE,
+ .stencilTestEnable = copy_stencil ? VK_TRUE : VK_FALSE,
+ .front = copy_stencil ? REPLACE_STENCIL_OP : VkStencilOpState{},
+ .back = copy_stencil ? REPLACE_STENCIL_OP : VkStencilOpState{},
+ .minDepthBounds = 0.0f,
+ .maxDepthBounds = 0.0f,
+ };
+ const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci =
+ GetPipelineInputAssemblyStateCreateInfo(device);
+ pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
+ .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = 0,
+ .stageCount = static_cast<u32>(stages.size()),
+ .pStages = stages.data(),
+ .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+ .pInputAssemblyState = &input_assembly_ci,
+ .pTessellationState = nullptr,
+ .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+ .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+ .pMultisampleState = &multisample_ci,
+ .pDepthStencilState = &depth_stencil_ci,
+ .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO,
+ .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+ .layout = copy_stencil ? *msaa_copy_depth_stencil_pipeline_layout
+ : *msaa_copy_pipeline_layout,
+ .renderPass = key.renderpass,
+ .subpass = 0,
+ .basePipelineHandle = VK_NULL_HANDLE,
+ .basePipelineIndex = 0,
+ }));
+ return *pipelines.back();
+}
+
void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) {
ConvertPipeline(pipeline, renderpass, false);
}