mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-22 23:50:32 +00:00
[TEST] Save space with Sync2
This commit is contained in:
@@ -1068,10 +1068,12 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
|
||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||
};
|
||||
const std::array pre_barriers{
|
||||
VkImageMemoryBarrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
VkImageMemoryBarrier2{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.pNext = nullptr,
|
||||
.srcStageMask = aspect_info.pre_src_stages,
|
||||
.srcAccessMask = aspect_info.pre_src_access,
|
||||
.dstStageMask = aspect_info.pre_src_dst_stages,
|
||||
.dstAccessMask = aspect_info.pre_src_dst_access,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
@@ -1080,10 +1082,12 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
|
||||
.image = src,
|
||||
.subresourceRange = barrier_range,
|
||||
},
|
||||
VkImageMemoryBarrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
VkImageMemoryBarrier2{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.pNext = nullptr,
|
||||
.srcStageMask = aspect_info.pre_src_stages,
|
||||
.srcAccessMask = aspect_info.pre_src_access,
|
||||
.dstStageMask = aspect_info.pre_dst_dst_stages,
|
||||
.dstAccessMask = aspect_info.pre_dst_dst_access,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
@@ -1093,8 +1097,7 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
|
||||
.subresourceRange = barrier_range,
|
||||
},
|
||||
};
|
||||
cmdbuf.PipelineBarrier(aspect_info.pre_src_stages, aspect_info.pre_dst_stages, 0,
|
||||
nullptr, nullptr, pre_barriers);
|
||||
cmdbuf.PipelineBarrier2Images(0, pre_barriers);
|
||||
const VkRenderPassBeginInfo renderpass_bi{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -1130,10 +1133,12 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
|
||||
cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, push_constants);
|
||||
cmdbuf.Draw(3, 1, 0, 0);
|
||||
cmdbuf.EndRenderPass();
|
||||
const VkImageMemoryBarrier post_barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
const VkImageMemoryBarrier2 post_barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.pNext = nullptr,
|
||||
.srcStageMask = aspect_info.post_src_stages,
|
||||
.srcAccessMask = aspect_info.post_src_access,
|
||||
.dstStageMask = aspect_info.post_dst_stages,
|
||||
.dstAccessMask = aspect_info.post_dst_access,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
@@ -1142,8 +1147,7 @@ void BlitImageHelper::CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline,
|
||||
.image = dst,
|
||||
.subresourceRange = barrier_range,
|
||||
};
|
||||
cmdbuf.PipelineBarrier(aspect_info.post_src_stages, aspect_info.post_dst_stages, 0,
|
||||
post_barrier);
|
||||
cmdbuf.PipelineBarrier2Images(0, post_barrier);
|
||||
});
|
||||
msaa_copy_resources.push_back(MSAACopyResources{
|
||||
.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,
|
||||
.attachment_aspect = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.barrier_aspect = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.pre_src_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT |
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.pre_src_dst_access = VK_ACCESS_SHADER_READ_BIT,
|
||||
.pre_src_access = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_SHADER_WRITE_BIT |
|
||||
VK_ACCESS_2_TRANSFER_WRITE_BIT,
|
||||
.pre_src_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT,
|
||||
.pre_dst_dst_access =
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.pre_src_stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
.pre_dst_stages =
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.post_src_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.post_dst_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT,
|
||||
.post_src_stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.post_dst_stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.pre_src_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_2_TRANSFER_BIT,
|
||||
.pre_src_dst_stages = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
.pre_dst_dst_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.post_src_access = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.post_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT | VK_ACCESS_2_TRANSFER_READ_BIT,
|
||||
.post_src_stages = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_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 =
|
||||
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,
|
||||
.barrier_aspect = attachment_aspect,
|
||||
.pre_src_access =
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.pre_src_dst_access = VK_ACCESS_SHADER_READ_BIT,
|
||||
.pre_dst_dst_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.pre_src_stages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
.pre_dst_stages =
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.post_src_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.post_dst_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
||||
.post_src_stages = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_2_TRANSFER_WRITE_BIT,
|
||||
.pre_src_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT,
|
||||
.pre_dst_dst_access = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.pre_src_stages = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_2_TRANSFER_BIT,
|
||||
.pre_src_dst_stages = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
.pre_dst_dst_stages = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.post_src_access = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.post_dst_access = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT | VK_ACCESS_2_TRANSFER_READ_BIT |
|
||||
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
||||
.post_src_stages = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
|
||||
.post_dst_stages = vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER,
|
||||
};
|
||||
const VkFormat src_vk_format =
|
||||
|
||||
@@ -140,15 +140,16 @@ private:
|
||||
VkImageAspectFlags src_view_aspect;
|
||||
VkImageAspectFlags attachment_aspect;
|
||||
VkImageAspectFlags barrier_aspect;
|
||||
VkAccessFlags pre_src_access;
|
||||
VkAccessFlags pre_src_dst_access;
|
||||
VkAccessFlags pre_dst_dst_access;
|
||||
VkPipelineStageFlags pre_src_stages;
|
||||
VkPipelineStageFlags pre_dst_stages;
|
||||
VkAccessFlags post_src_access;
|
||||
VkAccessFlags post_dst_access;
|
||||
VkPipelineStageFlags post_src_stages;
|
||||
VkPipelineStageFlags post_dst_stages;
|
||||
VkAccessFlags2 pre_src_access;
|
||||
VkAccessFlags2 pre_src_dst_access;
|
||||
VkAccessFlags2 pre_dst_dst_access;
|
||||
VkPipelineStageFlags2 pre_src_stages;
|
||||
VkPipelineStageFlags2 pre_src_dst_stages;
|
||||
VkPipelineStageFlags2 pre_dst_dst_stages;
|
||||
VkAccessFlags2 post_src_access;
|
||||
VkAccessFlags2 post_dst_access;
|
||||
VkPipelineStageFlags2 post_src_stages;
|
||||
VkPipelineStageFlags2 post_dst_stages;
|
||||
};
|
||||
|
||||
void CopyMSAAImpl(VkRenderPass renderpass, VkPipeline pipeline, VkPipelineLayout layout,
|
||||
|
||||
@@ -363,8 +363,6 @@ void RasterizerVulkan::DrawTexture() {
|
||||
|
||||
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& sampler = texture_cache.GetSampler(draw_texture_state.src_sampler, false);
|
||||
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;
|
||||
if (!can_defer_clear) {
|
||||
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);
|
||||
|
||||
const u32 color_attachment = regs.clear_surface.RT;
|
||||
@@ -1877,19 +1875,13 @@ void RasterizerVulkan::UpdateColorWriteEnable(Tegra::Engines::Maxwell3D::Regs& r
|
||||
if (!state_tracker.TouchColorMask()) {
|
||||
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{};
|
||||
for (size_t index = 0; index < Maxwell::NumRenderTargets; 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;
|
||||
}
|
||||
scheduler.Record([setup_enables, num_attachments](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetColorWriteEnableEXT(vk::Span<VkBool32>(setup_enables.data(), num_attachments));
|
||||
scheduler.Record([setup_enables](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetColorWriteEnableEXT(setup_enables);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -331,10 +331,6 @@ VkRenderPass RenderPassCache::Get(const RenderPassKey& key) {
|
||||
};
|
||||
if (device->HasSynchronization2()) {
|
||||
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{
|
||||
.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
|
||||
|
||||
@@ -421,18 +421,21 @@ void Scheduler::EndRenderPass()
|
||||
Record([num_images = num_renderpass_images,
|
||||
images = renderpass_images,
|
||||
ranges = renderpass_image_ranges,
|
||||
consumer_stages = device.AttachmentConsumerStages(),
|
||||
shader_stages = device.ShaderConsumerStages(),
|
||||
has_transform_feedback = device.IsExtTransformFeedbackSupported()](
|
||||
vk::CommandBuffer cmdbuf) {
|
||||
static constexpr VkAccessFlags SHADER_ACCESS =
|
||||
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
|
||||
static constexpr VkAccessFlags COLOR_ACCESS =
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
static constexpr VkAccessFlags DEPTH_STENCIL_ACCESS =
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
static constexpr VkAccessFlags2 SHADER_ACCESS =
|
||||
VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT;
|
||||
static constexpr VkAccessFlags2 COLOR_ACCESS =
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
static constexpr VkAccessFlags2 DEPTH_STENCIL_ACCESS =
|
||||
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_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) {
|
||||
const VkImageSubresourceRange& range = ranges[i];
|
||||
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_STENCIL_BIT)) !=0;
|
||||
|
||||
VkAccessFlags src_access = 0;
|
||||
VkAccessFlags dst_access = SHADER_ACCESS;
|
||||
VkPipelineStageFlags2 src_stages = 0;
|
||||
VkAccessFlags2 src_access = 0;
|
||||
VkPipelineStageFlags2 dst_stages = shader_stages;
|
||||
VkAccessFlags2 dst_access = SHADER_ACCESS;
|
||||
|
||||
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;
|
||||
} 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;
|
||||
} else {
|
||||
src_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
||||
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
src_stages |= VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_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;
|
||||
}
|
||||
|
||||
barriers[i] = VkImageMemoryBarrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
barriers[i] = VkImageMemoryBarrier2{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.pNext = nullptr,
|
||||
.srcStageMask = src_stages,
|
||||
.srcAccessMask = src_access,
|
||||
.dstStageMask = dst_stages,
|
||||
.dstAccessMask = dst_access,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
@@ -469,19 +484,19 @@ void Scheduler::EndRenderPass()
|
||||
};
|
||||
}
|
||||
cmdbuf.EndRenderPass();
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, consumer_stages,
|
||||
0, nullptr, nullptr, vk::Span(barriers.data(), num_images));
|
||||
cmdbuf.PipelineBarrier2Images(0, vk::Span(barriers.data(), num_images));
|
||||
if (has_transform_feedback) {
|
||||
static constexpr VkMemoryBarrier XFB_OUTPUT_BARRIER{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
|
||||
static constexpr VkMemoryBarrier2 XFB_OUTPUT_BARRIER{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT,
|
||||
.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT,
|
||||
.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,
|
||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, XFB_OUTPUT_BARRIER);
|
||||
cmdbuf.PipelineBarrier2Memory(0, XFB_OUTPUT_BARRIER);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1027,14 +1027,11 @@ FN_MAX_LIMIT_LIST
|
||||
return features2.features.geometryShader;
|
||||
}
|
||||
|
||||
VkPipelineStageFlags AttachmentConsumerStages() const {
|
||||
VkPipelineStageFlags ShaderConsumerStages() const {
|
||||
VkPipelineStageFlags stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_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;
|
||||
if (features2.features.geometryShader) {
|
||||
stages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
|
||||
@@ -1042,6 +1039,12 @@ FN_MAX_LIMIT_LIST
|
||||
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.
|
||||
bool IsKhrMaintenance1Supported() const {
|
||||
return extensions.maintenance1;
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging.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
|
||||
|
||||
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 {
|
||||
#define X(name) Proc(dld.name, dld, #name)
|
||||
return X(vkCreateInstance) && X(vkEnumerateInstanceExtensionProperties) &&
|
||||
|
||||
@@ -158,6 +158,41 @@ inline constexpr VkPipelineStageFlags PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER_H
|
||||
|
||||
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.
|
||||
struct InstanceDispatch {
|
||||
@@ -1197,6 +1232,12 @@ private:
|
||||
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 {
|
||||
public:
|
||||
CommandBuffer() noexcept = default;
|
||||
@@ -1347,78 +1388,45 @@ public:
|
||||
VkDependencyFlags dependency_flags, Span<VkMemoryBarrier> memory_barriers,
|
||||
Span<VkBufferMemoryBarrier> buffer_barriers,
|
||||
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,
|
||||
memory_barriers.size(), memory_barriers.data(),
|
||||
buffer_barriers.size(), buffer_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,
|
||||
VkDependencyFlags dependency_flags = 0) const noexcept {
|
||||
PipelineBarrier(src_stage_mask, dst_stage_mask, dependency_flags, {}, {}, {});
|
||||
|
||||
Reference in New Issue
Block a user