Loosen some texture WaR sync when possible

By keeping track of the stages reading the image we can do more fine-grained WaR prevention, as opposed to waiting for all commands to complete.
This commit is contained in:
Billy Laws 2023-02-13 18:02:13 +00:00
parent 6ee8a919e5
commit d45f9e4d26
3 changed files with 23 additions and 8 deletions

View File

@ -151,7 +151,7 @@ namespace skyline::gpu::interconnect {
std::array<TextureView *, 1> sampledImages{srcTextureView.get()};
executor.AddSubpass(std::move(executionCallback), {{static_cast<i32>(dstRectX), static_cast<i32>(dstRectY)}, {dstRectWidth, dstRectHeight} },
sampledImages, {}, {dst}, {}, false,
vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eAllCommands);
vk::PipelineStageFlagBits::eAllGraphics, vk::PipelineStageFlagBits::eAllGraphics);
}
);

View File

@ -1007,22 +1007,31 @@ namespace skyline::gpu {
lastRenderPassUsage = renderPassUsage;
lastRenderPassIndex = renderPassIndex;
if (renderPassUsage == texture::RenderPassUsage::RenderTarget)
if (renderPassUsage == texture::RenderPassUsage::RenderTarget) {
pendingStageMask = vk::PipelineStageFlagBits::eVertexShader |
vk::PipelineStageFlagBits::eTessellationControlShader |
vk::PipelineStageFlagBits::eTessellationEvaluationShader |
vk::PipelineStageFlagBits::eGeometryShader |
vk::PipelineStageFlagBits::eFragmentShader |
vk::PipelineStageFlagBits::eComputeShader;
else if (renderPassUsage == texture::RenderPassUsage::None)
vk::PipelineStageFlagBits::eTessellationControlShader |
vk::PipelineStageFlagBits::eTessellationEvaluationShader |
vk::PipelineStageFlagBits::eGeometryShader |
vk::PipelineStageFlagBits::eFragmentShader |
vk::PipelineStageFlagBits::eComputeShader;
readStageMask = {};
} else if (renderPassUsage == texture::RenderPassUsage::None) {
pendingStageMask = {};
readStageMask = {};
}
}
texture::RenderPassUsage Texture::GetLastRenderPassUsage() {
return lastRenderPassUsage;
}
vk::PipelineStageFlags Texture::GetReadStageMask() {
return readStageMask;
}
void Texture::PopulateReadBarrier(vk::PipelineStageFlagBits dstStage, vk::PipelineStageFlags &srcStageMask, vk::PipelineStageFlags &dstStageMask) {
readStageMask |= dstStage;
if (!(pendingStageMask & dstStage))
return;

View File

@ -411,6 +411,7 @@ namespace skyline::gpu {
u32 lastRenderPassIndex{}; //!< The index of the last render pass that used this texture
texture::RenderPassUsage lastRenderPassUsage{texture::RenderPassUsage::None}; //!< The type of usage in the last render pass
vk::PipelineStageFlags pendingStageMask{}; //!< List of pipeline stages that are yet to be flushed for reads since the last time this texture was used an an RT
vk::PipelineStageFlags readStageMask{}; //!< Set of pipeline stages that this texture has been read in since it was last used as an RT
friend TextureManager;
friend TextureView;
@ -613,6 +614,11 @@ namespace skyline::gpu {
*/
texture::RenderPassUsage GetLastRenderPassUsage();
/**
* @return The set of stages this texture has been read in since it was last used as an RT
*/
vk::PipelineStageFlags GetReadStageMask();
/**
* @brief Populates the input src and dst stage masks with appropriate read barrier parameters for the current texture state
*/