diff options
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 19 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.h | 12 |
2 files changed, 22 insertions, 9 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index ec64f2293..47cb0a47d 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -680,6 +680,9 @@ void BufferCache<P>::SetUniformBuffersState(const std::array<u32, NUM_STAGES>& m | |||
| 680 | const UniformBufferSizes* sizes) { | 680 | const UniformBufferSizes* sizes) { |
| 681 | if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { | 681 | if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { |
| 682 | if (enabled_uniform_buffer_masks != mask) { | 682 | if (enabled_uniform_buffer_masks != mask) { |
| 683 | if constexpr (IS_OPENGL) { | ||
| 684 | fast_bound_uniform_buffers.fill(0); | ||
| 685 | } | ||
| 683 | dirty_uniform_buffers.fill(~u32{0}); | 686 | dirty_uniform_buffers.fill(~u32{0}); |
| 684 | } | 687 | } |
| 685 | } | 688 | } |
| @@ -1020,6 +1023,7 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 | |||
| 1020 | // Fast path for Nvidia | 1023 | // Fast path for Nvidia |
| 1021 | if (!HasFastUniformBufferBound(stage, binding_index)) { | 1024 | if (!HasFastUniformBufferBound(stage, binding_index)) { |
| 1022 | // We only have to bind when the currently bound buffer is not the fast version | 1025 | // We only have to bind when the currently bound buffer is not the fast version |
| 1026 | fast_bound_uniform_buffers[stage] |= 1U << binding_index; | ||
| 1023 | runtime.BindFastUniformBuffer(stage, binding_index, size); | 1027 | runtime.BindFastUniformBuffer(stage, binding_index, size); |
| 1024 | } | 1028 | } |
| 1025 | const auto span = ImmediateBufferWithData(cpu_addr, size); | 1029 | const auto span = ImmediateBufferWithData(cpu_addr, size); |
| @@ -1027,8 +1031,9 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 | |||
| 1027 | return; | 1031 | return; |
| 1028 | } | 1032 | } |
| 1029 | } | 1033 | } |
| 1030 | fast_bound_uniform_buffers[stage] |= 1U << binding_index; | 1034 | if constexpr (IS_OPENGL) { |
| 1031 | 1035 | fast_bound_uniform_buffers[stage] |= 1U << binding_index; | |
| 1036 | } | ||
| 1032 | // Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan | 1037 | // Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan |
| 1033 | const std::span<u8> span = runtime.BindMappedUniformBuffer(stage, binding_index, size); | 1038 | const std::span<u8> span = runtime.BindMappedUniformBuffer(stage, binding_index, size); |
| 1034 | cpu_memory.ReadBlockUnsafe(cpu_addr, span.data(), size); | 1039 | cpu_memory.ReadBlockUnsafe(cpu_addr, span.data(), size); |
| @@ -1046,9 +1051,15 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 | |||
| 1046 | // 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 |
| 1047 | return; | 1052 | return; |
| 1048 | } | 1053 | } |
| 1049 | fast_bound_uniform_buffers[stage] &= ~(1U << binding_index); | ||
| 1050 | |||
| 1051 | const u32 offset = buffer.Offset(cpu_addr); | 1054 | const u32 offset = buffer.Offset(cpu_addr); |
| 1055 | if constexpr (IS_OPENGL) { | ||
| 1056 | // Fast buffer will be unbound | ||
| 1057 | fast_bound_uniform_buffers[stage] &= ~(1U << binding_index); | ||
| 1058 | |||
| 1059 | // Mark the index as dirty if offset doesn't match | ||
| 1060 | const bool is_copy_bind = offset != 0 && !runtime.SupportsNonZeroUniformOffset(); | ||
| 1061 | dirty_uniform_buffers[stage] |= (is_copy_bind ? 1U : 0U) << index; | ||
| 1062 | } | ||
| 1052 | if constexpr (NEEDS_BIND_UNIFORM_INDEX) { | 1063 | if constexpr (NEEDS_BIND_UNIFORM_INDEX) { |
| 1053 | runtime.BindUniformBuffer(stage, binding_index, buffer, offset, size); | 1064 | runtime.BindUniformBuffer(stage, binding_index, buffer, offset, size); |
| 1054 | } else { | 1065 | } else { |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index bc16abafb..060d36427 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h | |||
| @@ -92,16 +92,14 @@ public: | |||
| 92 | VideoCore::Surface::PixelFormat format); | 92 | VideoCore::Surface::PixelFormat format); |
| 93 | 93 | ||
| 94 | void BindFastUniformBuffer(size_t stage, u32 binding_index, u32 size) { | 94 | void BindFastUniformBuffer(size_t stage, u32 binding_index, u32 size) { |
| 95 | const GLuint handle = fast_uniforms[stage][binding_index].handle; | ||
| 96 | const GLsizeiptr gl_size = static_cast<GLsizeiptr>(size); | ||
| 95 | if (use_assembly_shaders) { | 97 | if (use_assembly_shaders) { |
| 96 | const GLuint handle = fast_uniforms[stage][binding_index].handle; | ||
| 97 | const GLsizeiptr gl_size = static_cast<GLsizeiptr>(size); | ||
| 98 | glBindBufferRangeNV(PABO_LUT[stage], binding_index, handle, 0, gl_size); | 98 | glBindBufferRangeNV(PABO_LUT[stage], binding_index, handle, 0, gl_size); |
| 99 | } else { | 99 | } else { |
| 100 | const GLuint base_binding = graphics_base_uniform_bindings[stage]; | 100 | const GLuint base_binding = graphics_base_uniform_bindings[stage]; |
| 101 | const GLuint binding = base_binding + binding_index; | 101 | const GLuint binding = base_binding + binding_index; |
| 102 | glBindBufferRange(GL_UNIFORM_BUFFER, binding, | 102 | glBindBufferRange(GL_UNIFORM_BUFFER, binding, handle, 0, gl_size); |
| 103 | fast_uniforms[stage][binding_index].handle, 0, | ||
| 104 | static_cast<GLsizeiptr>(size)); | ||
| 105 | } | 103 | } |
| 106 | } | 104 | } |
| 107 | 105 | ||
| @@ -134,6 +132,10 @@ public: | |||
| 134 | return has_fast_buffer_sub_data; | 132 | return has_fast_buffer_sub_data; |
| 135 | } | 133 | } |
| 136 | 134 | ||
| 135 | [[nodiscard]] bool SupportsNonZeroUniformOffset() const noexcept { | ||
| 136 | return !use_assembly_shaders; | ||
| 137 | } | ||
| 138 | |||
| 137 | void SetBaseUniformBindings(const std::array<GLuint, 5>& bindings) { | 139 | void SetBaseUniformBindings(const std::array<GLuint, 5>& bindings) { |
| 138 | graphics_base_uniform_bindings = bindings; | 140 | graphics_base_uniform_bindings = bindings; |
| 139 | } | 141 | } |