Commit 0136ac37 by Jiacheng Lu Committed by Commit Bot

Separate dirty bit for attrib's binding VBO change

Make a separate dirty bit DIRTY_ATTRIB_POINTER_BUFFER for vertex attrib's binding buffer change. So in handling glVertexAttribPointer, ANGLE will only modify a vulkan graphics pipeline when attrib.format, attrib.stride or attrib.divisor change. If only the VBO pointer changes, then Vulkan can update the state via "vkCmdBindVertexBuffers()" without triggering a pipeline update. Bug: angleproject:3256 Change-Id: I01e02adde3708963b496a20050a5723e8eb57ab2 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1707614Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jiacheng Lu <lujc@google.com>
parent 6aca71d7
......@@ -457,8 +457,6 @@ ANGLE_INLINE void VertexArray::setVertexAttribPointerImpl(const Context *context
{
ASSERT(attribIndex < getMaxAttribs());
GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
SetComponentTypeMask(componentType, attribIndex, &mState.mVertexAttributesTypeMask);
......@@ -473,28 +471,35 @@ ANGLE_INLINE void VertexArray::setVertexAttribPointerImpl(const Context *context
GLsizei effectiveStride =
stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
if (pointer != attrib.pointer || attrib.vertexAttribArrayStride != static_cast<GLuint>(stride))
if (attrib.vertexAttribArrayStride != static_cast<GLuint>(stride))
{
attribDirty = true;
}
attrib.pointer = pointer;
attrib.vertexAttribArrayStride = stride;
// "Pointer buffer" dirty bit disabled because of a bug. http://anglebug.com/3256
bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride);
setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER);
ANGLE_UNUSED_VARIABLE(attribDirty);
// if (bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride) &&
// !attribDirty)
//{
// setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER_BUFFER);
//}
// else if (attribDirty)
//{
// setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER);
//}
// If we switch from an array buffer to a client pointer(or vice-versa), we set the whole
// attribute dirty. This notifies the Vulkan back-end to update all its caches.
const VertexBinding &binding = mState.mVertexBindings[attribIndex];
if ((boundBuffer == nullptr) != (binding.getBuffer().get() == nullptr))
{
attribDirty = true;
}
// Change of attrib.pointer is not part of attribDirty. Pointer is actually the buffer offset
// which is handled within bindVertexBufferImpl and reflected in bufferDirty.
attrib.pointer = pointer;
GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
const bool bufferDirty =
bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride);
if (attribDirty)
{
setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER);
}
else if (bufferDirty)
{
setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER_BUFFER);
}
mState.mNullPointerClientMemoryAttribsMask.set(attribIndex,
boundBuffer == nullptr && pointer == nullptr);
......
......@@ -108,11 +108,8 @@ class VertexArrayVk : public VertexArrayImpl
angle::Result syncDirtyAttrib(ContextVk *contextVk,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding,
size_t attribIndex);
void syncDirtyBuffer(ContextVk *contextVk,
const gl::VertexBinding &binding,
size_t bindingIndex);
size_t attribIndex,
bool bufferOnly);
gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles;
gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets;
......
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