|
|
|
@@ -21,6 +21,7 @@
|
|
|
|
|
#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_non_msaa_to_msaa_depth_frag_spv.h"
|
|
|
|
|
#include "video_core/host_shaders/convert_non_msaa_to_msaa_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"
|
|
|
|
@@ -519,7 +520,8 @@ void RecordShaderReadBarrier(Scheduler& scheduler, const ImageView& image_view)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] vk::ImageView MakeMSAACopyView(const vk::Device& device, VkImage image,
|
|
|
|
|
VkFormat format, u32 base_level) {
|
|
|
|
|
VkFormat format, u32 base_level,
|
|
|
|
|
VkImageAspectFlags aspect_mask) {
|
|
|
|
|
return device.CreateImageView(VkImageViewCreateInfo{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
@@ -534,7 +536,7 @@ 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,
|
|
|
|
@@ -610,6 +612,8 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
|
|
|
|
|
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_non_msaa_to_msaa_frag(BuildShader(device, CONVERT_NON_MSAA_TO_MSAA_FRAG_SPV)),
|
|
|
|
|
convert_non_msaa_to_msaa_depth_frag(
|
|
|
|
|
BuildShader(device, CONVERT_NON_MSAA_TO_MSAA_DEPTH_FRAG_SPV)),
|
|
|
|
|
linear_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_LINEAR>)),
|
|
|
|
|
nearest_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_NEAREST>)) {}
|
|
|
|
|
|
|
|
|
@@ -895,16 +899,31 @@ void BlitImageHelper::CopyMSAA(RenderPassCache& render_pass_cache, VkImage dst_i
|
|
|
|
|
const s32 scale_y = 1 << samples_y;
|
|
|
|
|
const VkSampleCountFlagBits samples =
|
|
|
|
|
msaa_to_non_msaa ? VK_SAMPLE_COUNT_1_BIT : SampleCountFlag(num_samples);
|
|
|
|
|
const auto dst_surface_type = VideoCore::Surface::GetFormatType(dst_format);
|
|
|
|
|
const bool is_depth = dst_surface_type == VideoCore::Surface::SurfaceType::Depth ||
|
|
|
|
|
dst_surface_type == VideoCore::Surface::SurfaceType::DepthStencil;
|
|
|
|
|
const bool has_stencil = dst_surface_type == VideoCore::Surface::SurfaceType::DepthStencil;
|
|
|
|
|
const VkImageAspectFlags view_aspect =
|
|
|
|
|
is_depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
|
const VkImageAspectFlags barrier_aspect =
|
|
|
|
|
is_depth ? (VK_IMAGE_ASPECT_DEPTH_BIT |
|
|
|
|
|
(has_stencil ? VK_IMAGE_ASPECT_STENCIL_BIT : 0u))
|
|
|
|
|
: VK_IMAGE_ASPECT_COLOR_BIT;
|
|
|
|
|
RenderPassKey renderpass_key{};
|
|
|
|
|
renderpass_key.color_formats.fill(VideoCore::Surface::PixelFormat::Invalid);
|
|
|
|
|
renderpass_key.color_formats[0] = dst_format;
|
|
|
|
|
renderpass_key.depth_format = VideoCore::Surface::PixelFormat::Invalid;
|
|
|
|
|
if (is_depth) {
|
|
|
|
|
renderpass_key.depth_format = dst_format;
|
|
|
|
|
} else {
|
|
|
|
|
renderpass_key.color_formats[0] = dst_format;
|
|
|
|
|
renderpass_key.depth_format = VideoCore::Surface::PixelFormat::Invalid;
|
|
|
|
|
}
|
|
|
|
|
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,
|
|
|
|
|
.is_depth = is_depth,
|
|
|
|
|
};
|
|
|
|
|
const VkPipeline pipeline = FindOrEmplaceMSAACopyPipeline(key);
|
|
|
|
|
const VkPipelineLayout layout = *msaa_copy_pipeline_layout;
|
|
|
|
@@ -920,10 +939,10 @@ void BlitImageHelper::CopyMSAA(RenderPassCache& render_pass_cache, VkImage dst_i
|
|
|
|
|
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));
|
|
|
|
|
static_cast<u32>(copy.src_subresource.base_level), view_aspect);
|
|
|
|
|
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_level), view_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{
|
|
|
|
@@ -949,50 +968,61 @@ void BlitImageHelper::CopyMSAA(RenderPassCache& render_pass_cache, VkImage dst_i
|
|
|
|
|
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,
|
|
|
|
|
src = src_image, dst = dst_image, render_area, is_depth, barrier_aspect,
|
|
|
|
|
push_constants](vk::CommandBuffer cmdbuf) {
|
|
|
|
|
constexpr VkImageSubresourceRange color_range{
|
|
|
|
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
|
|
|
const VkImageSubresourceRange src_range{
|
|
|
|
|
.aspectMask = barrier_aspect,
|
|
|
|
|
.baseMipLevel = 0,
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS,
|
|
|
|
|
.baseArrayLayer = 0,
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
|
|
|
|
};
|
|
|
|
|
const VkImageSubresourceRange dst_range = src_range;
|
|
|
|
|
const VkAccessFlags attachment_read =
|
|
|
|
|
is_depth ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
|
|
|
|
: VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
|
|
|
|
|
const VkAccessFlags attachment_write =
|
|
|
|
|
is_depth ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
|
|
|
|
|
: VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
|
|
|
const VkPipelineStageFlags attachment_stage =
|
|
|
|
|
is_depth ? VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
|
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
|
|
|
|
|
: VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
|
|
|
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,
|
|
|
|
|
.srcAccessMask = attachment_write | 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,
|
|
|
|
|
.subresourceRange = src_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,
|
|
|
|
|
.srcAccessMask = attachment_write | VK_ACCESS_SHADER_WRITE_BIT |
|
|
|
|
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
|
|
|
|
.dstAccessMask = attachment_read | attachment_write,
|
|
|
|
|
.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,
|
|
|
|
|
.subresourceRange = dst_range,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
|
|
|
|
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
|
|
|
|
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_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,
|
|
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | attachment_stage,
|
|
|
|
|
0, nullptr, nullptr, pre_barriers);
|
|
|
|
|
const VkRenderPassBeginInfo renderpass_bi{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
|
|
|
@@ -1025,16 +1055,16 @@ void BlitImageHelper::CopyMSAA(RenderPassCache& render_pass_cache, VkImage dst_i
|
|
|
|
|
const VkImageMemoryBarrier post_barrier{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
|
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
|
|
|
.srcAccessMask = attachment_write,
|
|
|
|
|
.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,
|
|
|
|
|
.subresourceRange = dst_range,
|
|
|
|
|
};
|
|
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
|
|
|
|
cmdbuf.PipelineBarrier(attachment_stage,
|
|
|
|
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
|
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
|
|
|
|
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
@@ -1423,9 +1453,36 @@ VkPipeline BlitImageHelper::FindOrEmplaceMSAACopyPipeline(const MSAACopyPipeline
|
|
|
|
|
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);
|
|
|
|
|
const VkShaderModule frag_module =
|
|
|
|
|
key.msaa_to_non_msaa
|
|
|
|
|
? *convert_msaa_to_non_msaa_frag
|
|
|
|
|
: (key.is_depth ? *convert_non_msaa_to_msaa_depth_frag
|
|
|
|
|
: *convert_non_msaa_to_msaa_frag);
|
|
|
|
|
const std::array stages = MakeStages(*clear_color_vert, frag_module);
|
|
|
|
|
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 = VK_FALSE,
|
|
|
|
|
.front = {},
|
|
|
|
|
.back = {},
|
|
|
|
|
.minDepthBounds = 0.0f,
|
|
|
|
|
.maxDepthBounds = 0.0f,
|
|
|
|
|
};
|
|
|
|
|
static constexpr VkPipelineColorBlendStateCreateInfo no_color_blend_ci{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
|
.flags = 0,
|
|
|
|
|
.logicOpEnable = VK_FALSE,
|
|
|
|
|
.logicOp = VK_LOGIC_OP_CLEAR,
|
|
|
|
|
.attachmentCount = 0,
|
|
|
|
|
.pAttachments = nullptr,
|
|
|
|
|
.blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
|
|
|
|
|
};
|
|
|
|
|
const VkPipelineMultisampleStateCreateInfo multisample_ci{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
|
|
|
|
.pNext = nullptr,
|
|
|
|
@@ -1450,8 +1507,9 @@ VkPipeline BlitImageHelper::FindOrEmplaceMSAACopyPipeline(const MSAACopyPipeline
|
|
|
|
|
.pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
|
|
|
|
.pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
|
|
|
|
.pMultisampleState = &multisample_ci,
|
|
|
|
|
.pDepthStencilState = nullptr,
|
|
|
|
|
.pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
|
|
|
|
|
.pDepthStencilState = key.is_depth ? &depth_stencil_ci : nullptr,
|
|
|
|
|
.pColorBlendState = key.is_depth ? &no_color_blend_ci
|
|
|
|
|
: &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
|
|
|
|
|
.pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
|
|
|
|
.layout = *msaa_copy_pipeline_layout,
|
|
|
|
|
.renderPass = key.renderpass,
|
|
|
|
|