forked from suyu/suyu
Merge pull request #10402 from liamwhite/uh
renderer_vulkan: barrier attachment feedback loops
This commit is contained in:
commit
58be9b12f4
6 changed files with 51 additions and 1 deletions
|
@ -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_);
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue