diff options
| author | 2020-06-26 16:58:40 -0300 | |
|---|---|---|
| committer | 2020-06-26 16:58:40 -0300 | |
| commit | 6481d91e4a5b5fbae899c3a7924af0b132c16bc8 (patch) | |
| tree | e67f6966cabda53be653cda6ba346f88d5f5090d /src | |
| parent | Merge pull request #4159 from ogniK5377/mem-manager-dumb-assert (diff) | |
| download | yuzu-6481d91e4a5b5fbae899c3a7924af0b132c16bc8.tar.gz yuzu-6481d91e4a5b5fbae899c3a7924af0b132c16bc8.tar.xz yuzu-6481d91e4a5b5fbae899c3a7924af0b132c16bc8.zip | |
gl_buffer_cache: Copy to buffers created as STREAM_READ before downloading
After marking buffers as resident, Nvidia's driver seems to take a
slow path. To workaround this issue, copy to a STREAM_READ buffer and
then call GetNamedBufferSubData on it.
This is a temporary solution until we have asynchronous flushing.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.cpp | 17 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.h | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.h | 6 |
5 files changed, 24 insertions, 18 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index cf8bdd021..c6479af9f 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -322,8 +322,7 @@ protected: | |||
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | private: | 324 | private: |
| 325 | MapInterval* MapAddress(const Buffer* block, GPUVAddr gpu_addr, VAddr cpu_addr, | 325 | MapInterval* MapAddress(Buffer* block, GPUVAddr gpu_addr, VAddr cpu_addr, std::size_t size) { |
| 326 | std::size_t size) { | ||
| 327 | const VectorMapInterval overlaps = GetMapsInRange(cpu_addr, size); | 326 | const VectorMapInterval overlaps = GetMapsInRange(cpu_addr, size); |
| 328 | if (overlaps.empty()) { | 327 | if (overlaps.empty()) { |
| 329 | auto& memory_manager = system.GPU().MemoryManager(); | 328 | auto& memory_manager = system.GPU().MemoryManager(); |
| @@ -377,8 +376,7 @@ private: | |||
| 377 | return map; | 376 | return map; |
| 378 | } | 377 | } |
| 379 | 378 | ||
| 380 | void UpdateBlock(const Buffer* block, VAddr start, VAddr end, | 379 | void UpdateBlock(Buffer* block, VAddr start, VAddr end, const VectorMapInterval& overlaps) { |
| 381 | const VectorMapInterval& overlaps) { | ||
| 382 | const IntervalType base_interval{start, end}; | 380 | const IntervalType base_interval{start, end}; |
| 383 | IntervalSet interval_set{}; | 381 | IntervalSet interval_set{}; |
| 384 | interval_set.add(base_interval); | 382 | interval_set.add(base_interval); |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index d9f7b4cc6..e461e4c70 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp | |||
| @@ -34,20 +34,27 @@ Buffer::Buffer(const Device& device, VAddr cpu_addr, std::size_t size) | |||
| 34 | 34 | ||
| 35 | Buffer::~Buffer() = default; | 35 | Buffer::~Buffer() = default; |
| 36 | 36 | ||
| 37 | void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) const { | 37 | void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) { |
| 38 | glNamedBufferSubData(Handle(), static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size), | 38 | glNamedBufferSubData(Handle(), static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size), |
| 39 | data); | 39 | data); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | void Buffer::Download(std::size_t offset, std::size_t size, u8* data) const { | 42 | void Buffer::Download(std::size_t offset, std::size_t size, u8* data) { |
| 43 | MICROPROFILE_SCOPE(OpenGL_Buffer_Download); | 43 | MICROPROFILE_SCOPE(OpenGL_Buffer_Download); |
| 44 | const GLsizeiptr gl_size = static_cast<GLsizeiptr>(size); | ||
| 45 | const GLintptr gl_offset = static_cast<GLintptr>(offset); | ||
| 46 | if (read_buffer.handle == 0) { | ||
| 47 | read_buffer.Create(); | ||
| 48 | glNamedBufferData(read_buffer.handle, static_cast<GLsizeiptr>(Size()), nullptr, | ||
| 49 | GL_STREAM_READ); | ||
| 50 | } | ||
| 44 | glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); | 51 | glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); |
| 45 | glGetNamedBufferSubData(Handle(), static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size), | 52 | glCopyNamedBufferSubData(gl_buffer.handle, read_buffer.handle, gl_offset, gl_offset, gl_size); |
| 46 | data); | 53 | glGetNamedBufferSubData(read_buffer.handle, gl_offset, gl_size, data); |
| 47 | } | 54 | } |
| 48 | 55 | ||
| 49 | void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset, | 56 | void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset, |
| 50 | std::size_t size) const { | 57 | std::size_t size) { |
| 51 | glCopyNamedBufferSubData(src.Handle(), Handle(), static_cast<GLintptr>(src_offset), | 58 | glCopyNamedBufferSubData(src.Handle(), Handle(), static_cast<GLintptr>(src_offset), |
| 52 | static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size)); | 59 | static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size)); |
| 53 | } | 60 | } |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index 59d95adbc..88fdc0536 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h | |||
| @@ -28,12 +28,12 @@ public: | |||
| 28 | explicit Buffer(const Device& device, VAddr cpu_addr, std::size_t size); | 28 | explicit Buffer(const Device& device, VAddr cpu_addr, std::size_t size); |
| 29 | ~Buffer(); | 29 | ~Buffer(); |
| 30 | 30 | ||
| 31 | void Upload(std::size_t offset, std::size_t size, const u8* data) const; | 31 | void Upload(std::size_t offset, std::size_t size, const u8* data); |
| 32 | 32 | ||
| 33 | void Download(std::size_t offset, std::size_t size, u8* data) const; | 33 | void Download(std::size_t offset, std::size_t size, u8* data); |
| 34 | 34 | ||
| 35 | void CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset, | 35 | void CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset, |
| 36 | std::size_t size) const; | 36 | std::size_t size); |
| 37 | 37 | ||
| 38 | GLuint Handle() const noexcept { | 38 | GLuint Handle() const noexcept { |
| 39 | return gl_buffer.handle; | 39 | return gl_buffer.handle; |
| @@ -45,6 +45,7 @@ public: | |||
| 45 | 45 | ||
| 46 | private: | 46 | private: |
| 47 | OGLBuffer gl_buffer; | 47 | OGLBuffer gl_buffer; |
| 48 | OGLBuffer read_buffer; | ||
| 48 | u64 gpu_address = 0; | 49 | u64 gpu_address = 0; |
| 49 | }; | 50 | }; |
| 50 | 51 | ||
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index f10f96cd8..2be38d419 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp | |||
| @@ -56,7 +56,7 @@ Buffer::Buffer(const VKDevice& device, VKMemoryManager& memory_manager, VKSchedu | |||
| 56 | 56 | ||
| 57 | Buffer::~Buffer() = default; | 57 | Buffer::~Buffer() = default; |
| 58 | 58 | ||
| 59 | void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) const { | 59 | void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) { |
| 60 | const auto& staging = staging_pool.GetUnusedBuffer(size, true); | 60 | const auto& staging = staging_pool.GetUnusedBuffer(size, true); |
| 61 | std::memcpy(staging.commit->Map(size), data, size); | 61 | std::memcpy(staging.commit->Map(size), data, size); |
| 62 | 62 | ||
| @@ -81,7 +81,7 @@ void Buffer::Upload(std::size_t offset, std::size_t size, const u8* data) const | |||
| 81 | }); | 81 | }); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | void Buffer::Download(std::size_t offset, std::size_t size, u8* data) const { | 84 | void Buffer::Download(std::size_t offset, std::size_t size, u8* data) { |
| 85 | const auto& staging = staging_pool.GetUnusedBuffer(size, true); | 85 | const auto& staging = staging_pool.GetUnusedBuffer(size, true); |
| 86 | scheduler.RequestOutsideRenderPassOperationContext(); | 86 | scheduler.RequestOutsideRenderPassOperationContext(); |
| 87 | 87 | ||
| @@ -110,7 +110,7 @@ void Buffer::Download(std::size_t offset, std::size_t size, u8* data) const { | |||
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset, | 112 | void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset, |
| 113 | std::size_t size) const { | 113 | std::size_t size) { |
| 114 | scheduler.RequestOutsideRenderPassOperationContext(); | 114 | scheduler.RequestOutsideRenderPassOperationContext(); |
| 115 | 115 | ||
| 116 | const VkBuffer dst_buffer = Handle(); | 116 | const VkBuffer dst_buffer = Handle(); |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index 3630aca77..991ee451c 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h | |||
| @@ -29,12 +29,12 @@ public: | |||
| 29 | VKStagingBufferPool& staging_pool, VAddr cpu_addr, std::size_t size); | 29 | VKStagingBufferPool& staging_pool, VAddr cpu_addr, std::size_t size); |
| 30 | ~Buffer(); | 30 | ~Buffer(); |
| 31 | 31 | ||
| 32 | void Upload(std::size_t offset, std::size_t size, const u8* data) const; | 32 | void Upload(std::size_t offset, std::size_t size, const u8* data); |
| 33 | 33 | ||
| 34 | void Download(std::size_t offset, std::size_t size, u8* data) const; | 34 | void Download(std::size_t offset, std::size_t size, u8* data); |
| 35 | 35 | ||
| 36 | void CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset, | 36 | void CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst_offset, |
| 37 | std::size_t size) const; | 37 | std::size_t size); |
| 38 | 38 | ||
| 39 | VkBuffer Handle() const { | 39 | VkBuffer Handle() const { |
| 40 | return *buffer.handle; | 40 | return *buffer.handle; |