summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index d004199ba..a75de4384 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -405,8 +405,6 @@ private:
405 u32 written_compute_texture_buffers = 0; 405 u32 written_compute_texture_buffers = 0;
406 u32 image_compute_texture_buffers = 0; 406 u32 image_compute_texture_buffers = 0;
407 407
408 std::array<u32, NUM_STAGES> fast_bound_uniform_buffers{};
409
410 std::array<u32, 16> uniform_cache_hits{}; 408 std::array<u32, 16> uniform_cache_hits{};
411 std::array<u32, 16> uniform_cache_shots{}; 409 std::array<u32, 16> uniform_cache_shots{};
412 410
@@ -416,6 +414,10 @@ private:
416 414
417 std::conditional_t<HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS, std::array<u32, NUM_STAGES>, Empty> 415 std::conditional_t<HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS, std::array<u32, NUM_STAGES>, Empty>
418 dirty_uniform_buffers{}; 416 dirty_uniform_buffers{};
417 std::conditional_t<IS_OPENGL, std::array<u32, NUM_STAGES>, Empty> fast_bound_uniform_buffers{};
418 std::conditional_t<HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS,
419 std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFERS>, NUM_STAGES>, Empty>
420 uniform_buffer_binding_sizes{};
419 421
420 std::vector<BufferId> cached_write_buffer_ids; 422 std::vector<BufferId> cached_write_buffer_ids;
421 423
@@ -684,6 +686,7 @@ void BufferCache<P>::SetUniformBuffersState(const std::array<u32, NUM_STAGES>& m
684 fast_bound_uniform_buffers.fill(0); 686 fast_bound_uniform_buffers.fill(0);
685 } 687 }
686 dirty_uniform_buffers.fill(~u32{0}); 688 dirty_uniform_buffers.fill(~u32{0});
689 uniform_buffer_binding_sizes.fill({});
687 } 690 }
688 } 691 }
689 enabled_uniform_buffer_masks = mask; 692 enabled_uniform_buffer_masks = mask;
@@ -1016,14 +1019,18 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
1016 TouchBuffer(buffer); 1019 TouchBuffer(buffer);
1017 const bool use_fast_buffer = binding.buffer_id != NULL_BUFFER_ID && 1020 const bool use_fast_buffer = binding.buffer_id != NULL_BUFFER_ID &&
1018 size <= uniform_buffer_skip_cache_size && 1021 size <= uniform_buffer_skip_cache_size &&
1019 !buffer.IsRegionGpuModified(cpu_addr, size); 1022 !buffer.IsRegionGpuModified(cpu_addr, size) && false;
1020 if (use_fast_buffer) { 1023 if (use_fast_buffer) {
1021 if constexpr (IS_OPENGL) { 1024 if constexpr (IS_OPENGL) {
1022 if (runtime.HasFastBufferSubData()) { 1025 if (runtime.HasFastBufferSubData()) {
1023 // Fast path for Nvidia 1026 // Fast path for Nvidia
1024 if (!HasFastUniformBufferBound(stage, binding_index)) { 1027 const bool should_fast_bind =
1028 !HasFastUniformBufferBound(stage, binding_index) ||
1029 uniform_buffer_binding_sizes[stage][binding_index] != size;
1030 if (should_fast_bind) {
1025 // We only have to bind when the currently bound buffer is not the fast version 1031 // We only have to bind when the currently bound buffer is not the fast version
1026 fast_bound_uniform_buffers[stage] |= 1U << binding_index; 1032 fast_bound_uniform_buffers[stage] |= 1U << binding_index;
1033 uniform_buffer_binding_sizes[stage][binding_index] = size;
1027 runtime.BindFastUniformBuffer(stage, binding_index, size); 1034 runtime.BindFastUniformBuffer(stage, binding_index, size);
1028 } 1035 }
1029 const auto span = ImmediateBufferWithData(cpu_addr, size); 1036 const auto span = ImmediateBufferWithData(cpu_addr, size);
@@ -1033,6 +1040,7 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
1033 } 1040 }
1034 if constexpr (IS_OPENGL) { 1041 if constexpr (IS_OPENGL) {
1035 fast_bound_uniform_buffers[stage] |= 1U << binding_index; 1042 fast_bound_uniform_buffers[stage] |= 1U << binding_index;
1043 uniform_buffer_binding_sizes[stage][binding_index] = size;
1036 } 1044 }
1037 // Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan 1045 // Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan
1038 const std::span<u8> span = runtime.BindMappedUniformBuffer(stage, binding_index, size); 1046 const std::span<u8> span = runtime.BindMappedUniformBuffer(stage, binding_index, size);
@@ -1046,9 +1054,13 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
1046 } 1054 }
1047 ++uniform_cache_shots[0]; 1055 ++uniform_cache_shots[0];
1048 1056
1049 if (!needs_bind && !HasFastUniformBufferBound(stage, binding_index)) { 1057 // Skip binding if it's not needed and if the bound buffer is not the fast version
1050 // Skip binding if it's not needed and if the bound buffer is not the fast version 1058 // This exists to avoid instances where the fast buffer is bound and a GPU write happens
1051 // This exists to avoid instances where the fast buffer is bound and a GPU write happens 1059 needs_bind |= HasFastUniformBufferBound(stage, binding_index);
1060 if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
1061 needs_bind |= uniform_buffer_binding_sizes[stage][binding_index] != size;
1062 }
1063 if (!needs_bind) {
1052 return; 1064 return;
1053 } 1065 }
1054 const u32 offset = buffer.Offset(cpu_addr); 1066 const u32 offset = buffer.Offset(cpu_addr);
@@ -1060,6 +1072,9 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
1060 const bool is_copy_bind = offset != 0 && !runtime.SupportsNonZeroUniformOffset(); 1072 const bool is_copy_bind = offset != 0 && !runtime.SupportsNonZeroUniformOffset();
1061 dirty_uniform_buffers[stage] |= (is_copy_bind ? 1U : 0U) << index; 1073 dirty_uniform_buffers[stage] |= (is_copy_bind ? 1U : 0U) << index;
1062 } 1074 }
1075 if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
1076 uniform_buffer_binding_sizes[stage][binding_index] = size;
1077 }
1063 if constexpr (NEEDS_BIND_UNIFORM_INDEX) { 1078 if constexpr (NEEDS_BIND_UNIFORM_INDEX) {
1064 runtime.BindUniformBuffer(stage, binding_index, buffer, offset, size); 1079 runtime.BindUniformBuffer(stage, binding_index, buffer, offset, size);
1065 } else { 1080 } else {
@@ -1725,6 +1740,7 @@ template <class P>
1725void BufferCache<P>::NotifyBufferDeletion() { 1740void BufferCache<P>::NotifyBufferDeletion() {
1726 if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { 1741 if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
1727 dirty_uniform_buffers.fill(~u32{0}); 1742 dirty_uniform_buffers.fill(~u32{0});
1743 uniform_buffer_binding_sizes.fill({});
1728 } 1744 }
1729 auto& flags = maxwell3d.dirty.flags; 1745 auto& flags = maxwell3d.dirty.flags;
1730 flags[Dirty::IndexBuffer] = true; 1746 flags[Dirty::IndexBuffer] = true;