Use pipeline barriers, as opposed to an ext dependency for RP barrier

Allows for waiting on compute shaders, which are not a graphics stage.
This commit is contained in:
Billy Laws 2023-02-13 18:01:02 +00:00
parent ee68facc5d
commit 6ee8a919e5
2 changed files with 24 additions and 18 deletions

View File

@ -6,14 +6,7 @@
#include <vulkan/vulkan_enums.hpp> #include <vulkan/vulkan_enums.hpp>
namespace skyline::gpu::interconnect::node { namespace skyline::gpu::interconnect::node {
RenderPassNode::RenderPassNode(vk::Rect2D renderArea) RenderPassNode::RenderPassNode(vk::Rect2D renderArea) : renderArea{renderArea} {}
: externalDependency{vk::SubpassDependency{
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcAccessMask = vk::AccessFlagBits::eMemoryWrite,
.dstAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite,
}},
renderArea{renderArea} {}
u32 RenderPassNode::AddAttachment(TextureView *view, GPU &gpu) { u32 RenderPassNode::AddAttachment(TextureView *view, GPU &gpu) {
auto vkView{view->GetView()}; auto vkView{view->GetView()};
@ -41,15 +34,18 @@ namespace skyline::gpu::interconnect::node {
}); });
if (auto usage{view->texture->GetLastRenderPassUsage()}; usage != texture::RenderPassUsage::None) { if (auto usage{view->texture->GetLastRenderPassUsage()}; usage != texture::RenderPassUsage::None) {
vk::PipelineStageFlags attachmentDstStageMask{};
if (view->format->vkAspect & vk::ImageAspectFlagBits::eColor) if (view->format->vkAspect & vk::ImageAspectFlagBits::eColor)
externalDependency.dstStageMask |= vk::PipelineStageFlagBits::eColorAttachmentOutput; attachmentDstStageMask |= vk::PipelineStageFlagBits::eColorAttachmentOutput;
else if (view->format->vkAspect & (vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil)) else if (view->format->vkAspect & (vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil))
externalDependency.dstStageMask |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; attachmentDstStageMask |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests;
dependencyDstStageMask |= attachmentDstStageMask;
if (usage == texture::RenderPassUsage::RenderTarget) if (usage == texture::RenderPassUsage::RenderTarget)
externalDependency.srcStageMask |= externalDependency.dstStageMask; dependencySrcStageMask |= attachmentDstStageMask;
else if (usage == texture::RenderPassUsage::Sampled) else if (usage == texture::RenderPassUsage::Sampled)
externalDependency.srcStageMask |= vk::PipelineStageFlagBits::eAllGraphics; dependencySrcStageMask |= view->texture->GetReadStageMask();
} }
return static_cast<u32>(attachments.size() - 1); return static_cast<u32>(attachments.size() - 1);
@ -173,8 +169,8 @@ namespace skyline::gpu::interconnect::node {
} }
void RenderPassNode::UpdateDependency(vk::PipelineStageFlags srcStageMask, vk::PipelineStageFlags dstStageMask) { void RenderPassNode::UpdateDependency(vk::PipelineStageFlags srcStageMask, vk::PipelineStageFlags dstStageMask) {
externalDependency.srcStageMask |= srcStageMask; dependencySrcStageMask |= srcStageMask;
externalDependency.dstStageMask |= dstStageMask; dependencyDstStageMask |= dstStageMask;
} }
bool RenderPassNode::ClearColorAttachment(u32 colorAttachment, const vk::ClearColorValue &value, GPU& gpu) { bool RenderPassNode::ClearColorAttachment(u32 colorAttachment, const vk::ClearColorValue &value, GPU& gpu) {
@ -240,8 +236,12 @@ namespace skyline::gpu::interconnect::node {
preserveAttachmentIt++; preserveAttachmentIt++;
} }
if (externalDependency.srcStageMask && externalDependency.dstStageMask) if (dependencyDstStageMask && dependencySrcStageMask) {
subpassDependencies.push_back(externalDependency); commandBuffer.pipelineBarrier(dependencySrcStageMask, dependencyDstStageMask, {}, {vk::MemoryBarrier{
.srcAccessMask = vk::AccessFlagBits::eMemoryWrite,
.dstAccessMask = vk::AccessFlagBits::eMemoryWrite | vk::AccessFlagBits::eMemoryRead,
}}, {}, {});
}
auto renderPass{gpu.renderPassCache.GetRenderPass(vk::RenderPassCreateInfo{ auto renderPass{gpu.renderPassCache.GetRenderPass(vk::RenderPassCreateInfo{
.attachmentCount = static_cast<u32>(attachmentDescriptions.size()), .attachmentCount = static_cast<u32>(attachmentDescriptions.size()),

View File

@ -48,7 +48,8 @@ namespace skyline::gpu::interconnect::node {
public: public:
std::vector<vk::SubpassDescription> subpassDescriptions; std::vector<vk::SubpassDescription> subpassDescriptions;
std::vector<vk::SubpassDependency> subpassDependencies; std::vector<vk::SubpassDependency> subpassDependencies;
vk::SubpassDependency externalDependency; vk::PipelineStageFlags dependencySrcStageMask;
vk::PipelineStageFlags dependencyDstStageMask;
vk::Rect2D renderArea; vk::Rect2D renderArea;
std::vector<vk::ClearValue> clearValues; std::vector<vk::ClearValue> clearValues;
@ -64,7 +65,12 @@ namespace skyline::gpu::interconnect::node {
/** /**
* @brief Creates a subpass with the attachments bound in the specified order * @brief Creates a subpass with the attachments bound in the specified order
*/ */
void AddSubpass(span<TextureView *> inputAttachments, span<TextureView *> colorAttachments, TextureView *depthStencilAttachment, GPU &gpu, vk::PipelineStageFlags srcStageMask, vk::PipelineStageFlags dstStageMask); void AddSubpass(span<TextureView *> inputAttachments, span<TextureView *> colorAttachments, TextureView *depthStencilAttachment, GPU &gpu);
/**
* @brief Updates the dependency barrier for the renderpass
*/
void UpdateDependency(vk::PipelineStageFlags srcStageMask, vk::PipelineStageFlags dstStageMask);
/** /**
* @brief Clears a color attachment in the current subpass with VK_ATTACHMENT_LOAD_OP_CLEAR * @brief Clears a color attachment in the current subpass with VK_ATTACHMENT_LOAD_OP_CLEAR