[TEST] Save space with Sync2

This commit is contained in:
CamilleLaVey
2026-08-22 04:42:36 -04:00
parent e0d4318042
commit 518f571fcf
8 changed files with 252 additions and 159 deletions
+43 -37
View File
@@ -1068,10 +1068,12 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
.layerCount = VK_REMAINING_ARRAY_LAYERS, .layerCount = VK_REMAINING_ARRAY_LAYERS,
}; };
const std::array pre_barriers{ const std::array pre_barriers{
VkImageMemoryBarrier{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = aspect_info.pre_src_stages,
.srcAccessMask = aspect_info.pre_src_access, .srcAccessMask = aspect_info.pre_src_access,
.dstStageMask = aspect_info.pre_src_dst_stages,
.dstAccessMask = aspect_info.pre_src_dst_access, .dstAccessMask = aspect_info.pre_src_dst_access,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1080,10 +1082,12 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
.image = src, .image = src,
.subresourceRange = barrier_range, .subresourceRange = barrier_range,
}, },
VkImageMemoryBarrier{ VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = aspect_info.pre_src_stages,
.srcAccessMask = aspect_info.pre_src_access, .srcAccessMask = aspect_info.pre_src_access,
.dstStageMask = aspect_info.pre_dst_dst_stages,
.dstAccessMask = aspect_info.pre_dst_dst_access, .dstAccessMask = aspect_info.pre_dst_dst_access,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1093,8 +1097,7 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
.subresourceRange = barrier_range, .subresourceRange = barrier_range,
}, },
}; };
cmdbuf.PipelineBarrier(aspect_info.pre_src_stages, aspect_info.pre_dst_stages, 0, cmdbuf.PipelineBarrier2Images(0, pre_barriers);
nullptr, nullptr, pre_barriers);
const VkRenderPassBeginInfo renderpass_bi{ const VkRenderPassBeginInfo renderpass_bi{
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.pNext = nullptr, .pNext = nullptr,
@@ -1130,10 +1133,12 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, push_constants); cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, push_constants);
cmdbuf.Draw(3, 1, 0, 0); cmdbuf.Draw(3, 1, 0, 0);
cmdbuf.EndRenderPass(); cmdbuf.EndRenderPass();
const VkImageMemoryBarrier post_barrier{ const VkImageMemoryBarrier2 post_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = aspect_info.post_src_stages,
.srcAccessMask = aspect_info.post_src_access, .srcAccessMask = aspect_info.post_src_access,
.dstStageMask = aspect_info.post_dst_stages,
.dstAccessMask = aspect_info.post_dst_access, .dstAccessMask = aspect_info.post_dst_access,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -1142,8 +1147,7 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
.image = dst, .image = dst,
.subresourceRange = barrier_range, .subresourceRange = barrier_range,
}; };
cmdbuf.PipelineBarrier(aspect_info.post_src_stages, aspect_info.post_dst_stages, 0, cmdbuf.PipelineBarrier2Images(0, post_barrier);
post_barrier);
}); });
msaa_copy_resources.push_back(MSAACopyResources{ msaa_copy_resources.push_back(MSAACopyResources{
.tick = scheduler.CurrentTick(), .tick = scheduler.CurrentTick(),
@@ -1192,21 +1196,23 @@ void BlitImageHelper::CopyMSAA(RenderPassCache& render_pass_cache, VkImage dst_i
.src_view_aspect = VK_IMAGE_ASPECT_COLOR_BIT, .src_view_aspect = VK_IMAGE_ASPECT_COLOR_BIT,
.attachment_aspect = VK_IMAGE_ASPECT_COLOR_BIT, .attachment_aspect = VK_IMAGE_ASPECT_COLOR_BIT,
.barrier_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 | .pre_src_access = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_SHADER_WRITE_BIT |
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT,
.pre_src_dst_access = VK_ACCESS_SHADER_READ_BIT, .pre_src_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT,
.pre_dst_dst_access = .pre_dst_dst_access =
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.pre_src_stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | .pre_src_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
.pre_dst_stages = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, .pre_src_dst_stages = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
.post_src_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, .pre_dst_dst_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
.post_dst_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, .post_src_access = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
.post_src_stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, .post_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT | VK_ACCESS_2_TRANSFER_READ_BIT,
.post_dst_stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | .post_src_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, .post_dst_stages = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_2_TRANSFER_BIT,
}; };
const VkFormat src_vk_format = const VkFormat src_vk_format =
MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, src_format).format; MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, true, src_format).format;
@@ -1702,19 +1708,19 @@ void BlitImageHelper::CopyMSAADepth(RenderPassCache& render_pass_cache, VkImage
.attachment_aspect = attachment_aspect, .attachment_aspect = attachment_aspect,
.barrier_aspect = attachment_aspect, .barrier_aspect = attachment_aspect,
.pre_src_access = .pre_src_access =
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT,
.pre_src_dst_access = VK_ACCESS_SHADER_READ_BIT, .pre_src_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT,
.pre_dst_dst_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | .pre_dst_dst_access = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.pre_src_stages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | .pre_src_stages = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.pre_dst_stages = .pre_src_dst_stages = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, .pre_dst_dst_stages = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT,
.post_src_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .post_src_access = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.post_dst_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | .post_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT | VK_ACCESS_2_TRANSFER_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
.post_src_stages = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, .post_src_stages = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
.post_dst_stages = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, .post_dst_stages = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER,
}; };
const VkFormat src_vk_format = const VkFormat src_vk_format =
+10 -9
View File
@@ -140,15 +140,16 @@ private:
VkImageAspectFlags src_view_aspect; VkImageAspectFlags src_view_aspect;
VkImageAspectFlags attachment_aspect; VkImageAspectFlags attachment_aspect;
VkImageAspectFlags barrier_aspect; VkImageAspectFlags barrier_aspect;
VkAccessFlags pre_src_access; VkAccessFlags2 pre_src_access;
VkAccessFlags pre_src_dst_access; VkAccessFlags2 pre_src_dst_access;
VkAccessFlags pre_dst_dst_access; VkAccessFlags2 pre_dst_dst_access;
VkPipelineStageFlags pre_src_stages; VkPipelineStageFlags2 pre_src_stages;
VkPipelineStageFlags pre_dst_stages; VkPipelineStageFlags2 pre_src_dst_stages;
VkAccessFlags post_src_access; VkPipelineStageFlags2 pre_dst_dst_stages;
VkAccessFlags post_dst_access; VkAccessFlags2 post_src_access;
VkPipelineStageFlags post_src_stages; VkAccessFlags2 post_dst_access;
VkPipelineStageFlags post_dst_stages; VkPipelineStageFlags2 post_src_stages;
VkPipelineStageFlags2 post_dst_stages;
}; };
void CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline, VkPipelineLayout layout, void CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline, VkPipelineLayout layout,
@@ -363,8 +363,6 @@ void RasterizerVulkan::DrawTexture() {
UpdateDynamicStates(); UpdateDynamicStates();
query_cache.NotifySegment(true);
query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, maxwell3d->regs.zpass_pixel_count_enable);
const auto& draw_texture_state = maxwell3d->draw_manager.draw_texture_state; const auto& draw_texture_state = maxwell3d->draw_manager.draw_texture_state;
const auto& sampler = texture_cache.GetSampler(draw_texture_state.src_sampler, false); const auto& sampler = texture_cache.GetSampler(draw_texture_state.src_sampler, false);
const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture); const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture);
@@ -495,10 +493,10 @@ void RasterizerVulkan::Clear(u32 layer_count) {
(!use_color || color_full_channels) && ds_deferrable; (!use_color || color_full_channels) && ds_deferrable;
if (!can_defer_clear) { if (!can_defer_clear) {
scheduler.RequestRenderpass(framebuffer); scheduler.RequestRenderpass(framebuffer);
query_cache.NotifySegment(true);
query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, maxwell3d->regs.zpass_pixel_count_enable);
} }
query_cache.NotifySegment(true);
query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, maxwell3d->regs.zpass_pixel_count_enable);
UpdateViewportsState(regs); UpdateViewportsState(regs);
const u32 color_attachment = regs.clear_surface.RT; const u32 color_attachment = regs.clear_surface.RT;
@@ -1877,19 +1875,13 @@ void RasterizerVulkan::UpdateColorWriteEnable(Tegra::Engines::Maxwell3D::Regs& r
if (!state_tracker.TouchColorMask()) { if (!state_tracker.TouchColorMask()) {
return; return;
} }
size_t num_attachments{};
for (size_t index = 0; index < Maxwell::NumRenderTargets; index++) {
if (regs.rt[index].format != Tegra::RenderTargetFormat::NONE) {
num_attachments = index + 1;
}
}
std::array<VkBool32, Maxwell::NumRenderTargets> setup_enables{}; std::array<VkBool32, Maxwell::NumRenderTargets> setup_enables{};
for (size_t index = 0; index < Maxwell::NumRenderTargets; index++) { for (size_t index = 0; index < Maxwell::NumRenderTargets; index++) {
const auto& mask = regs.color_mask[regs.color_mask_common ? 0 : index]; const auto& mask = regs.color_mask[regs.color_mask_common ? 0 : index];
setup_enables[index] = (mask.R || mask.G || mask.B || mask.A) ? VK_TRUE : VK_FALSE; setup_enables[index] = (mask.R || mask.G || mask.B || mask.A) ? VK_TRUE : VK_FALSE;
} }
scheduler.Record([setup_enables, num_attachments](vk::CommandBuffer cmdbuf) { scheduler.Record([setup_enables](vk::CommandBuffer cmdbuf) {
cmdbuf.SetColorWriteEnableEXT(vk::Span<VkBool32>(setup_enables.data(), num_attachments)); cmdbuf.SetColorWriteEnableEXT(setup_enables);
}); });
} }
@@ -331,10 +331,6 @@ VkRenderPass RenderPassCache::Get(const RenderPassKey& key) {
}; };
if (device->HasSynchronization2()) { if (device->HasSynchronization2()) {
counter_resume_dependency2.pNext = &counter_resume_barrier; counter_resume_dependency2.pNext = &counter_resume_barrier;
counter_resume_dependency2.srcStageMask = 0;
counter_resume_dependency2.dstStageMask = 0;
counter_resume_dependency2.srcAccessMask = 0;
counter_resume_dependency2.dstAccessMask = 0;
} }
const VkSubpassDependency2 feedback_loop_dependency2{ const VkSubpassDependency2 feedback_loop_dependency2{
.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, .sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
+42 -27
View File
@@ -421,18 +421,21 @@ void Scheduler::EndRenderPass()
Record([num_images = num_renderpass_images, Record([num_images = num_renderpass_images,
images = renderpass_images, images = renderpass_images,
ranges = renderpass_image_ranges, ranges = renderpass_image_ranges,
consumer_stages = device.AttachmentConsumerStages(), shader_stages = device.ShaderConsumerStages(),
has_transform_feedback = device.IsExtTransformFeedbackSupported()]( has_transform_feedback = device.IsExtTransformFeedbackSupported()](
vk::CommandBuffer cmdbuf) { vk::CommandBuffer cmdbuf) {
static constexpr VkAccessFlags SHADER_ACCESS = static constexpr VkAccessFlags2 SHADER_ACCESS =
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT;
static constexpr VkAccessFlags COLOR_ACCESS = static constexpr VkAccessFlags2 COLOR_ACCESS =
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
static constexpr VkAccessFlags DEPTH_STENCIL_ACCESS = static constexpr VkAccessFlags2 DEPTH_STENCIL_ACCESS =
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
static constexpr VkPipelineStageFlags2 DEPTH_STENCIL_STAGES =
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT;
std::array<VkImageMemoryBarrier, 9> barriers; std::array<VkImageMemoryBarrier2, 9> barriers;
for (size_t i = 0; i < num_images; ++i) { for (size_t i = 0; i < num_images; ++i) {
const VkImageSubresourceRange& range = ranges[i]; const VkImageSubresourceRange& range = ranges[i];
const bool is_color = (range.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0; const bool is_color = (range.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0;
@@ -440,25 +443,37 @@ void Scheduler::EndRenderPass()
& (VK_IMAGE_ASPECT_DEPTH_BIT & (VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT)) !=0; | VK_IMAGE_ASPECT_STENCIL_BIT)) !=0;
VkAccessFlags src_access = 0; VkPipelineStageFlags2 src_stages = 0;
VkAccessFlags dst_access = SHADER_ACCESS; VkAccessFlags2 src_access = 0;
VkPipelineStageFlags2 dst_stages = shader_stages;
VkAccessFlags2 dst_access = SHADER_ACCESS;
if (is_color) { if (is_color) {
src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; src_stages |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
src_access |= VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
dst_stages |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
dst_access |= COLOR_ACCESS; dst_access |= COLOR_ACCESS;
} else if (is_depth_stencil) { } else if (is_depth_stencil) {
src_access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; src_stages |= DEPTH_STENCIL_STAGES;
src_access |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dst_stages |= DEPTH_STENCIL_STAGES;
dst_access |= DEPTH_STENCIL_ACCESS; dst_access |= DEPTH_STENCIL_ACCESS;
} else { } else {
src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT src_stages |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; | DEPTH_STENCIL_STAGES;
src_access |= VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT
| VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dst_stages |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT
| DEPTH_STENCIL_STAGES;
dst_access |= COLOR_ACCESS | DEPTH_STENCIL_ACCESS; dst_access |= COLOR_ACCESS | DEPTH_STENCIL_ACCESS;
} }
barriers[i] = VkImageMemoryBarrier{ barriers[i] = VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcStageMask = src_stages,
.srcAccessMask = src_access, .srcAccessMask = src_access,
.dstStageMask = dst_stages,
.dstAccessMask = dst_access, .dstAccessMask = dst_access,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL,
@@ -469,19 +484,19 @@ void Scheduler::EndRenderPass()
}; };
} }
cmdbuf.EndRenderPass(); cmdbuf.EndRenderPass();
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | cmdbuf.PipelineBarrier2Images(0, vk::Span(barriers.data(), num_images));
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, consumer_stages,
0, nullptr, nullptr, vk::Span(barriers.data(), num_images));
if (has_transform_feedback) { if (has_transform_feedback) {
static constexpr VkMemoryBarrier XFB_OUTPUT_BARRIER{ static constexpr VkMemoryBarrier2 XFB_OUTPUT_BARRIER{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr, .pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT,
.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT,
.dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT |
VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT |
VK_ACCESS_2_TRANSFER_READ_BIT,
}; };
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, cmdbuf.PipelineBarrier2Memory(0, XFB_OUTPUT_BARRIER);
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
0, XFB_OUTPUT_BARRIER);
} }
}); });
+7 -4
View File
@@ -1027,14 +1027,11 @@ FN_MAX_LIMIT_LIST
return features2.features.geometryShader; return features2.features.geometryShader;
} }
VkPipelineStageFlags AttachmentConsumerStages() const { VkPipelineStageFlags ShaderConsumerStages() const {
VkPipelineStageFlags stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VkPipelineStageFlags stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
if (features2.features.geometryShader) { if (features2.features.geometryShader) {
stages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT; stages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
@@ -1042,6 +1039,12 @@ FN_MAX_LIMIT_LIST
return stages; return stages;
} }
VkPipelineStageFlags AttachmentConsumerStages() const {
return ShaderConsumerStages() | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
}
/// Returns true if the device supports VK_KHR_maintenance1. /// Returns true if the device supports VK_KHR_maintenance1.
bool IsKhrMaintenance1Supported() const { bool IsKhrMaintenance1Supported() const {
return extensions.maintenance1; return extensions.maintenance1;
@@ -10,6 +10,8 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <boost/container/small_vector.hpp>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging.h" #include "common/logging.h"
#include "video_core/vulkan_common/vk_enum_string_helper.h" #include "video_core/vulkan_common/vk_enum_string_helper.h"
@@ -296,6 +298,76 @@ void SetObjectName(const DeviceDispatch* dld, VkDevice device, T handle, VkObjec
} // Anonymous namespace } // Anonymous namespace
void PipelineBarrierDowngrade(const DeviceDispatch& dld, VkCommandBuffer handle,
VkDependencyFlags dependency_flags,
Span<VkMemoryBarrier2> memory_barriers,
Span<VkBufferMemoryBarrier2> buffer_barriers,
Span<VkImageMemoryBarrier2> image_barriers) {
VkPipelineStageFlags2 src_stages = 0;
VkPipelineStageFlags2 dst_stages = 0;
for (const VkMemoryBarrier2& barrier : memory_barriers) {
src_stages |= barrier.srcStageMask;
dst_stages |= barrier.dstStageMask;
}
for (const VkBufferMemoryBarrier2& barrier : buffer_barriers) {
src_stages |= barrier.srcStageMask;
dst_stages |= barrier.dstStageMask;
}
for (const VkImageMemoryBarrier2& barrier : image_barriers) {
src_stages |= barrier.srcStageMask;
dst_stages |= barrier.dstStageMask;
}
boost::container::small_vector<VkMemoryBarrier, 4> memory;
memory.reserve(memory_barriers.size());
for (const VkMemoryBarrier2& barrier : memory_barriers) {
memory.push_back(VkMemoryBarrier{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = DowngradeAccessMask(barrier.srcAccessMask),
.dstAccessMask = DowngradeAccessMask(barrier.dstAccessMask),
});
}
boost::container::small_vector<VkBufferMemoryBarrier, 4> buffers;
buffers.reserve(buffer_barriers.size());
for (const VkBufferMemoryBarrier2& barrier : buffer_barriers) {
buffers.push_back(VkBufferMemoryBarrier{
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = DowngradeAccessMask(barrier.srcAccessMask),
.dstAccessMask = DowngradeAccessMask(barrier.dstAccessMask),
.srcQueueFamilyIndex = barrier.srcQueueFamilyIndex,
.dstQueueFamilyIndex = barrier.dstQueueFamilyIndex,
.buffer = barrier.buffer,
.offset = barrier.offset,
.size = barrier.size,
});
}
boost::container::small_vector<VkImageMemoryBarrier, 9> images;
images.reserve(image_barriers.size());
for (const VkImageMemoryBarrier2& barrier : image_barriers) {
images.push_back(VkImageMemoryBarrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = DowngradeAccessMask(barrier.srcAccessMask),
.dstAccessMask = DowngradeAccessMask(barrier.dstAccessMask),
.oldLayout = barrier.oldLayout,
.newLayout = barrier.newLayout,
.srcQueueFamilyIndex = barrier.srcQueueFamilyIndex,
.dstQueueFamilyIndex = barrier.dstQueueFamilyIndex,
.image = barrier.image,
.subresourceRange = barrier.subresourceRange,
});
}
dld.vkCmdPipelineBarrier(handle,
DowngradeStageMask(src_stages, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT),
DowngradeStageMask(dst_stages, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT),
dependency_flags, static_cast<u32>(memory.size()), memory.data(),
static_cast<u32>(buffers.size()), buffers.data(),
static_cast<u32>(images.size()), images.data());
}
bool Load(InstanceDispatch& dld) noexcept { bool Load(InstanceDispatch& dld) noexcept {
#define X(name) Proc(dld.name, dld, #name) #define X(name) Proc(dld.name, dld, #name)
return X(vkCreateInstance) && X(vkEnumerateInstanceExtensionProperties) && return X(vkCreateInstance) && X(vkEnumerateInstanceExtensionProperties) &&
+74 -66
View File
@@ -158,6 +158,41 @@ inline constexpr VkPipelineStageFlags PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER_H
inline constexpr VkPipelineStageFlags PIPELINE_STAGE_HOST = VK_PIPELINE_STAGE_HOST_BIT; inline constexpr VkPipelineStageFlags PIPELINE_STAGE_HOST = VK_PIPELINE_STAGE_HOST_BIT;
constexpr VkPipelineStageFlags DowngradeStageMask(VkPipelineStageFlags2 mask,
VkPipelineStageFlags empty) noexcept {
VkPipelineStageFlags result = static_cast<VkPipelineStageFlags>(mask & 0xFFFFFFFFULL);
if ((mask & (VK_PIPELINE_STAGE_2_COPY_BIT | VK_PIPELINE_STAGE_2_RESOLVE_BIT |
VK_PIPELINE_STAGE_2_BLIT_BIT | VK_PIPELINE_STAGE_2_CLEAR_BIT)) != 0) {
result |= VK_PIPELINE_STAGE_TRANSFER_BIT;
}
if ((mask & VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT) != 0) {
result |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
}
if ((mask & VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT) != 0) {
result |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
}
if ((mask & VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT) != 0) {
result |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
}
if (result == 0) {
return empty;
}
return result;
}
constexpr VkAccessFlags DowngradeAccessMask(VkAccessFlags2 mask) noexcept {
VkAccessFlags result = static_cast<VkAccessFlags>(mask & 0xFFFFFFFFULL);
if ((mask & (VK_ACCESS_2_SHADER_SAMPLED_READ_BIT | VK_ACCESS_2_SHADER_STORAGE_READ_BIT)) != 0) {
result |= VK_ACCESS_SHADER_READ_BIT;
}
if ((mask & VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT) != 0) {
result |= VK_ACCESS_SHADER_WRITE_BIT;
}
return result;
}
/// Table holding Vulkan instance function pointers. /// Table holding Vulkan instance function pointers.
struct InstanceDispatch { struct InstanceDispatch {
@@ -1197,6 +1232,12 @@ private:
const InstanceDispatch* dld = nullptr; const InstanceDispatch* dld = nullptr;
}; };
void PipelineBarrierDowngrade(const DeviceDispatch& dld, VkCommandBuffer handle,
VkDependencyFlags dependency_flags,
Span<VkMemoryBarrier2> memory_barriers,
Span<VkBufferMemoryBarrier2> buffer_barriers,
Span<VkImageMemoryBarrier2> image_barriers);
class CommandBuffer { class CommandBuffer {
public: public:
CommandBuffer() noexcept = default; CommandBuffer() noexcept = default;
@@ -1347,78 +1388,45 @@ public:
VkDependencyFlags dependency_flags, Span<VkMemoryBarrier> memory_barriers, VkDependencyFlags dependency_flags, Span<VkMemoryBarrier> memory_barriers,
Span<VkBufferMemoryBarrier> buffer_barriers, Span<VkBufferMemoryBarrier> buffer_barriers,
Span<VkImageMemoryBarrier> image_barriers) const noexcept { Span<VkImageMemoryBarrier> image_barriers) const noexcept {
static constexpr u32 MaxBarriers = 16;
if (dld->vkCmdPipelineBarrier2 && memory_barriers.size() <= MaxBarriers &&
buffer_barriers.size() <= MaxBarriers && image_barriers.size() <= MaxBarriers) {
const auto src_stage_mask2 = static_cast<VkPipelineStageFlags2>(src_stage_mask);
const auto dst_stage_mask2 = static_cast<VkPipelineStageFlags2>(dst_stage_mask);
std::array<VkMemoryBarrier2, MaxBarriers> memory_barriers2;
for (u32 i = 0; i < memory_barriers.size(); ++i) {
memory_barriers2[i] = VkMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = src_stage_mask2,
.srcAccessMask = static_cast<VkAccessFlags2>(memory_barriers[i].srcAccessMask),
.dstStageMask = dst_stage_mask2,
.dstAccessMask = static_cast<VkAccessFlags2>(memory_barriers[i].dstAccessMask),
};
}
std::array<VkBufferMemoryBarrier2, MaxBarriers> buffer_barriers2;
for (u32 i = 0; i < buffer_barriers.size(); ++i) {
const auto& barrier = buffer_barriers[i];
buffer_barriers2[i] = VkBufferMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = src_stage_mask2,
.srcAccessMask = static_cast<VkAccessFlags2>(barrier.srcAccessMask),
.dstStageMask = dst_stage_mask2,
.dstAccessMask = static_cast<VkAccessFlags2>(barrier.dstAccessMask),
.srcQueueFamilyIndex = barrier.srcQueueFamilyIndex,
.dstQueueFamilyIndex = barrier.dstQueueFamilyIndex,
.buffer = barrier.buffer,
.offset = barrier.offset,
.size = barrier.size,
};
}
std::array<VkImageMemoryBarrier2, MaxBarriers> image_barriers2;
for (u32 i = 0; i < image_barriers.size(); ++i) {
const auto& barrier = image_barriers[i];
image_barriers2[i] = VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = src_stage_mask2,
.srcAccessMask = static_cast<VkAccessFlags2>(barrier.srcAccessMask),
.dstStageMask = dst_stage_mask2,
.dstAccessMask = static_cast<VkAccessFlags2>(barrier.dstAccessMask),
.oldLayout = barrier.oldLayout,
.newLayout = barrier.newLayout,
.srcQueueFamilyIndex = barrier.srcQueueFamilyIndex,
.dstQueueFamilyIndex = barrier.dstQueueFamilyIndex,
.image = barrier.image,
.subresourceRange = barrier.subresourceRange,
};
}
const VkDependencyInfo dependency_info{
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
.pNext = nullptr,
.dependencyFlags = dependency_flags,
.memoryBarrierCount = memory_barriers.size(),
.pMemoryBarriers = memory_barriers2.data(),
.bufferMemoryBarrierCount = buffer_barriers.size(),
.pBufferMemoryBarriers = buffer_barriers2.data(),
.imageMemoryBarrierCount = image_barriers.size(),
.pImageMemoryBarriers = image_barriers2.data(),
};
dld->vkCmdPipelineBarrier2(handle, &dependency_info);
return;
}
dld->vkCmdPipelineBarrier(handle, src_stage_mask, dst_stage_mask, dependency_flags, dld->vkCmdPipelineBarrier(handle, src_stage_mask, dst_stage_mask, dependency_flags,
memory_barriers.size(), memory_barriers.data(), memory_barriers.size(), memory_barriers.data(),
buffer_barriers.size(), buffer_barriers.data(), buffer_barriers.size(), buffer_barriers.data(),
image_barriers.size(), image_barriers.data()); image_barriers.size(), image_barriers.data());
} }
void PipelineBarrier2(VkDependencyFlags dependency_flags,
Span<VkMemoryBarrier2> memory_barriers,
Span<VkBufferMemoryBarrier2> buffer_barriers,
Span<VkImageMemoryBarrier2> image_barriers) const noexcept {
if (!dld->vkCmdPipelineBarrier2) {
PipelineBarrierDowngrade(*dld, handle, dependency_flags, memory_barriers,
buffer_barriers, image_barriers);
return;
}
const VkDependencyInfo dependency_info{
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
.pNext = nullptr,
.dependencyFlags = dependency_flags,
.memoryBarrierCount = memory_barriers.size(),
.pMemoryBarriers = memory_barriers.data(),
.bufferMemoryBarrierCount = buffer_barriers.size(),
.pBufferMemoryBarriers = buffer_barriers.data(),
.imageMemoryBarrierCount = image_barriers.size(),
.pImageMemoryBarriers = image_barriers.data(),
};
dld->vkCmdPipelineBarrier2(handle, &dependency_info);
}
void PipelineBarrier2Images(VkDependencyFlags dependency_flags,
Span<VkImageMemoryBarrier2> image_barriers) const noexcept {
PipelineBarrier2(dependency_flags, {}, {}, image_barriers);
}
void PipelineBarrier2Memory(VkDependencyFlags dependency_flags,
Span<VkMemoryBarrier2> memory_barriers) const noexcept {
PipelineBarrier2(dependency_flags, memory_barriers, {}, {});
}
void PipelineBarrier(VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, void PipelineBarrier(VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask,
VkDependencyFlags dependency_flags = 0) const noexcept { VkDependencyFlags dependency_flags = 0) const noexcept {
PipelineBarrier(src_stage_mask, dst_stage_mask, dependency_flags, {}, {}, {}); PipelineBarrier(src_stage_mask, dst_stage_mask, dependency_flags, {}, {}, {});