Commit ff4224d6 by Jamie Madill

Fix deleting a buffer not updating VAO validation.

Deleting a buffer that is bound to a VAO should act as if the application unbound the buffer. Unbinding the buffer should update relevant validation caches. But we were missing the logic that updates the validation caches. This CL adds the necessary cache updates. It does not include a regression test. The test was causing an unrelated regression that is going to be a bit longer. It should not block this fix. Bug: chromium:943538 Change-Id: Ib073cd07a230ca073a5b14bc054e961158a0097d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1536491 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> (cherry picked from commit f7f15ac2) Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1556697Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 0e5cf404
...@@ -1799,6 +1799,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -1799,6 +1799,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
std::shared_ptr<angle::WorkerThreadPool> getWorkerThreadPool() const { return mThreadPool; } std::shared_ptr<angle::WorkerThreadPool> getWorkerThreadPool() const { return mThreadPool; }
const StateCache &getStateCache() const { return mStateCache; } const StateCache &getStateCache() const { return mStateCache; }
StateCache &getStateCache() { return mStateCache; }
void onSubjectStateChange(const Context *context, void onSubjectStateChange(const Context *context,
angle::SubjectIndex index, angle::SubjectIndex index,
......
...@@ -1543,7 +1543,7 @@ const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t ...@@ -1543,7 +1543,7 @@ const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t
return mShaderStorageBuffers[index]; return mShaderStorageBuffers[index];
} }
angle::Result State::detachBuffer(const Context *context, const Buffer *buffer) angle::Result State::detachBuffer(Context *context, const Buffer *buffer)
{ {
if (!buffer->isBound()) if (!buffer->isBound())
{ {
...@@ -1564,7 +1564,11 @@ angle::Result State::detachBuffer(const Context *context, const Buffer *buffer) ...@@ -1564,7 +1564,11 @@ angle::Result State::detachBuffer(const Context *context, const Buffer *buffer)
ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferName)); ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferName));
} }
getVertexArray()->detachBuffer(context, bufferName); if (getVertexArray()->detachBuffer(context, bufferName))
{
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
context->getStateCache().onVertexArrayStateChange(context);
}
for (auto &buf : mUniformBuffers) for (auto &buf : mUniformBuffers)
{ {
......
...@@ -343,7 +343,7 @@ class State : angle::NonCopyable ...@@ -343,7 +343,7 @@ class State : angle::NonCopyable
const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const; const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
// Detach a buffer from all bindings // Detach a buffer from all bindings
angle::Result detachBuffer(const Context *context, const Buffer *buffer); angle::Result detachBuffer(Context *context, const Buffer *buffer);
// Vertex attrib manipulation // Vertex attrib manipulation
void setEnableVertexAttribArray(unsigned int attribNum, bool enabled); void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
......
...@@ -170,9 +170,10 @@ const std::string &VertexArray::getLabel() const ...@@ -170,9 +170,10 @@ const std::string &VertexArray::getLabel() const
return mState.mLabel; return mState.mLabel;
} }
void VertexArray::detachBuffer(const Context *context, GLuint bufferName) bool VertexArray::detachBuffer(const Context *context, GLuint bufferName)
{ {
bool isBound = context->isCurrentVertexArray(this); bool isBound = context->isCurrentVertexArray(this);
bool anyBufferDetached = false;
for (size_t bindingIndex = 0; bindingIndex < gl::MAX_VERTEX_ATTRIB_BINDINGS; ++bindingIndex) for (size_t bindingIndex = 0; bindingIndex < gl::MAX_VERTEX_ATTRIB_BINDINGS; ++bindingIndex)
{ {
VertexBinding &binding = mState.mVertexBindings[bindingIndex]; VertexBinding &binding = mState.mVertexBindings[bindingIndex];
...@@ -185,6 +186,19 @@ void VertexArray::detachBuffer(const Context *context, GLuint bufferName) ...@@ -185,6 +186,19 @@ void VertexArray::detachBuffer(const Context *context, GLuint bufferName)
} }
binding.setBuffer(context, nullptr); binding.setBuffer(context, nullptr);
mArrayBufferObserverBindings[bindingIndex].reset(); mArrayBufferObserverBindings[bindingIndex].reset();
if (context->getClientVersion() >= ES_3_1)
{
setDirtyBindingBit(bindingIndex, DIRTY_BINDING_BUFFER);
}
else
{
ASSERT(binding.getBoundAttributesMask() == AttributesMask(1ull << bindingIndex));
setDirtyAttribBit(bindingIndex, DIRTY_ATTRIB_POINTER);
}
anyBufferDetached = true;
mState.mClientMemoryAttribsMask |= binding.getBoundAttributesMask();
} }
} }
...@@ -193,7 +207,11 @@ void VertexArray::detachBuffer(const Context *context, GLuint bufferName) ...@@ -193,7 +207,11 @@ void VertexArray::detachBuffer(const Context *context, GLuint bufferName)
if (isBound && mState.mElementArrayBuffer.get()) if (isBound && mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onNonTFBindingChanged(-1); mState.mElementArrayBuffer->onNonTFBindingChanged(-1);
mState.mElementArrayBuffer.bind(context, nullptr); mState.mElementArrayBuffer.bind(context, nullptr);
mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
anyBufferDetached = true;
} }
return anyBufferDetached;
} }
const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const
......
...@@ -116,7 +116,9 @@ class VertexArray final : public angle::ObserverInterface, ...@@ -116,7 +116,9 @@ class VertexArray final : public angle::ObserverInterface,
return mState.getBindingFromAttribIndex(attribIndex); return mState.getBindingFromAttribIndex(attribIndex);
} }
void detachBuffer(const Context *context, GLuint bufferName); // Returns true if the function finds and detaches a bound buffer.
bool detachBuffer(const Context *context, GLuint bufferName);
void setVertexAttribDivisor(const Context *context, size_t index, GLuint divisor); void setVertexAttribDivisor(const Context *context, size_t index, GLuint divisor);
void enableAttribute(size_t attribIndex, bool enabledState); void enableAttribute(size_t attribIndex, bool enabledState);
......
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