summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/StreamBuffer.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@users.noreply.github.com>2016-12-01 12:38:31 +1000
committerGitHub <noreply@github.com>2016-12-01 12:38:31 +1000
commite2018f22085dd168b8ef6ec1c8ff6260e8c3e8b2 (patch)
tree913af0e2da3f35154c7aa06af0bb6421546543b4 /Source/Core/VideoBackends/Vulkan/StreamBuffer.cpp
parenta3d2dead76f9fe46163a20f6b7cc6ac7b2b66f29 (diff)
parentca691a9d95c437334cfeb8321a544ed36d17849b (diff)
Merge pull request #4480 from stenzek/vulkan-streambuffer-reuse
Vulkan: Fix stream buffer re-use problems
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/StreamBuffer.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/StreamBuffer.cpp36
1 files changed, 18 insertions, 18 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/StreamBuffer.cpp b/Source/Core/VideoBackends/Vulkan/StreamBuffer.cpp
index 4d90401bcf..6cf55ab0f2 100644
--- a/Source/Core/VideoBackends/Vulkan/StreamBuffer.cpp
+++ b/Source/Core/VideoBackends/Vulkan/StreamBuffer.cpp
@@ -286,8 +286,11 @@ bool StreamBuffer::WaitForClearSpace(size_t num_bytes)
for (; iter != m_tracked_fences.end(); iter++)
{
// Would this fence bring us in line with the GPU?
+ // This is the "last resort" case, where a command buffer execution has been forced
+ // after no additional data has been written to it, so we can assume that after the
+ // fence has been signaled the entire buffer is now consumed.
size_t gpu_position = iter->second;
- if (gpu_position == m_current_offset)
+ if (m_current_offset == gpu_position)
{
// Start at the start of the buffer again.
new_offset = 0;
@@ -295,12 +298,12 @@ bool StreamBuffer::WaitForClearSpace(size_t num_bytes)
break;
}
- // We can wrap around to the start, behind the GPU, if there is enough space.
- // We use > here because otherwise we'd end up lining up with the GPU, and then the
- // allocator would assume that the GPU has consumed what we just wrote.
- if (m_current_offset >= m_current_gpu_position)
+ // Assuming that we wait for this fence, are we allocating in front of the GPU?
+ if (m_current_offset > gpu_position)
{
- // Wrap around to the start (behind the GPU) if there is sufficient space.
+ // We can wrap around to the start, behind the GPU, if there is enough space.
+ // We use > here because otherwise we'd end up lining up with the GPU, and then the
+ // allocator would assume that the GPU has consumed what we just wrote.
if (gpu_position > num_bytes)
{
new_offset = 0;
@@ -310,19 +313,16 @@ bool StreamBuffer::WaitForClearSpace(size_t num_bytes)
}
else
{
- // We're currently allocating behind the GPU. Therefore, if this fence is behind us,
- // and it's the last fence in the list (no data has been written after it), we can
- // move back to allocating in front of the GPU.
- if (gpu_position < m_current_offset)
+ // We're currently allocating behind the GPU. This would give us between the current
+ // offset and the GPU position worth of space to work with. Again, > because we can't
+ // align the GPU position with the buffer offset.
+ size_t available_space_inbetween = m_current_offset - gpu_position;
+ if (available_space_inbetween > num_bytes)
{
- if (std::none_of(iter, m_tracked_fences.end(),
- [gpu_position](const auto& it) { return it.second > gpu_position; }))
- {
- // Wait for this fence to complete, then allocate directly after it.
- new_offset = gpu_position;
- new_gpu_position = gpu_position;
- break;
- }
+ // Leave the offset as-is, but update the GPU position.
+ new_offset = m_current_offset;
+ new_gpu_position = gpu_position;
+ break;
}
}
}