Some corrections towards HCR + Discard MSAA

This commit is contained in:
CamilleLaVey
2026-09-30 12:05:15 -04:00
parent 4f5fc58b6e
commit dd1c024efc
9 changed files with 185 additions and 209 deletions
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -7,8 +10,10 @@ layout (push_constant) uniform PushConstants {
vec4 clear_color; vec4 clear_color;
}; };
layout(location = 0) out vec4 color; layout(location = 0) out vec4 colors[8];
void main() { void main() {
color = clear_color; for (int index = 0; index < 8; ++index) {
colors[index] = clear_color;
}
} }
+114 -133
View File
@@ -279,6 +279,44 @@ constexpr VkPipelineDepthStencilStateCreateInfo PIPELINE_DEPTH_ONLY_STATE_CREATE
.maxDepthBounds = 0.0f, .maxDepthBounds = 0.0f,
}; };
constexpr VkPipelineDepthStencilStateCreateInfo PIPELINE_DEPTH_STENCIL_STATE_DISABLED_CREATE_INFO{
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.depthTestEnable = VK_FALSE,
.depthWriteEnable = VK_FALSE,
.depthCompareOp = VK_COMPARE_OP_ALWAYS,
.depthBoundsTestEnable = VK_FALSE,
.stencilTestEnable = VK_FALSE,
.front = VkStencilOpState{},
.back = VkStencilOpState{},
.minDepthBounds = 0.0f,
.maxDepthBounds = 0.0f,
};
using BlendAttachments = std::array<VkPipelineColorBlendAttachmentState, 8>;
[[nodiscard]] VkPipelineColorBlendStateCreateInfo MakeColorBlendState(
const BlendAttachments& attachments, const RenderingFormats& formats) {
return VkPipelineColorBlendStateCreateInfo{
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.logicOpEnable = VK_FALSE,
.logicOp = VK_LOGIC_OP_CLEAR,
.attachmentCount = formats.num_colors,
.pAttachments = attachments.data(),
.blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
};
}
[[nodiscard]] VkPipelineMultisampleStateCreateInfo MakeMultisampleState(
VkSampleCountFlagBits samples) {
VkPipelineMultisampleStateCreateInfo multisample_ci = PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisample_ci.rasterizationSamples = samples;
return multisample_ci;
}
template <VkFilter filter> template <VkFilter filter>
inline constexpr VkSamplerCreateInfo SAMPLER_CREATE_INFO{ inline constexpr VkSamplerCreateInfo SAMPLER_CREATE_INFO{
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
@@ -628,6 +666,8 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, const ImageV
const BlitImagePipelineKey key{ const BlitImagePipelineKey key{
.formats = dst_framebuffer->Formats(), .formats = dst_framebuffer->Formats(),
.operation = operation, .operation = operation,
.samples = dst_framebuffer->Samples(),
.target = 0,
}; };
VkSampler sampler = *nearest_sampler; VkSampler sampler = *nearest_sampler;
if (is_linear) { if (is_linear) {
@@ -645,6 +685,8 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView
const BlitImagePipelineKey key{ const BlitImagePipelineKey key{
.formats = dst_framebuffer->Formats(), .formats = dst_framebuffer->Formats(),
.operation = Tegra::Engines::Fermi2D::Operation::SrcCopy, .operation = Tegra::Engines::Fermi2D::Operation::SrcCopy,
.samples = dst_framebuffer->Samples(),
.target = 0,
}; };
const VkPipelineLayout layout = *one_texture_pipeline_layout; const VkPipelineLayout layout = *one_texture_pipeline_layout;
const VkPipeline pipeline = FindOrEmplaceColorPipeline(key); const VkPipeline pipeline = FindOrEmplaceColorPipeline(key);
@@ -763,6 +805,8 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
const BlitImagePipelineKey key{ const BlitImagePipelineKey key{
.formats = dst_framebuffer->Formats(), .formats = dst_framebuffer->Formats(),
.operation = operation, .operation = operation,
.samples = dst_framebuffer->Samples(),
.target = 0,
}; };
VkPipeline pipeline{}; VkPipeline pipeline{};
VkImageView src_stencil_view = VK_NULL_HANDLE; VkImageView src_stencil_view = VK_NULL_HANDLE;
@@ -778,26 +822,22 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view) { const ImageView& src_image_view) {
ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer->Formats()); Convert(*convert_depth_to_float_frag, dst_framebuffer, src_image_view);
Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view);
} }
void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view) { const ImageView& src_image_view) {
ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->Formats()); Convert(*convert_float_to_depth_frag, dst_framebuffer, src_image_view);
Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view);
} }
void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view) { const ImageView& src_image_view) {
ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer->Formats()); Convert(*convert_depth_to_float_frag, dst_framebuffer, src_image_view);
Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view);
} }
void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view) { const ImageView& src_image_view) {
ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer->Formats()); Convert(*convert_float_to_depth_frag, dst_framebuffer, src_image_view);
Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view);
} }
void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer,
@@ -807,45 +847,37 @@ void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer,
LOG_WARNING(Render_Vulkan, "ConvertABGR8ToD24S8 requires shader_stencil_export, skipping"); LOG_WARNING(Render_Vulkan, "ConvertABGR8ToD24S8 requires shader_stencil_export, skipping");
return; return;
} }
ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->Formats(), Convert(*convert_abgr8_to_d24s8_frag, dst_framebuffer, src_image_view);
convert_abgr8_to_d24s8_frag);
Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view);
} }
void BlitImageHelper::ConvertABGR8ToD32F(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertABGR8ToD32F(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view) { const ImageView& src_image_view) {
ConvertPipelineDepthTargetEx(convert_abgr8_to_d32f_pipeline, dst_framebuffer->Formats(), Convert(*convert_abgr8_to_d32f_frag, dst_framebuffer, src_image_view);
convert_abgr8_to_d32f_frag);
Convert(*convert_abgr8_to_d32f_pipeline, dst_framebuffer, src_image_view);
} }
void BlitImageHelper::ConvertD32FToABGR8(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertD32FToABGR8(const Framebuffer* dst_framebuffer,
ImageView& src_image_view) { ImageView& src_image_view) {
ConvertPipelineColorTargetEx(convert_d32f_to_abgr8_pipeline, dst_framebuffer->Formats(), ConvertDepthStencil(*convert_d32f_to_abgr8_frag, dst_framebuffer, src_image_view);
convert_d32f_to_abgr8_frag);
ConvertDepthStencil(*convert_d32f_to_abgr8_pipeline, dst_framebuffer, src_image_view);
} }
void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer,
ImageView& src_image_view) { ImageView& src_image_view) {
ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->Formats(), ConvertDepthStencil(*convert_d24s8_to_abgr8_frag, dst_framebuffer, src_image_view);
convert_d24s8_to_abgr8_frag);
ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view);
} }
void BlitImageHelper::ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer,
ImageView& src_image_view) { ImageView& src_image_view) {
ConvertPipelineColorTargetEx(convert_s8d24_to_abgr8_pipeline, dst_framebuffer->Formats(), ConvertDepthStencil(*convert_s8d24_to_abgr8_frag, dst_framebuffer, src_image_view);
convert_s8d24_to_abgr8_frag);
ConvertDepthStencil(*convert_s8d24_to_abgr8_pipeline, dst_framebuffer, src_image_view);
} }
void BlitImageHelper::ClearColor(const Framebuffer* dst_framebuffer, u8 color_mask, void BlitImageHelper::ClearColor(const Framebuffer* dst_framebuffer, u32 target, u8 color_mask,
const std::array<f32, 4>& clear_color, const std::array<f32, 4>& clear_color,
const Region2D& dst_region) { const Region2D& dst_region) {
const BlitImagePipelineKey key{ const BlitImagePipelineKey key{
.formats = dst_framebuffer->Formats(), .formats = dst_framebuffer->Formats(),
.operation = Tegra::Engines::Fermi2D::Operation::BlendPremult, .operation = Tegra::Engines::Fermi2D::Operation::BlendPremult,
.samples = dst_framebuffer->Samples(),
.target = target,
}; };
const VkPipeline pipeline = FindOrEmplaceClearColorPipeline(key); const VkPipeline pipeline = FindOrEmplaceClearColorPipeline(key);
const VkPipelineLayout layout = *clear_color_pipeline_layout; const VkPipelineLayout layout = *clear_color_pipeline_layout;
@@ -873,6 +905,7 @@ void BlitImageHelper::ClearDepthStencil(const Framebuffer* dst_framebuffer, bool
.stencil_mask = stencil_mask, .stencil_mask = stencil_mask,
.stencil_compare_mask = stencil_compare_mask, .stencil_compare_mask = stencil_compare_mask,
.stencil_ref = stencil_ref, .stencil_ref = stencil_ref,
.samples = dst_framebuffer->Samples(),
}; };
const VkPipeline pipeline = FindOrEmplaceClearStencilPipeline(key); const VkPipeline pipeline = FindOrEmplaceClearStencilPipeline(key);
const VkPipelineLayout layout = *clear_color_pipeline_layout; const VkPipelineLayout layout = *clear_color_pipeline_layout;
@@ -1079,9 +1112,11 @@ void BlitImageHelper::CopyMSAA(VkImage dst_image, VideoCore::Surface::PixelForma
aspect_info, false); aspect_info, false);
} }
void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, void BlitImageHelper::Convert(VkShaderModule module, const Framebuffer* dst_framebuffer,
const ImageView& src_image_view) { const ImageView& src_image_view) {
const VkPipelineLayout layout = *one_texture_pipeline_layout; const VkPipelineLayout layout = *one_texture_pipeline_layout;
const VkPipeline pipeline =
FindOrEmplaceConvertPipeline(dst_framebuffer->Formats(), module, layout);
const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D); const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D);
const VkSampler sampler = *nearest_sampler; const VkSampler sampler = *nearest_sampler;
const VkExtent2D extent = GetConversionExtent(src_image_view); const VkExtent2D extent = GetConversionExtent(src_image_view);
@@ -1128,9 +1163,12 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb
scheduler.InvalidateState(); scheduler.InvalidateState();
} }
void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, void BlitImageHelper::ConvertDepthStencil(VkShaderModule module,
const Framebuffer* dst_framebuffer,
ImageView& src_image_view) { ImageView& src_image_view) {
const VkPipelineLayout layout = *two_textures_pipeline_layout; const VkPipelineLayout layout = *two_textures_pipeline_layout;
const VkPipeline pipeline =
FindOrEmplaceConvertPipeline(dst_framebuffer->Formats(), module, layout);
const VkImageView src_depth_view = src_image_view.DepthView(); const VkImageView src_depth_view = src_image_view.DepthView();
const VkImageView src_stencil_view = src_image_view.StencilView(); const VkImageView src_stencil_view = src_image_view.StencilView();
const VkSampler sampler = *nearest_sampler; const VkSampler sampler = *nearest_sampler;
@@ -1187,28 +1225,12 @@ VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKe
blit_color_keys.push_back(key); blit_color_keys.push_back(key);
const std::array stages = MakeStages(*full_screen_vert, *blit_color_to_color_frag); const std::array stages = MakeStages(*full_screen_vert, *blit_color_to_color_frag);
const VkPipelineColorBlendAttachmentState blend_attachment{ BlendAttachments blend_attachments{};
.blendEnable = VK_FALSE, blend_attachments[key.target] = PIPELINE_COLOR_BLEND_ATTACHMENT_STATE;
.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO,
.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
.colorBlendOp = VK_BLEND_OP_ADD,
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
.alphaBlendOp = VK_BLEND_OP_ADD,
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
};
// TODO: programmable blending // TODO: programmable blending
const VkPipelineColorBlendStateCreateInfo color_blend_create_info{ const VkPipelineColorBlendStateCreateInfo color_blend_create_info =
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, MakeColorBlendState(blend_attachments, key.formats);
.pNext = nullptr, const VkPipelineMultisampleStateCreateInfo multisample_ci = MakeMultisampleState(key.samples);
.flags = 0,
.logicOpEnable = VK_FALSE,
.logicOp = VK_LOGIC_OP_CLEAR,
.attachmentCount = 1,
.pAttachments = &blend_attachment,
.blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
};
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
const VkPipelineRenderingCreateInfo rendering_ci = key.formats.CreateInfo(); const VkPipelineRenderingCreateInfo rendering_ci = key.formats.CreateInfo();
blit_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ blit_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
@@ -1222,8 +1244,8 @@ VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKe
.pTessellationState = nullptr, .pTessellationState = nullptr,
.pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pMultisampleState = &multisample_ci,
.pDepthStencilState = nullptr, .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_DISABLED_CREATE_INFO,
.pColorBlendState = &color_blend_create_info, .pColorBlendState = &color_blend_create_info,
.pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.layout = *one_texture_pipeline_layout, .layout = *one_texture_pipeline_layout,
@@ -1241,6 +1263,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip
} }
blit_depth_stencil_keys.push_back(key); blit_depth_stencil_keys.push_back(key);
const std::array stages = MakeStages(*full_screen_vert, *blit_depth_stencil_frag); const std::array stages = MakeStages(*full_screen_vert, *blit_depth_stencil_frag);
const VkPipelineMultisampleStateCreateInfo multisample_ci = MakeMultisampleState(key.samples);
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
const VkPipelineRenderingCreateInfo rendering_ci = key.formats.CreateInfo(); const VkPipelineRenderingCreateInfo rendering_ci = key.formats.CreateInfo();
blit_depth_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ blit_depth_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
@@ -1254,7 +1277,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip
.pTessellationState = nullptr, .pTessellationState = nullptr,
.pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pMultisampleState = &multisample_ci,
.pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO, .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO,
.pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
@@ -1284,16 +1307,11 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipel
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
}; };
const VkPipelineColorBlendStateCreateInfo color_blend_state_generic_create_info{ BlendAttachments blend_attachments{};
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, blend_attachments[key.target] = color_blend_attachment_state;
.pNext = nullptr, const VkPipelineColorBlendStateCreateInfo color_blend_create_info =
.flags = 0, MakeColorBlendState(blend_attachments, key.formats);
.logicOpEnable = VK_FALSE, const VkPipelineMultisampleStateCreateInfo multisample_ci = MakeMultisampleState(key.samples);
.logicOp = VK_LOGIC_OP_CLEAR,
.attachmentCount = 1,
.pAttachments = &color_blend_attachment_state,
.blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
};
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
const VkPipelineRenderingCreateInfo rendering_ci = key.formats.CreateInfo(); const VkPipelineRenderingCreateInfo rendering_ci = key.formats.CreateInfo();
clear_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ clear_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
@@ -1307,9 +1325,9 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipel
.pTessellationState = nullptr, .pTessellationState = nullptr,
.pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pMultisampleState = &multisample_ci,
.pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_DISABLED_CREATE_INFO,
.pColorBlendState = &color_blend_state_generic_create_info, .pColorBlendState = &color_blend_create_info,
.pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.layout = *clear_color_pipeline_layout, .layout = *clear_color_pipeline_layout,
.subpass = 0, .subpass = 0,
@@ -1350,6 +1368,10 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
.minDepthBounds = 0.0f, .minDepthBounds = 0.0f,
.maxDepthBounds = 0.0f, .maxDepthBounds = 0.0f,
}; };
const BlendAttachments blend_attachments{};
const VkPipelineColorBlendStateCreateInfo color_blend_create_info =
MakeColorBlendState(blend_attachments, key.formats);
const VkPipelineMultisampleStateCreateInfo multisample_ci = MakeMultisampleState(key.samples);
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
const VkPipelineRenderingCreateInfo rendering_ci = key.formats.CreateInfo(); const VkPipelineRenderingCreateInfo rendering_ci = key.formats.CreateInfo();
clear_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ clear_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
@@ -1363,9 +1385,9 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
.pTessellationState = nullptr, .pTessellationState = nullptr,
.pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pMultisampleState = &multisample_ci,
.pDepthStencilState = &depth_stencil_ci, .pDepthStencilState = &depth_stencil_ci,
.pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO, .pColorBlendState = &color_blend_create_info,
.pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.layout = *clear_color_pipeline_layout, .layout = *clear_color_pipeline_layout,
.subpass = 0, .subpass = 0,
@@ -1716,26 +1738,30 @@ VkPipeline BlitImageHelper::FindOrEmplaceMSAACopyDepthPipeline(const MSAACopyPip
return *pipelines.back(); return *pipelines.back();
} }
void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkPipeline BlitImageHelper::FindOrEmplaceConvertPipeline(const RenderingFormats& formats,
const RenderingFormats& formats) { VkShaderModule module,
ConvertPipeline(pipeline, formats, false); VkPipelineLayout layout) {
} const ConvertPipelineKey key{
.formats = formats,
void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, .module = module,
const RenderingFormats& formats) { };
ConvertPipeline(pipeline, formats, true); const auto it = std::ranges::find(convert_keys, key);
} if (it != convert_keys.end()) {
return *convert_pipelines[std::distance(convert_keys.begin(), it)];
void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, const RenderingFormats& formats,
vk::ShaderModule& module, bool single_texture,
bool is_target_depth) {
if (pipeline) {
return;
} }
const std::array stages = MakeStages(*full_screen_vert, *module); convert_keys.push_back(key);
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); const VkPipelineDepthStencilStateCreateInfo* depth_stencil_ci = nullptr;
const VkPipelineColorBlendStateCreateInfo* color_blend_ci =
&PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO;
if (formats.num_colors == 0) {
depth_stencil_ci = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
color_blend_ci = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO;
}
const std::array stages = MakeStages(*full_screen_vert, module);
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci =
GetPipelineInputAssemblyStateCreateInfo(device);
const VkPipelineRenderingCreateInfo rendering_ci = formats.CreateInfo(); const VkPipelineRenderingCreateInfo rendering_ci = formats.CreateInfo();
pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{ convert_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = &rendering_ci, .pNext = &rendering_ci,
.flags = 0, .flags = 0,
@@ -1747,60 +1773,15 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, const RenderingF
.pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.pDepthStencilState = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr, .pDepthStencilState = depth_stencil_ci,
.pColorBlendState = is_target_depth ? &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO .pColorBlendState = color_blend_ci,
: &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
.pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.layout = single_texture ? *one_texture_pipeline_layout : *two_textures_pipeline_layout, .layout = layout,
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0, .basePipelineIndex = 0,
}); }));
} return *convert_pipelines.back();
void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline,
const RenderingFormats& formats,
vk::ShaderModule& module) {
ConvertPipelineEx(pipeline, formats, module, false, false);
}
void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline,
const RenderingFormats& formats,
vk::ShaderModule& module) {
ConvertPipelineEx(pipeline, formats, module, true, true);
}
void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, const RenderingFormats& formats,
bool is_target_depth) {
if (pipeline) {
return;
}
VkShaderModule frag_shader =
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 VkPipelineRenderingCreateInfo rendering_ci = formats.CreateInfo();
pipeline = device.GetLogical().CreateGraphicsPipeline(VkGraphicsPipelineCreateInfo{
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = &rendering_ci,
.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 = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr,
.pColorBlendState = is_target_depth ? &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO
: &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
.pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.layout = *one_texture_pipeline_layout,
.subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0,
});
} }
} // namespace Vulkan } // namespace Vulkan
+18 -28
View File
@@ -33,6 +33,8 @@ struct BlitImagePipelineKey {
RenderingFormats formats; RenderingFormats formats;
Tegra::Engines::Fermi2D::Operation operation; Tegra::Engines::Fermi2D::Operation operation;
VkSampleCountFlagBits samples;
u32 target;
}; };
struct BlitDepthStencilPipelineKey { struct BlitDepthStencilPipelineKey {
@@ -43,6 +45,14 @@ struct BlitDepthStencilPipelineKey {
u8 stencil_mask; u8 stencil_mask;
u32 stencil_compare_mask; u32 stencil_compare_mask;
u32 stencil_ref; u32 stencil_ref;
VkSampleCountFlagBits samples;
};
struct ConvertPipelineKey {
constexpr auto operator<=>(const ConvertPipelineKey&) const noexcept = default;
RenderingFormats formats;
VkShaderModule module;
}; };
enum class MSAACopyFormatClass : u32 { enum class MSAACopyFormatClass : u32 {
@@ -117,7 +127,7 @@ public:
void ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); void ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view);
void ClearColor(const Framebuffer* dst_framebuffer, u8 color_mask, void ClearColor(const Framebuffer* dst_framebuffer, u32 target, u8 color_mask,
const std::array<f32, 4>& clear_color, const Region2D& dst_region); const std::array<f32, 4>& clear_color, const Region2D& dst_region);
void ClearDepthStencil(const Framebuffer* dst_framebuffer, bool depth_clear, f32 clear_depth, void ClearDepthStencil(const Framebuffer* dst_framebuffer, bool depth_clear, f32 clear_depth,
@@ -156,10 +166,10 @@ private:
std::span<const VideoCommon::ImageCopy> copies, std::span<const VideoCommon::ImageCopy> copies,
const MSAACopyAspectInfo& aspect_info, bool copy_stencil); const MSAACopyAspectInfo& aspect_info, bool copy_stencil);
void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, void Convert(VkShaderModule module, const Framebuffer* dst_framebuffer,
const ImageView& src_image_view); const ImageView& src_image_view);
void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, void ConvertDepthStencil(VkShaderModule module, const Framebuffer* dst_framebuffer,
ImageView& src_image_view); ImageView& src_image_view);
[[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key); [[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key);
@@ -179,22 +189,9 @@ private:
[[nodiscard]] VkPipeline FindOrEmplaceBlitDepthPipeline(const RenderingFormats& formats); [[nodiscard]] VkPipeline FindOrEmplaceBlitDepthPipeline(const RenderingFormats& formats);
[[nodiscard]] VkPipeline FindOrEmplaceResolveDepthStencilPipeline( [[nodiscard]] VkPipeline FindOrEmplaceResolveDepthStencilPipeline(
const RenderingFormats& formats, bool resolve_stencil); const RenderingFormats& formats, bool resolve_stencil);
[[nodiscard]] VkPipeline FindOrEmplaceConvertPipeline(const RenderingFormats& formats,
void ConvertPipeline(vk::Pipeline& pipeline, const RenderingFormats& formats, VkShaderModule module,
bool is_target_depth); VkPipelineLayout layout);
void ConvertDepthToColorPipeline(vk::Pipeline& pipeline, const RenderingFormats& formats);
void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, const RenderingFormats& formats);
void ConvertPipelineEx(vk::Pipeline& pipeline, const RenderingFormats& formats,
vk::ShaderModule& module, bool single_texture, bool is_target_depth);
void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, const RenderingFormats& formats,
vk::ShaderModule& module);
void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, const RenderingFormats& formats,
vk::ShaderModule& module);
const Device& device; const Device& device;
Scheduler& scheduler; Scheduler& scheduler;
@@ -271,15 +268,8 @@ private:
vk::ImageView dst_view; vk::ImageView dst_view;
}; };
std::deque<MSAACopyResources> msaa_copy_resources; std::deque<MSAACopyResources> msaa_copy_resources;
vk::Pipeline convert_d32_to_r32_pipeline; std::vector<ConvertPipelineKey> convert_keys;
vk::Pipeline convert_r32_to_d32_pipeline; std::vector<vk::Pipeline> convert_pipelines;
vk::Pipeline convert_d16_to_r16_pipeline;
vk::Pipeline convert_r16_to_d16_pipeline;
vk::Pipeline convert_abgr8_to_d24s8_pipeline;
vk::Pipeline convert_abgr8_to_d32f_pipeline;
vk::Pipeline convert_d32f_to_abgr8_pipeline;
vk::Pipeline convert_d24s8_to_abgr8_pipeline;
vk::Pipeline convert_s8d24_to_abgr8_pipeline;
}; };
} // namespace Vulkan } // namespace Vulkan
@@ -1421,24 +1421,19 @@ void QueryCacheRuntime::HostConditionalRenderingCompareValueImpl(VideoCommon::Lo
impl->hcr_buffer = buffer->Handle(); impl->hcr_buffer = buffer->Handle();
impl->hcr_offset = offset; impl->hcr_offset = offset;
} }
if (impl->hcr_is_set) { VkConditionalRenderingFlagsEXT flags = 0;
if (impl->hcr_setup.buffer == impl->hcr_buffer && if (is_equal) {
impl->hcr_setup.offset == impl->hcr_offset) { flags = VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT;
return;
}
} }
bool was_running = impl->is_hcr_running; if (impl->hcr_is_set && impl->hcr_setup.buffer == impl->hcr_buffer &&
if (was_running) { impl->hcr_setup.offset == impl->hcr_offset && impl->hcr_setup.flags == flags) {
PauseHostConditionalRendering(); return;
} }
PauseHostConditionalRendering();
impl->hcr_setup.buffer = impl->hcr_buffer; impl->hcr_setup.buffer = impl->hcr_buffer;
impl->hcr_setup.offset = impl->hcr_offset; impl->hcr_setup.offset = impl->hcr_offset;
impl->hcr_setup.flags = is_equal ? VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT : 0; impl->hcr_setup.flags = flags;
impl->hcr_is_set = true; impl->hcr_is_set = true;
impl->is_hcr_running = false;
if (was_running) {
ResumeHostConditionalRendering();
}
} }
void QueryCacheRuntime::HostConditionalRenderingCompareBCImpl(DAddr address, bool is_equal, void QueryCacheRuntime::HostConditionalRenderingCompareBCImpl(DAddr address, bool is_equal,
@@ -1455,20 +1450,16 @@ void QueryCacheRuntime::HostConditionalRenderingCompareBCImpl(DAddr address, boo
to_resolve = buffer->Handle(); to_resolve = buffer->Handle();
to_resolve_offset = static_cast<u32>(offset); to_resolve_offset = static_cast<u32>(offset);
} }
bool was_running = impl->is_hcr_running; PauseHostConditionalRendering();
if (was_running) {
PauseHostConditionalRendering();
}
impl->conditional_resolve_pass->Resolve(*impl->hcr_resolve_buffer, to_resolve, impl->conditional_resolve_pass->Resolve(*impl->hcr_resolve_buffer, to_resolve,
to_resolve_offset, compare_to_zero); to_resolve_offset, compare_to_zero);
impl->hcr_setup.buffer = *impl->hcr_resolve_buffer; impl->hcr_setup.buffer = *impl->hcr_resolve_buffer;
impl->hcr_setup.offset = 0; impl->hcr_setup.offset = 0;
impl->hcr_setup.flags = is_equal ? 0 : VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT; impl->hcr_setup.flags = 0;
impl->hcr_is_set = true; if (!is_equal) {
impl->is_hcr_running = false; impl->hcr_setup.flags = VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT;
if (was_running) {
ResumeHostConditionalRendering();
} }
impl->hcr_is_set = true;
} }
bool QueryCacheRuntime::HostConditionalRenderingCompareValue(VideoCommon::LookupData object_1, bool QueryCacheRuntime::HostConditionalRenderingCompareValue(VideoCommon::LookupData object_1,
@@ -550,7 +550,8 @@ void RasterizerVulkan::Clear(u32 layer_count) {
Offset2D{.x = clear_rect.rect.offset.x + s32(clear_rect.rect.extent.width), Offset2D{.x = clear_rect.rect.offset.x + s32(clear_rect.rect.extent.width),
.y = clear_rect.rect.offset.y + s32(clear_rect.rect.extent.height)}}; .y = clear_rect.rect.offset.y + s32(clear_rect.rect.extent.height)}};
request_renderpass(); request_renderpass();
blit_image.ClearColor(framebuffer, color_mask, regs.clear_color, dst_region); blit_image.ClearColor(framebuffer, color_attachment, color_mask, regs.clear_color,
dst_region);
} else if (!clear_on_load || } else if (!clear_on_load ||
!scheduler.OverrideLoadOps(framebuffer, 1u << color_attachment, !scheduler.OverrideLoadOps(framebuffer, 1u << color_attachment,
VK_ATTACHMENT_LOAD_OP_CLEAR, clear_value)) { VK_ATTACHMENT_LOAD_OP_CLEAR, clear_value)) {
@@ -4,8 +4,10 @@
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <span>
#include <thread> #include <thread>
#include <utility> #include <utility>
@@ -116,6 +118,7 @@ void Scheduler::DispatchWork() {
} }
event_cv.notify_all(); event_cv.notify_all();
recorded_attachments = nullptr; recorded_attachments = nullptr;
ended_attachments = nullptr;
AcquireNewChunk(); AcquireNewChunk();
} }
} }
@@ -169,29 +172,41 @@ bool Scheduler::OverrideLoadOps(const Framebuffer* framebuffer, u32 attachments,
if (!renderpass_pristine || recorded_attachments == nullptr) { if (!renderpass_pristine || recorded_attachments == nullptr) {
return false; return false;
} }
const auto set_load_op = [&](VkRenderingAttachmentInfo& attachment, bool discards_msaa) { const auto set_load_op = [&](VkRenderingAttachmentInfo& attachment) {
attachment.loadOp = load_op; attachment.loadOp = load_op;
attachment.clearValue = value; attachment.clearValue = value;
if (discards_msaa && load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
}; };
for (u32 slot = 0; slot < recorded_attachments->num_colors; ++slot) { for (u32 slot = 0; slot < recorded_attachments->num_colors; ++slot) {
if ((attachments & (1u << slot)) != 0) { if ((attachments & (1u << slot)) != 0) {
set_load_op(recorded_attachments->colors[slot], framebuffer->DiscardsMsaaColor()); set_load_op(recorded_attachments->colors[slot]);
} }
} }
if ((attachments & DEPTH_ATTACHMENT_BIT) != 0) { if ((attachments & DEPTH_ATTACHMENT_BIT) != 0) {
set_load_op(recorded_attachments->depth, framebuffer->DiscardsMsaaDepthStencil()); set_load_op(recorded_attachments->depth);
} }
if ((attachments & STENCIL_ATTACHMENT_BIT) != 0) { if ((attachments & STENCIL_ATTACHMENT_BIT) != 0) {
set_load_op(recorded_attachments->stencil, framebuffer->DiscardsMsaaDepthStencil()); set_load_op(recorded_attachments->stencil);
} }
attachments_touched |= attachments; attachments_touched |= attachments;
attachments_written |= attachments; attachments_written |= attachments;
return true; return true;
} }
void Scheduler::DiscardResolvedAttachments(VkImageView resolve_view) {
if (ended_attachments == nullptr) {
return;
}
const auto discard = [resolve_view](VkRenderingAttachmentInfo& attachment) {
if (attachment.resolveImageView == resolve_view) {
attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
};
std::ranges::for_each(std::span(ended_attachments->colors).first(ended_attachments->num_colors),
discard);
discard(ended_attachments->depth);
discard(ended_attachments->stencil);
}
void Scheduler::RequestOutsideRenderPassOperationContext() { void Scheduler::RequestOutsideRenderPassOperationContext() {
EndRenderPass(); EndRenderPass();
PublishComputeWrites(); PublishComputeWrites();
@@ -420,8 +435,8 @@ void Scheduler::EndRenderPass()
} }
if (recorded_attachments != nullptr) { if (recorded_attachments != nullptr) {
RelaxAttachmentOps(*recorded_attachments); RelaxAttachmentOps(*recorded_attachments);
recorded_attachments = nullptr;
} }
ended_attachments = std::exchange(recorded_attachments, nullptr);
query_cache->CounterClose(VideoCommon::QueryType::StreamingByteCount); query_cache->CounterClose(VideoCommon::QueryType::StreamingByteCount);
@@ -69,6 +69,8 @@ public:
bool OverrideLoadOps(const Framebuffer* framebuffer, u32 attachments, bool OverrideLoadOps(const Framebuffer* framebuffer, u32 attachments,
VkAttachmentLoadOp load_op, const VkClearValue& value); VkAttachmentLoadOp load_op, const VkClearValue& value);
void DiscardResolvedAttachments(VkImageView resolve_view);
/// Requests the current execution context to be able to execute operations only allowed outside /// Requests the current execution context to be able to execute operations only allowed outside
/// of a renderpass. /// of a renderpass.
void RequestOutsideRenderPassOperationContext(); void RequestOutsideRenderPassOperationContext();
@@ -338,6 +340,7 @@ private:
u32 attachments_touched = 0; u32 attachments_touched = 0;
u32 attachments_written = 0; u32 attachments_written = 0;
RenderingAttachments* recorded_attachments = nullptr; RenderingAttachments* recorded_attachments = nullptr;
RenderingAttachments* ended_attachments = nullptr;
VkMemoryBarrier2 renderpass_write_barrier{}; VkMemoryBarrier2 renderpass_write_barrier{};
VkMemoryBarrier2 compute_write_barrier{}; VkMemoryBarrier2 compute_write_barrier{};
VkMemoryBarrier2 upload_write_barrier{}; VkMemoryBarrier2 upload_write_barrier{};
@@ -1838,6 +1838,11 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, region); VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, region);
cmdbuf.PipelineBarrier(0, {}, {}, post_barriers); cmdbuf.PipelineBarrier(0, {}, {}, post_barriers);
}); });
const bool is_color = aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT;
if ((is_color && ENABLE_MSAA_COLOR_DISCARD) ||
(!is_color && ENABLE_MSAA_DEPTH_STENCIL_DISCARD)) {
scheduler.DiscardResolvedAttachments(*shadow->view);
}
return; return;
} }
} }
@@ -3076,11 +3081,6 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
samples != VK_SAMPLE_COUNT_1_BIT && depth_image != VK_NULL_HANDLE && samples != VK_SAMPLE_COUNT_1_BIT && depth_image != VK_NULL_HANDLE &&
runtime.device.IsTiler() && SupportsDepthStencilResolve(runtime.device, depth_format); runtime.device.IsTiler() && SupportsDepthStencilResolve(runtime.device, depth_format);
discard_msaa_color =
ENABLE_MSAA_RESOLVE_CONSUME && ENABLE_MSAA_COLOR_DISCARD && do_resolve_color;
discard_msaa_depth_stencil = ENABLE_MSAA_RESOLVE_CONSUME &&
ENABLE_MSAA_DEPTH_STENCIL_DISCARD && do_resolve_depth_stencil;
runtime_ptr = &runtime; runtime_ptr = &runtime;
id = ++runtime.framebuffer_serial; id = ++runtime.framebuffer_serial;
render_area.width = (std::min)(render_area.width, width); render_area.width = (std::min)(render_area.width, width);
@@ -250,14 +250,6 @@ public:
return is_rescaled; return is_rescaled;
} }
[[nodiscard]] bool DiscardsMsaaColor() const noexcept {
return discard_msaa_color;
}
[[nodiscard]] bool DiscardsMsaaDepthStencil() const noexcept {
return discard_msaa_depth_stencil;
}
/// Records that a render pass has begun, so its resolve attachments will hold valid contents /// Records that a render pass has begun, so its resolve attachments will hold valid contents
/// once it ends. /// once it ends.
void MarkResolveShadowsUpToDate() const; void MarkResolveShadowsUpToDate() const;
@@ -278,8 +270,6 @@ private:
std::array<VkImage, 9> resolve_shadow_images{}; std::array<VkImage, 9> resolve_shadow_images{};
u32 num_resolve_shadows = 0; u32 num_resolve_shadows = 0;
TextureCacheRuntime* runtime_ptr{nullptr}; TextureCacheRuntime* runtime_ptr{nullptr};
bool discard_msaa_color{};
bool discard_msaa_depth_stencil{};
}; };
class Image : public VideoCommon::ImageBase { class Image : public VideoCommon::ImageBase {