mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-10-23 05:30:39 +02:00
[TEST] Upload on depth MSAACopy pass
This commit is contained in:
parent
5c0fe5da06
commit
624f955821
5 changed files with 111 additions and 29 deletions
|
|
@ -32,6 +32,7 @@ set(SHADER_FILES
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/convert_msaa_to_non_msaa.frag
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/convert_non_msaa_to_msaa.comp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/convert_non_msaa_to_msaa.frag
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/convert_non_msaa_to_msaa_depth.frag
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/convert_s8d24_to_abgr8.frag
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/full_screen_triangle.vert
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fxaa.frag
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#version 450 core
|
||||
|
||||
layout(binding = 0) uniform sampler2D img_in;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
ivec2 dst_offset;
|
||||
ivec2 src_offset;
|
||||
ivec2 scale;
|
||||
};
|
||||
|
||||
void main() {
|
||||
const ivec2 msaa_coord = ivec2(gl_FragCoord.xy) - dst_offset;
|
||||
const ivec2 sample_offset = ivec2(gl_SampleID % scale.x, gl_SampleID / scale.x);
|
||||
const ivec2 coord = msaa_coord * scale + sample_offset + src_offset;
|
||||
gl_FragDepth = texelFetch(img_in, coord, 0).r;
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
@ -639,6 +641,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>)) {}
|
||||
|
||||
|
|
@ -936,16 +940,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;
|
||||
|
|
@ -961,10 +980,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{
|
||||
|
|
@ -990,50 +1009,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,
|
||||
|
|
@ -1066,16 +1096,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,
|
||||
|
|
@ -1497,9 +1527,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,
|
||||
|
|
@ -1524,8 +1581,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,
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ struct MSAACopyPipelineKey {
|
|||
VkRenderPass renderpass;
|
||||
VkSampleCountFlagBits samples;
|
||||
bool msaa_to_non_msaa;
|
||||
bool is_depth;
|
||||
};
|
||||
|
||||
struct BlitMSAAPipelineKey {
|
||||
|
|
@ -198,6 +199,7 @@ private:
|
|||
vk::ShaderModule convert_s8d24_to_abgr8_frag;
|
||||
vk::ShaderModule convert_msaa_to_non_msaa_frag;
|
||||
vk::ShaderModule convert_non_msaa_to_msaa_frag;
|
||||
vk::ShaderModule convert_non_msaa_to_msaa_depth_frag;
|
||||
vk::Sampler linear_sampler;
|
||||
vk::Sampler nearest_sampler;
|
||||
|
||||
|
|
|
|||
|
|
@ -1949,9 +1949,11 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset,
|
|||
ScaleDown(true);
|
||||
}
|
||||
|
||||
const bool wants_msaa_upload = info.num_samples > 1
|
||||
&& (aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != 0
|
||||
const bool is_color_upload = (aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != 0
|
||||
&& !VideoCore::Surface::IsPixelFormatInteger(info.format);
|
||||
const bool is_depth_upload = (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0;
|
||||
const bool wants_msaa_upload =
|
||||
info.num_samples > 1 && (is_color_upload || is_depth_upload);
|
||||
|
||||
if (wants_msaa_upload) {
|
||||
ImageInfo temp_info = info;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue