Vulkan: Store reference to context command buffer.
This frees us from checking the FB every draw. Slightly reduces time
spent in all draw methods. Improvement seen on the draw call overhead
tests. Scores went from 28.17 ns/draw to 26.76 ns/draw on my machine.
In a future improvement we could make this command buffer a dirty bit.
Currently it's a bit slower to call a handler function due to the
dispatch table. Likely we could optimize this by reverting back to a
dirty bit switch and inlining the handler functions. That is left for
future work.
Vulkan is happy enough to run multiple RenderPasses and bind different
Pipelines in the same command buffer. But ANGLE defers RenderPass init
until we submit our work. Thus we can only support one RenderPass per
secondary buffer.
Test: angle_perftests DrawCall*/vulkan_null
Bug: angleproject:3014
Change-Id: I89fd0d9e0822400a5c5a16acb5a9c400a0e71ab5
Reviewed-on: https://chromium-review.googlesource.com/c/1393905
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index 43689c0..ede6f91 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -17,10 +17,12 @@
#include "common/debug.h"
#include "common/platform.h"
#include "common/system_utils.h"
+#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/vulkan/CommandGraph.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
+#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/GlslangWrapper.h"
@@ -570,8 +572,7 @@
mDeviceLost = true;
mCommandGraph.clear();
- mLastSubmittedQueueSerial = mCurrentQueueSerial;
- mCurrentQueueSerial = mQueueSerialFactory.generate();
+ nextSerial();
freeAllInFlightResources();
mDisplay->notifyDeviceLost();
@@ -1312,10 +1313,7 @@
// InterleavedAttributeDataBenchmark perf test for example issues a large number of flushes.
ASSERT(mInFlightCommands.size() <= kInFlightCommandsLimit);
- // Increment the queue serial. If this fails, we should restart ANGLE.
- // TODO(jmadill): Overflow check.
- mLastSubmittedQueueSerial = mCurrentQueueSerial;
- mCurrentQueueSerial = mQueueSerialFactory.generate();
+ nextSerial();
ANGLE_TRY(checkCompletedCommands(context));
@@ -1338,6 +1336,25 @@
return angle::Result::Continue;
}
+void RendererVk::nextSerial()
+{
+ // Increment the queue serial. If this fails, we should restart ANGLE.
+ mLastSubmittedQueueSerial = mCurrentQueueSerial;
+ mCurrentQueueSerial = mQueueSerialFactory.generate();
+
+ // Notify the Contexts that they should be starting new command buffers.
+ // We use one command pool per serial/submit associated with this VkQueue. We can also
+ // have multiple Contexts sharing one VkQueue. In ContextVk::setupDraw we don't explicitly
+ // check for a new serial when starting a new command buffer. We just check that the current
+ // recording command buffer is valid. Thus we need to explicitly notify every other Context
+ // using this VkQueue that they their current command buffer is no longer valid.
+ for (gl::Context *context : mDisplay->getContextSet())
+ {
+ ContextVk *contextVk = vk::GetImpl(context);
+ contextVk->onCommandBufferFinished();
+ }
+}
+
bool RendererVk::isSerialInUse(Serial serial) const
{
return serial > mLastCompletedQueueSerial;