diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 603a042ba2..186cf35278 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -291,55 +291,93 @@ void TextureCache
::CheckFeedbackLoop(std::span ::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 +459,18 @@ void TextureCache ::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 +584,7 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
return;
}
+ const RenderTargets previous_render_targets = render_targets;
const bool rescaled = RescaleRenderTargets();
if (is_rescaling != rescaled) {
flags[Dirty::RescaleViewports] = true;
@@ -549,6 +600,70 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
+ rt_active_mask = 0;
+ const ImageViewId rt0_view = render_targets.color_buffer_ids[0];
+ if (rt0_view) {
+ rt_active_mask |= (1u << 0);
+ rt0_image_id = slot_image_views[rt0_view].image_id;
+ } else {
+ rt0_image_id = ImageId{};
+ }
+ const ImageViewId rt1_view = render_targets.color_buffer_ids[1];
+ if (rt1_view) {
+ rt_active_mask |= (1u << 1);
+ rt1_image_id = slot_image_views[rt1_view].image_id;
+ } else {
+ rt1_image_id = ImageId{};
+ }
+ const ImageViewId rt2_view = render_targets.color_buffer_ids[2];
+ if (rt2_view) {
+ rt_active_mask |= (1u << 2);
+ rt2_image_id = slot_image_views[rt2_view].image_id;
+ } else {
+ rt2_image_id = ImageId{};
+ }
+ const ImageViewId rt3_view = render_targets.color_buffer_ids[3];
+ if (rt3_view) {
+ rt_active_mask |= (1u << 3);
+ rt3_image_id = slot_image_views[rt3_view].image_id;
+ } else {
+ rt3_image_id = ImageId{};
+ }
+ const ImageViewId rt4_view = render_targets.color_buffer_ids[4];
+ if (rt4_view) {
+ rt_active_mask |= (1u << 4);
+ rt4_image_id = slot_image_views[rt4_view].image_id;
+ } else {
+ rt4_image_id = ImageId{};
+ }
+ const ImageViewId rt5_view = render_targets.color_buffer_ids[5];
+ if (rt5_view) {
+ rt_active_mask |= (1u << 5);
+ rt5_image_id = slot_image_views[rt5_view].image_id;
+ } else {
+ rt5_image_id = ImageId{};
+ }
+ const ImageViewId rt6_view = render_targets.color_buffer_ids[6];
+ if (rt6_view) {
+ rt_active_mask |= (1u << 6);
+ rt6_image_id = slot_image_views[rt6_view].image_id;
+ } else {
+ rt6_image_id = ImageId{};
+ }
+ const ImageViewId rt7_view = render_targets.color_buffer_ids[7];
+ if (rt7_view) {
+ rt_active_mask |= (1u << 7);
+ rt7_image_id = slot_image_views[rt7_view].image_id;
+ } else {
+ rt7_image_id = ImageId{};
+ }
+ 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 ::UpdateRenderTargets(bool is_clear) {
};
render_targets.is_rescaled = is_rescaling;
+ if (render_targets != previous_render_targets) {
+ ++render_targets_serial;
+ }
+
flags[Dirty::DepthBiasGlobal] = true;
}
template ::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 ::RemoveFramebuffers(std::span