Vulkan: Use minimal dirty bits in VertexArrayVk.
This should slightly reduce draw call overhead.
BUG=angleproject:1898
Change-Id: I0e515bf2868f237f1d6948c12942f8cb6637c0c0
Reviewed-on: https://chromium-review.googlesource.com/707690
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 6bbfd9b..11e2afd 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -11,6 +11,7 @@
#include "common/bitset_utils.h"
#include "common/debug.h"
+#include "libANGLE/Context.h"
#include "libANGLE/Program.h"
#include "libANGLE/renderer/vulkan/BufferVk.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
@@ -77,8 +78,9 @@
gl::Error ContextVk::finish()
{
- UNIMPLEMENTED();
- return gl::InternalError();
+ // TODO(jmadill): Implement finish.
+ // UNIMPLEMENTED();
+ return gl::NoError();
}
gl::Error ContextVk::initPipeline(const gl::Context *context)
@@ -302,46 +304,29 @@
const auto &state = mState.getState();
const auto &programGL = state.getProgram();
const auto &vao = state.getVertexArray();
- const auto &attribs = vao->getVertexAttributes();
- const auto &bindings = vao->getVertexBindings();
+ VertexArrayVk *vkVAO = GetImplAs<VertexArrayVk>(vao);
const auto *drawFBO = state.getDrawFramebuffer();
FramebufferVk *vkFBO = GetImplAs<FramebufferVk>(drawFBO);
Serial queueSerial = mRenderer->getCurrentQueueSerial();
+ uint32_t maxAttrib = programGL->getState().getMaxActiveAttribLocation();
- // Process vertex attributes
- // TODO(jmadill): Caching with dirty bits.
- std::vector<VkBuffer> vertexHandles;
- std::vector<VkDeviceSize> vertexOffsets;
-
- for (auto attribIndex : programGL->getActiveAttribLocationsMask())
- {
- const auto &attrib = attribs[attribIndex];
- const auto &binding = bindings[attrib.bindingIndex];
- if (attrib.enabled)
- {
- // TODO(jmadill): Offset handling.
- gl::Buffer *bufferGL = binding.getBuffer().get();
- ASSERT(bufferGL);
- BufferVk *bufferVk = GetImplAs<BufferVk>(bufferGL);
- vertexHandles.push_back(bufferVk->getVkBuffer().getHandle());
- vertexOffsets.push_back(0);
-
- bufferVk->setQueueSerial(queueSerial);
- }
- else
- {
- UNIMPLEMENTED();
- }
- }
+ // Process vertex attributes. Assume zero offsets for now.
+ // TODO(jmadill): Offset handling.
+ const std::vector<VkBuffer> &vertexHandles = vkVAO->getCurrentVertexBufferHandlesCache();
+ angle::MemoryBuffer *zeroBuf = nullptr;
+ ANGLE_TRY(context->getZeroFilledBuffer(maxAttrib * sizeof(VkDeviceSize), &zeroBuf));
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(mRenderer->getStartedCommandBuffer(&commandBuffer));
ANGLE_TRY(vkFBO->ensureInRenderPass(context, device, commandBuffer, queueSerial, state));
commandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mCurrentPipeline);
+ commandBuffer->bindVertexBuffers(0, maxAttrib, vertexHandles.data(),
+ reinterpret_cast<const VkDeviceSize *>(zeroBuf->data()));
+
// TODO(jmadill): the queue serial should be bound to the pipeline.
setQueueSerial(queueSerial);
- commandBuffer->bindVertexBuffers(0, vertexHandles, vertexOffsets);
+ vkVAO->updateCurrentBufferSerials(programGL->getActiveAttribLocationsMask(), queueSerial);
return gl::NoError();
}