Commit 6dd4a92a by Frank Henigman Committed by Commit Bot

Vulkan: track attributes in client memory.

To support indexed draws it's useful to have a cheap query for the presence of vertex attribute data in client memory. This patch adds a bit mask to keep track of such attributes. It also lets us simplify VertexArrayVk::streamVertexData() slightly. BUG=angleproject:1683 Change-Id: I871bfb885112650b025e110c383db3c391eafb90 Reviewed-on: https://chromium-review.googlesource.com/947927 Commit-Queue: Frank Henigman <fjhenigman@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 99d492c2
......@@ -45,45 +45,44 @@ void VertexArrayVk::destroy(const gl::Context *context)
gl::Error VertexArrayVk::streamVertexData(ContextVk *context,
StreamingBuffer *stream,
int firstVertex,
int lastVertex)
size_t firstVertex,
size_t lastVertex)
{
const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings();
const gl::Program *programGL = context->getGLState().getProgram();
const gl::AttributesMask attribsToStream =
mClientMemoryAttribs & programGL->getActiveAttribLocationsMask();
// TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
// un-interleaved, wasting space and copying time. Consider improving on that.
for (auto attribIndex : programGL->getActiveAttribLocationsMask())
for (auto attribIndex : attribsToStream)
{
const auto &attrib = attribs[attribIndex];
const auto &binding = bindings[attrib.bindingIndex];
gl::Buffer *bufferGL = binding.getBuffer().get();
const gl::VertexAttribute &attrib = attribs[attribIndex];
const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
if (attrib.enabled && !bufferGL)
// TODO(fjhenigman): Work with more formats than just GL_FLOAT.
if (attrib.type != GL_FLOAT)
{
// TODO(fjhenigman): Work with more formats than just GL_FLOAT.
if (attrib.type != GL_FLOAT)
{
UNIMPLEMENTED();
return gl::InternalError();
}
// Only [firstVertex, lastVertex] is needed by the upcoming draw so that
// is all we copy, but we allocate space for [0, lastVertex] so indexing
// will work. If we don't start at zero all the indices will be off.
// TODO(fjhenigman): See if we can account for indices being off by adjusting
// the offset, thus avoiding wasted memory.
const size_t firstByte = firstVertex * binding.getStride();
const size_t lastByte =
lastVertex * binding.getStride() + gl::ComputeVertexAttributeTypeSize(attrib);
uint8_t *dst = nullptr;
ANGLE_TRY(stream->allocate(context, lastByte, &dst,
&mCurrentArrayBufferHandles[attribIndex],
&mCurrentArrayBufferOffsets[attribIndex]));
memcpy(dst + firstByte, static_cast<const uint8_t *>(attrib.pointer) + firstByte,
lastByte - firstByte);
UNIMPLEMENTED();
return gl::InternalError();
}
// Only [firstVertex, lastVertex] is needed by the upcoming draw so that
// is all we copy, but we allocate space for [0, lastVertex] so indexing
// will work. If we don't start at zero all the indices will be off.
// TODO(fjhenigman): See if we can account for indices being off by adjusting
// the offset, thus avoiding wasted memory.
const size_t firstByte = firstVertex * binding.getStride();
const size_t lastByte =
lastVertex * binding.getStride() + gl::ComputeVertexAttributeTypeSize(attrib);
uint8_t *dst = nullptr;
ANGLE_TRY(stream->allocate(context, lastByte, &dst,
&mCurrentArrayBufferHandles[attribIndex],
&mCurrentArrayBufferOffsets[attribIndex]));
memcpy(dst + firstByte, static_cast<const uint8_t *>(attrib.pointer) + firstByte,
lastByte - firstByte);
}
ANGLE_TRY(stream->flush(context));
......@@ -137,17 +136,20 @@ void VertexArrayVk::syncState(const gl::Context *context,
BufferVk *bufferVk = vk::GetImpl(bufferGL);
mCurrentArrayBufferResources[attribIndex] = bufferVk;
mCurrentArrayBufferHandles[attribIndex] = bufferVk->getVkBuffer().getHandle();
mClientMemoryAttribs.reset(attribIndex);
}
else
{
mCurrentArrayBufferResources[attribIndex] = nullptr;
mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
mClientMemoryAttribs.set(attribIndex);
}
// TODO(jmadill): Offset handling. Assume zero for now.
mCurrentArrayBufferOffsets[attribIndex] = 0;
}
else
{
mClientMemoryAttribs.reset(attribIndex);
UNIMPLEMENTED();
}
}
......
......@@ -28,8 +28,8 @@ class VertexArrayVk : public VertexArrayImpl
gl::Error streamVertexData(ContextVk *context,
StreamingBuffer *stream,
int firstVertex,
int lastVertex);
size_t firstVertex,
size_t lastVertex);
void syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits) override;
......@@ -65,6 +65,10 @@ class VertexArrayVk : public VertexArrayImpl
gl::AttributesMask mDirtyPackedInputs;
vk::VertexInputBindings mPackedInputBindings;
vk::VertexInputAttributes mPackedInputAttributes;
// Which attributes need to be copied from client memory.
// TODO(jmadill): Move this to VertexArrayState. http://anglebug.com/2389
gl::AttributesMask mClientMemoryAttribs;
};
} // namespace rx
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment