renderer_vulkan: barrier attachment feedback loops

This commit is contained in:
Liam 2023-05-22 01:13:47 -04:00
parent f82efe9f65
commit 8758932031
6 changed files with 51 additions and 1 deletions

View file

@ -144,6 +144,10 @@ public:
return state_tracker; return state_tracker;
} }
void BarrierFeedbackLoop() const noexcept {
// OpenGL does not require a barrier for attachment feedback loops.
}
private: private:
struct StagingBuffers { struct StagingBuffers {
explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_); explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_);

View file

@ -481,12 +481,13 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
if constexpr (Spec::enabled_stages[4]) { if constexpr (Spec::enabled_stages[4]) {
prepare_stage(4); prepare_stage(4);
} }
texture_cache.UpdateRenderTargets(false);
texture_cache.CheckFeedbackLoop(views);
ConfigureDraw(rescaling, render_area); ConfigureDraw(rescaling, render_area);
} }
void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling, void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling,
const RenderAreaPushConstant& render_area) { const RenderAreaPushConstant& render_area) {
texture_cache.UpdateRenderTargets(false);
scheduler.RequestRenderpass(texture_cache.GetFramebuffer()); scheduler.RequestRenderpass(texture_cache.GetFramebuffer());
if (!is_built.load(std::memory_order::relaxed)) { if (!is_built.load(std::memory_order::relaxed)) {

View file

@ -861,6 +861,10 @@ VkBuffer TextureCacheRuntime::GetTemporaryBuffer(size_t needed_size) {
return *buffers[level]; return *buffers[level];
} }
void TextureCacheRuntime::BarrierFeedbackLoop() {
scheduler.RequestOutsideRenderPassOperationContext();
}
void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src, void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
std::span<const VideoCommon::ImageCopy> copies) { std::span<const VideoCommon::ImageCopy> copies) {
std::vector<VkBufferImageCopy> vk_in_copies(copies.size()); std::vector<VkBufferImageCopy> vk_in_copies(copies.size());

View file

@ -103,6 +103,8 @@ public:
[[nodiscard]] VkBuffer GetTemporaryBuffer(size_t needed_size); [[nodiscard]] VkBuffer GetTemporaryBuffer(size_t needed_size);
void BarrierFeedbackLoop();
const Device& device; const Device& device;
Scheduler& scheduler; Scheduler& scheduler;
MemoryAllocator& memory_allocator; MemoryAllocator& memory_allocator;

View file

@ -183,6 +183,42 @@ void TextureCache<P>::FillComputeImageViews(std::span<ImageViewInOut> views) {
views); views);
} }
template <class P>
void TextureCache<P>::CheckFeedbackLoop(std::span<const ImageViewInOut> views) {
const bool requires_barrier = [&] {
for (const auto& view : views) {
if (!view.id) {
continue;
}
auto& image_view = slot_image_views[view.id];
// Check color targets
for (const auto& ct_view_id : render_targets.color_buffer_ids) {
if (ct_view_id) {
auto& ct_view = slot_image_views[ct_view_id];
if (image_view.image_id == ct_view.image_id) {
return true;
}
}
}
// Check zeta target
if (render_targets.depth_buffer_id) {
auto& zt_view = slot_image_views[render_targets.depth_buffer_id];
if (image_view.image_id == zt_view.image_id) {
return true;
}
}
}
return false;
}();
if (requires_barrier) {
runtime.BarrierFeedbackLoop();
}
}
template <class P> template <class P>
typename P::Sampler* TextureCache<P>::GetGraphicsSampler(u32 index) { typename P::Sampler* TextureCache<P>::GetGraphicsSampler(u32 index) {
if (index > channel_state->graphics_sampler_table.Limit()) { if (index > channel_state->graphics_sampler_table.Limit()) {

View file

@ -148,6 +148,9 @@ public:
/// Fill image_view_ids with the compute images in indices /// Fill image_view_ids with the compute images in indices
void FillComputeImageViews(std::span<ImageViewInOut> views); void FillComputeImageViews(std::span<ImageViewInOut> views);
/// Handle feedback loops during draws.
void CheckFeedbackLoop(std::span<const ImageViewInOut> views);
/// Get the sampler from the graphics descriptor table in the specified index /// Get the sampler from the graphics descriptor table in the specified index
Sampler* GetGraphicsSampler(u32 index); Sampler* GetGraphicsSampler(u32 index);