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) ...@@ -45,45 +45,44 @@ void VertexArrayVk::destroy(const gl::Context *context)
gl::Error VertexArrayVk::streamVertexData(ContextVk *context, gl::Error VertexArrayVk::streamVertexData(ContextVk *context,
StreamingBuffer *stream, StreamingBuffer *stream,
int firstVertex, size_t firstVertex,
int lastVertex) size_t lastVertex)
{ {
const auto &attribs = mState.getVertexAttributes(); const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings(); const auto &bindings = mState.getVertexBindings();
const gl::Program *programGL = context->getGLState().getProgram(); 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 // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
// un-interleaved, wasting space and copying time. Consider improving on that. // 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 gl::VertexAttribute &attrib = attribs[attribIndex];
const auto &binding = bindings[attrib.bindingIndex]; const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
gl::Buffer *bufferGL = binding.getBuffer().get(); 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. UNIMPLEMENTED();
if (attrib.type != GL_FLOAT) return gl::InternalError();
{
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);
} }
// 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)); ANGLE_TRY(stream->flush(context));
...@@ -137,17 +136,20 @@ void VertexArrayVk::syncState(const gl::Context *context, ...@@ -137,17 +136,20 @@ void VertexArrayVk::syncState(const gl::Context *context,
BufferVk *bufferVk = vk::GetImpl(bufferGL); BufferVk *bufferVk = vk::GetImpl(bufferGL);
mCurrentArrayBufferResources[attribIndex] = bufferVk; mCurrentArrayBufferResources[attribIndex] = bufferVk;
mCurrentArrayBufferHandles[attribIndex] = bufferVk->getVkBuffer().getHandle(); mCurrentArrayBufferHandles[attribIndex] = bufferVk->getVkBuffer().getHandle();
mClientMemoryAttribs.reset(attribIndex);
} }
else else
{ {
mCurrentArrayBufferResources[attribIndex] = nullptr; mCurrentArrayBufferResources[attribIndex] = nullptr;
mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE; mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
mClientMemoryAttribs.set(attribIndex);
} }
// TODO(jmadill): Offset handling. Assume zero for now. // TODO(jmadill): Offset handling. Assume zero for now.
mCurrentArrayBufferOffsets[attribIndex] = 0; mCurrentArrayBufferOffsets[attribIndex] = 0;
} }
else else
{ {
mClientMemoryAttribs.reset(attribIndex);
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
} }
......
...@@ -28,8 +28,8 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -28,8 +28,8 @@ class VertexArrayVk : public VertexArrayImpl
gl::Error streamVertexData(ContextVk *context, gl::Error streamVertexData(ContextVk *context,
StreamingBuffer *stream, StreamingBuffer *stream,
int firstVertex, size_t firstVertex,
int lastVertex); size_t lastVertex);
void syncState(const gl::Context *context, void syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits) override; const gl::VertexArray::DirtyBits &dirtyBits) override;
...@@ -65,6 +65,10 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -65,6 +65,10 @@ class VertexArrayVk : public VertexArrayImpl
gl::AttributesMask mDirtyPackedInputs; gl::AttributesMask mDirtyPackedInputs;
vk::VertexInputBindings mPackedInputBindings; vk::VertexInputBindings mPackedInputBindings;
vk::VertexInputAttributes mPackedInputAttributes; 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 } // 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