Commit bcef3224 by Jamie Madill Committed by Commit Bot

Move client attribs mask to front-end.

The Vulkan and GL back-ends both had a client attributes mask. This consolidates them into the front-end, where it can also be used in the validation layer. Also includes a fix which was incorrectly setting the enabled mask in setVertexAttribFormatImpl. Bug: angleproject:1391 Change-Id: I5e45c1e2a56b30a36dec1482d170592c30a16d40 Reviewed-on: https://chromium-review.googlesource.com/1008272 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarLuc Ferron <lucferron@chromium.org>
parent e1326469
......@@ -15,7 +15,7 @@
namespace gl
{
// VertexArrayState implementation.
VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings)
: mLabel(), mVertexBindings(maxAttribBindings)
{
......@@ -31,6 +31,12 @@ VertexArrayState::~VertexArrayState()
{
}
gl::AttributesMask VertexArrayState::getEnabledClientMemoryAttribsMask() const
{
return (mClientMemoryAttribsMask & mEnabledAttributesMask);
}
// VertexArray implementation.
VertexArray::VertexArray(rx::GLImplFactory *factory,
GLuint id,
size_t maxAttribs,
......@@ -49,7 +55,7 @@ VertexArray::VertexArray(rx::GLImplFactory *factory,
void VertexArray::onDestroy(const Context *context)
{
bool isBound = context->isCurrentVertexArray(this);
for (auto &binding : mState.mVertexBindings)
for (VertexBinding &binding : mState.mVertexBindings)
{
binding.setBuffer(context, nullptr, isBound);
}
......@@ -202,7 +208,6 @@ void VertexArray::setVertexAttribFormatImpl(size_t attribIndex,
attrib->pureInteger = pureInteger;
attrib->relativeOffset = relativeOffset;
mState.mVertexAttributesTypeMask.setIndex(GetVertexAttributeBaseType(*attrib), attribIndex);
mState.mEnabledAttributesMask.set(attribIndex);
}
void VertexArray::setVertexAttribFormat(size_t attribIndex,
......@@ -265,6 +270,8 @@ void VertexArray::setVertexAttribPointer(const Context *context,
bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride);
setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER);
mState.mClientMemoryAttribsMask.set(attribIndex, boundBuffer == nullptr);
}
void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer)
......
......@@ -63,6 +63,9 @@ class VertexArrayState final : angle::NonCopyable
return mVertexAttributes[attribIndex].bindingIndex;
}
// Combines mClientMemoryAttribsMask with mEnabledAttributesMask.
gl::AttributesMask getEnabledClientMemoryAttribsMask() const;
private:
friend class VertexArray;
std::string mLabel;
......@@ -71,6 +74,12 @@ class VertexArrayState final : angle::NonCopyable
std::vector<VertexBinding> mVertexBindings;
AttributesMask mEnabledAttributesMask;
ComponentTypeMask mVertexAttributesTypeMask;
// From the GLES 3.1 spec:
// When a generic attribute array is sourced from client memory, the vertex attribute binding
// state is ignored. Thus we don't have to worry about binding state when using client memory
// attribs.
gl::AttributesMask mClientMemoryAttribsMask;
};
class VertexArray final : public angle::ObserverInterface, public LabeledObject
......
......@@ -26,12 +26,6 @@ namespace rx
{
namespace
{
// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
bool AttributeNeedsStreaming(const VertexAttribute &attrib, const VertexBinding &binding)
{
return (attrib.enabled && binding.getBuffer().get() == nullptr);
}
bool SameVertexAttribFormat(const VertexAttribute &a, const VertexAttribute &b)
{
return a.size == b.size && a.type == b.type && a.normalized == b.normalized &&
......@@ -154,7 +148,8 @@ gl::Error VertexArrayGL::syncDrawState(const gl::Context *context,
{
// Check if any attributes need to be streamed, determines if the index range needs to be
// computed
bool attributesNeedStreaming = mAttributesNeedStreaming.any();
const gl::AttributesMask &needsStreamingAttribs =
(mState.getEnabledClientMemoryAttribsMask() & activeAttributesMask);
// Determine if an index buffer needs to be streamed and the range of vertices that need to be
// copied
......@@ -162,7 +157,7 @@ gl::Error VertexArrayGL::syncDrawState(const gl::Context *context,
if (type != GL_NONE)
{
ANGLE_TRY(syncIndexData(context, count, type, indices, primitiveRestartEnabled,
attributesNeedStreaming, &indexRange, outIndices));
needsStreamingAttribs.any(), &indexRange, outIndices));
}
else
{
......@@ -171,9 +166,9 @@ gl::Error VertexArrayGL::syncDrawState(const gl::Context *context,
indexRange.end = first + count - 1;
}
if (attributesNeedStreaming)
if (needsStreamingAttribs.any())
{
ANGLE_TRY(streamAttributes(activeAttributesMask, instanceCount, indexRange));
ANGLE_TRY(streamAttributes(needsStreamingAttribs, instanceCount, indexRange));
}
return gl::NoError();
......@@ -261,7 +256,7 @@ gl::Error VertexArrayGL::syncIndexData(const gl::Context *context,
return gl::NoError();
}
void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask,
void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &attribsToStream,
GLsizei instanceCount,
const gl::IndexRange &indexRange,
size_t *outStreamingDataSize,
......@@ -270,18 +265,15 @@ void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &act
*outStreamingDataSize = 0;
*outMaxAttributeDataSize = 0;
ASSERT(mAttributesNeedStreaming.any());
ASSERT(attribsToStream.any());
const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings();
gl::AttributesMask attribsToStream = (mAttributesNeedStreaming & activeAttributesMask);
for (auto idx : attribsToStream)
{
const auto &attrib = attribs[idx];
const auto &binding = bindings[attrib.bindingIndex];
ASSERT(AttributeNeedsStreaming(attrib, binding));
// If streaming is going to be required, compute the size of the required buffer
// and how much slack space at the beginning of the buffer will be required by determining
......@@ -295,7 +287,7 @@ void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &act
}
}
gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttributesMask,
gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &attribsToStream,
GLsizei instanceCount,
const gl::IndexRange &indexRange) const
{
......@@ -303,8 +295,8 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib
size_t streamingDataSize = 0;
size_t maxAttributeDataSize = 0;
computeStreamingAttributeSizes(activeAttributesMask, instanceCount, indexRange,
&streamingDataSize, &maxAttributeDataSize);
computeStreamingAttributeSizes(attribsToStream, instanceCount, indexRange, &streamingDataSize,
&maxAttributeDataSize);
if (streamingDataSize == 0)
{
......@@ -345,15 +337,12 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib
const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings();
gl::AttributesMask attribsToStream = (mAttributesNeedStreaming & activeAttributesMask);
for (auto idx : attribsToStream)
{
const auto &attrib = attribs[idx];
ASSERT(IsVertexAttribPointerSupported(idx, attrib));
const auto &binding = bindings[attrib.bindingIndex];
ASSERT(AttributeNeedsStreaming(attrib, binding));
GLuint adjustedDivisor = GetAdjustedDivisor(mAppliedNumViews, binding.getDivisor());
const size_t streamedVertexCount = ComputeVertexBindingElementCount(
......@@ -425,13 +414,6 @@ GLuint VertexArrayGL::getAppliedElementArrayBufferID() const
return GetImplAs<BufferGL>(mAppliedElementArrayBuffer.get())->getBufferID();
}
void VertexArrayGL::updateNeedsStreaming(size_t attribIndex)
{
const auto &attrib = mState.getVertexAttribute(attribIndex);
const auto &binding = mState.getBindingFromAttribIndex(attribIndex);
mAttributesNeedStreaming.set(attribIndex, AttributeNeedsStreaming(attrib, binding));
}
void VertexArrayGL::updateAttribEnabled(size_t attribIndex)
{
const bool enabled = mState.getVertexAttribute(attribIndex).enabled;
......@@ -440,8 +422,6 @@ void VertexArrayGL::updateAttribEnabled(size_t attribIndex)
return;
}
updateNeedsStreaming(attribIndex);
if (enabled)
{
mFunctions->enableVertexAttribArray(static_cast<GLuint>(attribIndex));
......@@ -462,21 +442,12 @@ void VertexArrayGL::updateAttribPointer(const gl::Context *context, size_t attri
// of the binding indexed attrib.bindingIndex (unless attribIndex == attrib.bindingIndex).
const VertexBinding &binding = mState.getVertexBinding(attribIndex);
// Since mAttributesNeedStreaming[attribIndex] keeps the value set in the last draw, here we
// only need to update it when the buffer has been changed. e.g. When we set an attribute to be
// streamed in the last draw, and only change its format in this draw without calling
// updateNeedsStreaming, it will still be streamed because the flag is already on.
const auto &bindingBuffer = binding.getBuffer();
if (bindingBuffer != mAppliedBindings[attribIndex].getBuffer())
{
updateNeedsStreaming(attribIndex);
}
// Early return when the vertex attribute isn't using a buffer object:
// - If we need to stream, defer the attribPointer to the draw call.
// - Skip the attribute that is disabled and uses a client memory pointer.
// - Skip the attribute whose buffer is detached by BindVertexBuffer. Since it cannot have a
// client memory pointer either, it must be disabled and shouldn't affect the draw.
const auto &bindingBuffer = binding.getBuffer();
const Buffer *arrayBuffer = bindingBuffer.get();
if (arrayBuffer == nullptr)
{
......
......@@ -74,14 +74,14 @@ class VertexArrayGL : public VertexArrayImpl
// Returns the amount of space needed to stream all attributes that need streaming
// and the data size of the largest attribute
void computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask,
void computeStreamingAttributeSizes(const gl::AttributesMask &attribsToStream,
GLsizei instanceCount,
const gl::IndexRange &indexRange,
size_t *outStreamingDataSize,
size_t *outMaxAttributeDataSize) const;
// Stream attributes that have client data
gl::Error streamAttributes(const gl::AttributesMask &activeAttributesMask,
gl::Error streamAttributes(const gl::AttributesMask &attribsToStream,
GLsizei instanceCount,
const gl::IndexRange &indexRange) const;
void syncDirtyAttrib(const gl::Context *context,
......@@ -125,9 +125,7 @@ class VertexArrayGL : public VertexArrayImpl
mutable size_t mStreamingArrayBufferSize;
mutable GLuint mStreamingArrayBuffer;
gl::AttributesMask mAttributesNeedStreaming;
};
}
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_VERTEXARRAYGL_H_
......@@ -70,8 +70,8 @@ gl::Error VertexArrayVk::streamVertexData(RendererVk *renderer,
{
ASSERT(!attribsToStream.none());
const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings();
const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings();
const size_t lastVertex = drawCallParams.firstVertex() + drawCallParams.vertexCount();
......@@ -243,20 +243,17 @@ void VertexArrayVk::syncDirtyAttrib(const gl::VertexAttribute &attrib,
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();
}
}
......@@ -439,12 +436,13 @@ gl::Error VertexArrayVk::onDraw(const gl::Context *context,
{
const gl::State &state = context->getGLState();
const gl::Program *programGL = state.getProgram();
const gl::AttributesMask &clientAttribs = mState.getEnabledClientMemoryAttribsMask();
const gl::AttributesMask &activeAttribs = programGL->getActiveAttribLocationsMask();
uint32_t maxAttrib = programGL->getState().getMaxActiveAttribLocation();
if (mClientMemoryAttribs.any())
if (clientAttribs.any())
{
const gl::AttributesMask &attribsToStream = (mClientMemoryAttribs & activeAttribs);
const gl::AttributesMask &attribsToStream = (clientAttribs & activeAttribs);
if (attribsToStream.any())
{
ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
......
......@@ -116,10 +116,6 @@ class VertexArrayVk : public VertexArrayImpl
vk::VertexInputBindings mPackedInputBindings;
vk::VertexInputAttributes mPackedInputAttributes;
// Which attributes need to be copied from client memory.
// TODO(jmadill): Move this to VertexArrayState. http://anglebug.com/1391
gl::AttributesMask mClientMemoryAttribs;
vk::DynamicBuffer mDynamicVertexData;
vk::DynamicBuffer mDynamicIndexData;
......
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