aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache/texture_cache.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/texture_cache/texture_cache.h')
-rw-r--r--src/video_core/texture_cache/texture_cache.h110
1 files changed, 78 insertions, 32 deletions
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 9f31c68cd2..71210ffe6e 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -291,55 +291,59 @@ void TextureCache<P>::CheckFeedbackLoop(std::span<const ImageViewInOut> views) {
return;
}
+ if (render_targets_serial == last_feedback_loop_serial &&
+ texture_bindings_serial == last_feedback_texture_serial) {
+ if (last_feedback_loop_result) {
+ runtime.BarrierFeedbackLoop();
+ }
+ return;
+ }
+
+ if (rt_active_mask == 0) {
+ last_feedback_loop_serial = render_targets_serial;
+ last_feedback_texture_serial = texture_bindings_serial;
+ last_feedback_loop_result = false;
+ return;
+ }
+ const u32 depth_bit = 1u << NUM_RT;
+ const bool depth_active = (rt_active_mask & depth_bit) != 0;
+
const bool requires_barrier = [&] {
for (const auto& view : views) {
if (!view.id) {
continue;
}
- bool is_render_target = false;
-
- for (const auto& ct_view_id : render_targets.color_buffer_ids) {
- if (ct_view_id && ct_view_id == view.id) {
- is_render_target = true;
- break;
- }
- }
-
- if (!is_render_target && render_targets.depth_buffer_id == view.id) {
- is_render_target = true;
+ {
+ bool is_continue = false;
+ for (size_t i = 0; i < 8; ++i)
+ is_continue |= (rt_active_mask & (1u << i)) && view.id == render_targets.color_buffer_ids[i];
+ if (is_continue)
+ continue;
}
- if (is_render_target) {
+ if (depth_active && view.id == render_targets.depth_buffer_id)
continue;
- }
- auto& image_view = slot_image_views[view.id];
-
- for (const auto& ct_view_id : render_targets.color_buffer_ids) {
- if (!ct_view_id) {
+ const ImageId view_image_id = slot_image_views[view.id].image_id;
+ {
+ bool is_continue = false;
+ for (size_t i = 0; i < 8; ++i)
+ is_continue |= (rt_active_mask & (1u << i)) && view_image_id == rt_image_id[i];
+ if (is_continue)
continue;
- }
-
- auto& ct_view = slot_image_views[ct_view_id];
-
- if (image_view.image_id == ct_view.image_id) {
- return true;
- }
}
-
- 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;
- }
+ if (depth_active && view_image_id == rt_depth_image_id) {
+ return true;
}
}
return false;
}();
+ last_feedback_loop_serial = render_targets_serial;
+ last_feedback_texture_serial = texture_bindings_serial;
+ last_feedback_loop_result = requires_barrier;
if (requires_barrier) {
runtime.BarrierFeedbackLoop();
}
@@ -399,13 +403,19 @@ void TextureCache<P>::SynchronizeGraphicsDescriptors() {
const bool linked_tsc = maxwell3d->regs.sampler_binding == SamplerBinding::ViaHeaderBinding;
const u32 tic_limit = maxwell3d->regs.tex_header.limit;
const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tex_sampler.limit;
+ bool bindings_changed = false;
if (channel_state->graphics_sampler_table.Synchronize(maxwell3d->regs.tex_sampler.Address(),
tsc_limit)) {
channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
+ bindings_changed = true;
}
if (channel_state->graphics_image_table.Synchronize(maxwell3d->regs.tex_header.Address(),
tic_limit)) {
channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
+ bindings_changed = true;
+ }
+ if (bindings_changed) {
+ ++texture_bindings_serial;
}
}
@@ -415,12 +425,18 @@ void TextureCache<P>::SynchronizeComputeDescriptors() {
const u32 tic_limit = kepler_compute->regs.tic.limit;
const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute->regs.tsc.limit;
const GPUVAddr tsc_gpu_addr = kepler_compute->regs.tsc.Address();
+ bool bindings_changed = false;
if (channel_state->compute_sampler_table.Synchronize(tsc_gpu_addr, tsc_limit)) {
channel_state->compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
+ bindings_changed = true;
}
if (channel_state->compute_image_table.Synchronize(kepler_compute->regs.tic.Address(),
tic_limit)) {
channel_state->compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
+ bindings_changed = true;
+ }
+ if (bindings_changed) {
+ ++texture_bindings_serial;
}
}
@@ -534,6 +550,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
return;
}
+ const VideoCommon::RenderTargets previous_render_targets = render_targets;
const bool rescaled = RescaleRenderTargets();
if (is_rescaling != rescaled) {
flags[Dirty::RescaleViewports] = true;
@@ -549,6 +566,21 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
+ rt_active_mask = 0;
+ rt_image_id = {};
+ for (size_t i = 0; i < rt_image_id.size(); ++i) {
+ if (ImageViewId const view = render_targets.color_buffer_ids[i]; view) {
+ rt_active_mask |= 1u << i;
+ rt_image_id[i] = slot_image_views[view].image_id;
+ }
+ }
+ if (depth_buffer_id) {
+ rt_active_mask |= (1u << NUM_RT);
+ rt_depth_image_id = slot_image_views[depth_buffer_id].image_id;
+ } else {
+ rt_depth_image_id = ImageId{};
+ }
+
for (size_t index = 0; index < NUM_RT; ++index) {
render_targets.draw_buffers[index] = static_cast<u8>(maxwell3d->regs.rt_control.Map(index));
}
@@ -564,12 +596,22 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
};
render_targets.is_rescaled = is_rescaling;
+ if (render_targets != previous_render_targets) {
+ ++render_targets_serial;
+ }
+
flags[Dirty::DepthBiasGlobal] = true;
}
template <class P>
typename P::Framebuffer* TextureCache<P>::GetFramebuffer() {
- return &slot_framebuffers[GetFramebufferId(render_targets)];
+ if (last_framebuffer_id && last_framebuffer_serial == render_targets_serial) {
+ return &slot_framebuffers[last_framebuffer_id];
+ }
+ const FramebufferId framebuffer_id = GetFramebufferId(render_targets);
+ last_framebuffer_id = framebuffer_id;
+ last_framebuffer_serial = render_targets_serial;
+ return &slot_framebuffers[framebuffer_id];
}
template <class P>
@@ -2610,6 +2652,10 @@ void TextureCache<P>::RemoveFramebuffers(std::span<const ImageViewId> removed_vi
if (it->first.Contains(removed_views)) {
auto framebuffer_id = it->second;
ASSERT(framebuffer_id);
+ if (framebuffer_id == last_framebuffer_id) {
+ last_framebuffer_id = {};
+ last_framebuffer_serial = 0;
+ }
sentenced_framebuffers.Push(std::move(slot_framebuffers[framebuffer_id]));
it = framebuffers.erase(it);
} else {