diff options
Diffstat (limited to '')
4 files changed, 34 insertions, 9 deletions
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index 38d553d3c..9d9c6b9da 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp | |||
| @@ -146,8 +146,12 @@ StagingBufferMap BufferCacheRuntime::UploadStagingBuffer(size_t size) { | |||
| 146 | return staging_buffer_pool.RequestUploadBuffer(size); | 146 | return staging_buffer_pool.RequestUploadBuffer(size); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | StagingBufferMap BufferCacheRuntime::DownloadStagingBuffer(size_t size) { | 149 | StagingBufferMap BufferCacheRuntime::DownloadStagingBuffer(size_t size, bool deferred) { |
| 150 | return staging_buffer_pool.RequestDownloadBuffer(size); | 150 | return staging_buffer_pool.RequestDownloadBuffer(size, deferred); |
| 151 | } | ||
| 152 | |||
| 153 | void BufferCacheRuntime::FreeDeferredStagingBuffer(StagingBufferMap& buffer) { | ||
| 154 | staging_buffer_pool.FreeDeferredStagingBuffer(buffer.index); | ||
| 151 | } | 155 | } |
| 152 | 156 | ||
| 153 | u64 BufferCacheRuntime::GetDeviceMemoryUsage() const { | 157 | u64 BufferCacheRuntime::GetDeviceMemoryUsage() const { |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index 41b746f3b..1b87954d7 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h | |||
| @@ -64,7 +64,9 @@ public: | |||
| 64 | 64 | ||
| 65 | [[nodiscard]] StagingBufferMap UploadStagingBuffer(size_t size); | 65 | [[nodiscard]] StagingBufferMap UploadStagingBuffer(size_t size); |
| 66 | 66 | ||
| 67 | [[nodiscard]] StagingBufferMap DownloadStagingBuffer(size_t size); | 67 | [[nodiscard]] StagingBufferMap DownloadStagingBuffer(size_t size, bool deferred = false); |
| 68 | |||
| 69 | void FreeDeferredStagingBuffer(StagingBufferMap& buffer); | ||
| 68 | 70 | ||
| 69 | void CopyBuffer(GLuint dst_buffer, GLuint src_buffer, | 71 | void CopyBuffer(GLuint dst_buffer, GLuint src_buffer, |
| 70 | std::span<const VideoCommon::BufferCopy> copies, bool barrier = true); | 72 | std::span<const VideoCommon::BufferCopy> copies, bool barrier = true); |
| @@ -233,7 +235,7 @@ struct BufferCacheParams { | |||
| 233 | static constexpr bool NEEDS_BIND_STORAGE_INDEX = true; | 235 | static constexpr bool NEEDS_BIND_STORAGE_INDEX = true; |
| 234 | static constexpr bool USE_MEMORY_MAPS = true; | 236 | static constexpr bool USE_MEMORY_MAPS = true; |
| 235 | static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = true; | 237 | static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = true; |
| 236 | static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = false; | 238 | static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = true; |
| 237 | 239 | ||
| 238 | // TODO: Investigate why OpenGL seems to perform worse with persistently mapped buffer uploads | 240 | // TODO: Investigate why OpenGL seems to perform worse with persistently mapped buffer uploads |
| 239 | static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = false; | 241 | static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = false; |
diff --git a/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp b/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp index 49121a775..edd0746dc 100644 --- a/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp +++ b/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp | |||
| @@ -28,19 +28,26 @@ StagingBuffers::StagingBuffers(GLenum storage_flags_, GLenum map_flags_) | |||
| 28 | 28 | ||
| 29 | StagingBuffers::~StagingBuffers() = default; | 29 | StagingBuffers::~StagingBuffers() = default; |
| 30 | 30 | ||
| 31 | StagingBufferMap StagingBuffers::RequestMap(size_t requested_size, bool insert_fence) { | 31 | StagingBufferMap StagingBuffers::RequestMap(size_t requested_size, bool insert_fence, |
| 32 | bool deferred) { | ||
| 32 | MICROPROFILE_SCOPE(OpenGL_BufferRequest); | 33 | MICROPROFILE_SCOPE(OpenGL_BufferRequest); |
| 33 | 34 | ||
| 34 | const size_t index = RequestBuffer(requested_size); | 35 | const size_t index = RequestBuffer(requested_size); |
| 35 | OGLSync* const sync = insert_fence ? &allocs[index].sync : nullptr; | 36 | OGLSync* const sync = insert_fence ? &allocs[index].sync : nullptr; |
| 36 | allocs[index].sync_index = insert_fence ? ++current_sync_index : 0; | 37 | allocs[index].sync_index = insert_fence ? ++current_sync_index : 0; |
| 38 | allocs[index].deferred = deferred; | ||
| 37 | return StagingBufferMap{ | 39 | return StagingBufferMap{ |
| 38 | .mapped_span = std::span(allocs[index].map, requested_size), | 40 | .mapped_span = std::span(allocs[index].map, requested_size), |
| 39 | .sync = sync, | 41 | .sync = sync, |
| 40 | .buffer = allocs[index].buffer.handle, | 42 | .buffer = allocs[index].buffer.handle, |
| 43 | .index = index, | ||
| 41 | }; | 44 | }; |
| 42 | } | 45 | } |
| 43 | 46 | ||
| 47 | void StagingBuffers::FreeDeferredStagingBuffer(size_t index) { | ||
| 48 | allocs[index].deferred = false; | ||
| 49 | } | ||
| 50 | |||
| 44 | size_t StagingBuffers::RequestBuffer(size_t requested_size) { | 51 | size_t StagingBuffers::RequestBuffer(size_t requested_size) { |
| 45 | if (const std::optional<size_t> index = FindBuffer(requested_size); index) { | 52 | if (const std::optional<size_t> index = FindBuffer(requested_size); index) { |
| 46 | return *index; | 53 | return *index; |
| @@ -68,6 +75,9 @@ std::optional<size_t> StagingBuffers::FindBuffer(size_t requested_size) { | |||
| 68 | if (buffer_size < requested_size || buffer_size >= smallest_buffer) { | 75 | if (buffer_size < requested_size || buffer_size >= smallest_buffer) { |
| 69 | continue; | 76 | continue; |
| 70 | } | 77 | } |
| 78 | if (alloc.deferred) { | ||
| 79 | continue; | ||
| 80 | } | ||
| 71 | if (alloc.sync.handle != 0) { | 81 | if (alloc.sync.handle != 0) { |
| 72 | if (alloc.sync_index >= known_unsignaled_index) { | 82 | if (alloc.sync_index >= known_unsignaled_index) { |
| 73 | // This fence is later than a fence that is known to not be signaled | 83 | // This fence is later than a fence that is known to not be signaled |
| @@ -138,8 +148,12 @@ StagingBufferMap StagingBufferPool::RequestUploadBuffer(size_t size) { | |||
| 138 | return upload_buffers.RequestMap(size, true); | 148 | return upload_buffers.RequestMap(size, true); |
| 139 | } | 149 | } |
| 140 | 150 | ||
| 141 | StagingBufferMap StagingBufferPool::RequestDownloadBuffer(size_t size) { | 151 | StagingBufferMap StagingBufferPool::RequestDownloadBuffer(size_t size, bool deferred) { |
| 142 | return download_buffers.RequestMap(size, false); | 152 | return download_buffers.RequestMap(size, false, deferred); |
| 153 | } | ||
| 154 | |||
| 155 | void StagingBufferPool::FreeDeferredStagingBuffer(size_t index) { | ||
| 156 | download_buffers.FreeDeferredStagingBuffer(index); | ||
| 143 | } | 157 | } |
| 144 | 158 | ||
| 145 | } // namespace OpenGL | 159 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_staging_buffer_pool.h b/src/video_core/renderer_opengl/gl_staging_buffer_pool.h index 5b229d0b6..598ddc172 100644 --- a/src/video_core/renderer_opengl/gl_staging_buffer_pool.h +++ b/src/video_core/renderer_opengl/gl_staging_buffer_pool.h | |||
| @@ -26,13 +26,16 @@ struct StagingBufferMap { | |||
| 26 | size_t offset = 0; | 26 | size_t offset = 0; |
| 27 | OGLSync* sync; | 27 | OGLSync* sync; |
| 28 | GLuint buffer; | 28 | GLuint buffer; |
| 29 | size_t index; | ||
| 29 | }; | 30 | }; |
| 30 | 31 | ||
| 31 | struct StagingBuffers { | 32 | struct StagingBuffers { |
| 32 | explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_); | 33 | explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_); |
| 33 | ~StagingBuffers(); | 34 | ~StagingBuffers(); |
| 34 | 35 | ||
| 35 | StagingBufferMap RequestMap(size_t requested_size, bool insert_fence); | 36 | StagingBufferMap RequestMap(size_t requested_size, bool insert_fence, bool deferred = false); |
| 37 | |||
| 38 | void FreeDeferredStagingBuffer(size_t index); | ||
| 36 | 39 | ||
| 37 | size_t RequestBuffer(size_t requested_size); | 40 | size_t RequestBuffer(size_t requested_size); |
| 38 | 41 | ||
| @@ -44,6 +47,7 @@ struct StagingBuffers { | |||
| 44 | u8* map; | 47 | u8* map; |
| 45 | size_t size; | 48 | size_t size; |
| 46 | size_t sync_index; | 49 | size_t sync_index; |
| 50 | bool deferred; | ||
| 47 | }; | 51 | }; |
| 48 | std::vector<StagingBufferAlloc> allocs; | 52 | std::vector<StagingBufferAlloc> allocs; |
| 49 | GLenum storage_flags; | 53 | GLenum storage_flags; |
| @@ -88,7 +92,8 @@ public: | |||
| 88 | ~StagingBufferPool() = default; | 92 | ~StagingBufferPool() = default; |
| 89 | 93 | ||
| 90 | StagingBufferMap RequestUploadBuffer(size_t size); | 94 | StagingBufferMap RequestUploadBuffer(size_t size); |
| 91 | StagingBufferMap RequestDownloadBuffer(size_t size); | 95 | StagingBufferMap RequestDownloadBuffer(size_t size, bool deferred = false); |
| 96 | void FreeDeferredStagingBuffer(size_t index); | ||
| 92 | 97 | ||
| 93 | private: | 98 | private: |
| 94 | StagingBuffers upload_buffers{GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT}; | 99 | StagingBuffers upload_buffers{GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT}; |