Commit 09303e44 by James Darpinian Committed by Commit Bot

Treat transform feedback generic binding point specially

The transform feedback generic binding point is not part of the transform feedback object and is not used for transform feedback. Only the indexed binding points are used. A buffer that is bound to the generic binding point should be usable for either transform feedback or non-transform-feedback purposes. Bug: 853978 Change-Id: I5b730212c65524188134ac34645328328664f0a4 Reviewed-on: https://chromium-review.googlesource.com/1112841 Commit-Queue: James Darpinian <jdarpinian@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 82af620e
...@@ -28,7 +28,8 @@ BufferState::BufferState() ...@@ -28,7 +28,8 @@ BufferState::BufferState()
mMapOffset(0), mMapOffset(0),
mMapLength(0), mMapLength(0),
mBindingCount(0), mBindingCount(0),
mTransformFeedbackBindingCount(0) mTransformFeedbackIndexedBindingCount(0),
mTransformFeedbackGenericBindingCount(0)
{ {
} }
...@@ -239,20 +240,35 @@ bool Buffer::isBound() const ...@@ -239,20 +240,35 @@ bool Buffer::isBound() const
bool Buffer::isBoundForTransformFeedbackAndOtherUse() const bool Buffer::isBoundForTransformFeedbackAndOtherUse() const
{ {
return mState.mTransformFeedbackBindingCount > 0 && // The transform feedback generic binding point is not an indexed binding point but it also does
mState.mTransformFeedbackBindingCount != mState.mBindingCount; // not count as a non-transform-feedback use of the buffer, so we subtract it from the binding
// count when checking if the buffer is bound to a non-transform-feedback location. See
// https://crbug.com/853978
return mState.mTransformFeedbackIndexedBindingCount > 0 &&
mState.mTransformFeedbackIndexedBindingCount !=
mState.mBindingCount - mState.mTransformFeedbackGenericBindingCount;
} }
void Buffer::onBindingChanged(const Context *context, bool bound, BufferBinding target) void Buffer::onBindingChanged(const Context *context,
bool bound,
BufferBinding target,
bool indexed)
{ {
ASSERT(bound || mState.mBindingCount > 0); ASSERT(bound || mState.mBindingCount > 0);
mState.mBindingCount += bound ? 1 : -1; mState.mBindingCount += bound ? 1 : -1;
if (target == BufferBinding::TransformFeedback) if (target == BufferBinding::TransformFeedback)
{ {
ASSERT(bound || mState.mTransformFeedbackBindingCount > 0); if (indexed)
mState.mTransformFeedbackBindingCount += bound ? 1 : -1; {
ASSERT(bound || mState.mTransformFeedbackIndexedBindingCount > 0);
mImpl->onStateChange(context, angle::SubjectMessage::BINDING_CHANGED); mState.mTransformFeedbackIndexedBindingCount += bound ? 1 : -1;
mImpl->onStateChange(context, angle::SubjectMessage::BINDING_CHANGED);
}
else
{
mState.mTransformFeedbackGenericBindingCount += bound ? 1 : -1;
}
} }
} }
......
...@@ -60,7 +60,8 @@ class BufferState final : angle::NonCopyable ...@@ -60,7 +60,8 @@ class BufferState final : angle::NonCopyable
GLint64 mMapOffset; GLint64 mMapOffset;
GLint64 mMapLength; GLint64 mMapLength;
int mBindingCount; int mBindingCount;
int mTransformFeedbackBindingCount; int mTransformFeedbackIndexedBindingCount;
int mTransformFeedbackGenericBindingCount;
}; };
class Buffer final : public RefCountObject, public LabeledObject class Buffer final : public RefCountObject, public LabeledObject
...@@ -116,7 +117,7 @@ class Buffer final : public RefCountObject, public LabeledObject ...@@ -116,7 +117,7 @@ class Buffer final : public RefCountObject, public LabeledObject
bool isBound() const; bool isBound() const;
bool isBoundForTransformFeedbackAndOtherUse() const; bool isBoundForTransformFeedbackAndOtherUse() const;
void onBindingChanged(const Context *context, bool bound, BufferBinding target); void onBindingChanged(const Context *context, bool bound, BufferBinding target, bool indexed);
private: private:
BufferState mState; BufferState mState;
......
...@@ -52,27 +52,29 @@ bool GetAlternativeQueryType(QueryType type, QueryType *alternativeType) ...@@ -52,27 +52,29 @@ bool GetAlternativeQueryType(QueryType type, QueryType *alternativeType)
void UpdateBufferBinding(const Context *context, void UpdateBufferBinding(const Context *context,
BindingPointer<Buffer> *binding, BindingPointer<Buffer> *binding,
Buffer *buffer, Buffer *buffer,
BufferBinding target) BufferBinding target,
bool indexed)
{ {
if (binding->get()) if (binding->get())
(*binding)->onBindingChanged(context, false, target); (*binding)->onBindingChanged(context, false, target, indexed);
binding->set(context, buffer); binding->set(context, buffer);
if (binding->get()) if (binding->get())
(*binding)->onBindingChanged(context, true, target); (*binding)->onBindingChanged(context, true, target, indexed);
} }
void UpdateBufferBinding(const Context *context, void UpdateBufferBinding(const Context *context,
OffsetBindingPointer<Buffer> *binding, OffsetBindingPointer<Buffer> *binding,
Buffer *buffer, Buffer *buffer,
BufferBinding target, BufferBinding target,
bool indexed,
GLintptr offset, GLintptr offset,
GLsizeiptr size) GLsizeiptr size)
{ {
if (binding->get()) if (binding->get())
(*binding)->onBindingChanged(context, false, target); (*binding)->onBindingChanged(context, false, target, indexed);
binding->set(context, buffer, offset, size); binding->set(context, buffer, offset, size);
if (binding->get()) if (binding->get())
(*binding)->onBindingChanged(context, true, target); (*binding)->onBindingChanged(context, true, target, indexed);
} }
State::State(bool debug, State::State(bool debug,
...@@ -281,7 +283,7 @@ void State::reset(const Context *context) ...@@ -281,7 +283,7 @@ void State::reset(const Context *context)
for (auto type : angle::AllEnums<BufferBinding>()) for (auto type : angle::AllEnums<BufferBinding>())
{ {
UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type); UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type, false);
} }
if (mProgram) if (mProgram)
...@@ -303,17 +305,17 @@ void State::reset(const Context *context) ...@@ -303,17 +305,17 @@ void State::reset(const Context *context)
for (auto &buf : mUniformBuffers) for (auto &buf : mUniformBuffers)
{ {
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::Uniform); UpdateBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, true);
} }
for (auto &buf : mAtomicCounterBuffers) for (auto &buf : mAtomicCounterBuffers)
{ {
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter); UpdateBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, true);
} }
for (auto &buf : mShaderStorageBuffers) for (auto &buf : mShaderStorageBuffers)
{ {
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage); UpdateBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, true);
} }
angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj); angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
...@@ -1417,19 +1419,19 @@ void State::setBufferBinding(const Context *context, BufferBinding target, Buffe ...@@ -1417,19 +1419,19 @@ void State::setBufferBinding(const Context *context, BufferBinding target, Buffe
switch (target) switch (target)
{ {
case BufferBinding::PixelPack: case BufferBinding::PixelPack:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target); UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING); mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
break; break;
case BufferBinding::PixelUnpack: case BufferBinding::PixelUnpack:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target); UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING); mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
break; break;
case BufferBinding::DrawIndirect: case BufferBinding::DrawIndirect:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target); UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING); mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
break; break;
case BufferBinding::DispatchIndirect: case BufferBinding::DispatchIndirect:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target); UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
mDirtyBits.set(DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING); mDirtyBits.set(DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING);
break; break;
case BufferBinding::ElementArray: case BufferBinding::ElementArray:
...@@ -1437,11 +1439,11 @@ void State::setBufferBinding(const Context *context, BufferBinding target, Buffe ...@@ -1437,11 +1439,11 @@ void State::setBufferBinding(const Context *context, BufferBinding target, Buffe
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
break; break;
case BufferBinding::ShaderStorage: case BufferBinding::ShaderStorage:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target); UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING); mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
break; break;
default: default:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target); UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
break; break;
} }
} }
...@@ -1462,16 +1464,17 @@ void State::setIndexedBufferBinding(const Context *context, ...@@ -1462,16 +1464,17 @@ void State::setIndexedBufferBinding(const Context *context,
setBufferBinding(context, target, buffer); setBufferBinding(context, target, buffer);
break; break;
case BufferBinding::Uniform: case BufferBinding::Uniform:
UpdateBufferBinding(context, &mUniformBuffers[index], buffer, target, offset, size); UpdateBufferBinding(context, &mUniformBuffers[index], buffer, target, true, offset,
size);
mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS); mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
break; break;
case BufferBinding::AtomicCounter: case BufferBinding::AtomicCounter:
UpdateBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target, offset, UpdateBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target, true,
size); offset, size);
break; break;
case BufferBinding::ShaderStorage: case BufferBinding::ShaderStorage:
UpdateBufferBinding(context, &mShaderStorageBuffers[index], buffer, target, offset, UpdateBufferBinding(context, &mShaderStorageBuffers[index], buffer, target, true,
size); offset, size);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -1519,7 +1522,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer) ...@@ -1519,7 +1522,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer)
{ {
if (mBoundBuffers[target].id() == bufferName) if (mBoundBuffers[target].id() == bufferName)
{ {
UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target); UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target, false);
} }
} }
...@@ -1535,7 +1538,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer) ...@@ -1535,7 +1538,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer)
{ {
if (buf.id() == bufferName) if (buf.id() == bufferName)
{ {
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::Uniform); UpdateBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, true);
} }
} }
...@@ -1543,7 +1546,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer) ...@@ -1543,7 +1546,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer)
{ {
if (buf.id() == bufferName) if (buf.id() == bufferName)
{ {
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter); UpdateBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, true);
} }
} }
...@@ -1551,7 +1554,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer) ...@@ -1551,7 +1554,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer)
{ {
if (buf.id() == bufferName) if (buf.id() == bufferName)
{ {
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage); UpdateBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, true);
} }
} }
} }
......
...@@ -238,8 +238,8 @@ void TransformFeedback::detachBuffer(const Context *context, GLuint bufferName) ...@@ -238,8 +238,8 @@ void TransformFeedback::detachBuffer(const Context *context, GLuint bufferName)
{ {
if (isBound) if (isBound)
{ {
mState.mIndexedBuffers[index]->onBindingChanged(context, false, mState.mIndexedBuffers[index]->onBindingChanged(
BufferBinding::TransformFeedback); context, false, BufferBinding::TransformFeedback, true);
} }
mState.mIndexedBuffers[index].set(context, nullptr); mState.mIndexedBuffers[index].set(context, nullptr);
mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]); mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]);
...@@ -258,12 +258,12 @@ void TransformFeedback::bindIndexedBuffer(const Context *context, ...@@ -258,12 +258,12 @@ void TransformFeedback::bindIndexedBuffer(const Context *context,
if (isBound && mState.mIndexedBuffers[index].get()) if (isBound && mState.mIndexedBuffers[index].get())
{ {
mState.mIndexedBuffers[index]->onBindingChanged(context, false, mState.mIndexedBuffers[index]->onBindingChanged(context, false,
BufferBinding::TransformFeedback); BufferBinding::TransformFeedback, true);
} }
mState.mIndexedBuffers[index].set(context, buffer, offset, size); mState.mIndexedBuffers[index].set(context, buffer, offset, size);
if (isBound && buffer) if (isBound && buffer)
{ {
buffer->onBindingChanged(context, true, BufferBinding::TransformFeedback); buffer->onBindingChanged(context, true, BufferBinding::TransformFeedback, true);
} }
mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]); mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]);
...@@ -308,7 +308,7 @@ void TransformFeedback::onBindingChanged(const Context *context, bool bound) ...@@ -308,7 +308,7 @@ void TransformFeedback::onBindingChanged(const Context *context, bool bound)
{ {
if (buffer.get()) if (buffer.get())
{ {
buffer->onBindingChanged(context, bound, BufferBinding::TransformFeedback); buffer->onBindingChanged(context, bound, BufferBinding::TransformFeedback, true);
} }
} }
} }
......
...@@ -65,7 +65,8 @@ void VertexArray::onDestroy(const Context *context) ...@@ -65,7 +65,8 @@ void VertexArray::onDestroy(const Context *context)
binding.setBuffer(context, nullptr, isBound); binding.setBuffer(context, nullptr, isBound);
} }
if (isBound && mState.mElementArrayBuffer.get()) if (isBound && mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::ElementArray); mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::ElementArray,
false);
mState.mElementArrayBuffer.set(context, nullptr); mState.mElementArrayBuffer.set(context, nullptr);
mVertexArray->destroy(context); mVertexArray->destroy(context);
SafeDelete(mVertexArray); SafeDelete(mVertexArray);
...@@ -106,7 +107,8 @@ void VertexArray::detachBuffer(const Context *context, GLuint bufferName) ...@@ -106,7 +107,8 @@ void VertexArray::detachBuffer(const Context *context, GLuint bufferName)
if (mState.mElementArrayBuffer.id() == bufferName) if (mState.mElementArrayBuffer.id() == bufferName)
{ {
if (isBound && mState.mElementArrayBuffer.get()) if (isBound && mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::Array); mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::Array,
false);
mState.mElementArrayBuffer.set(context, nullptr); mState.mElementArrayBuffer.set(context, nullptr);
} }
} }
...@@ -288,10 +290,12 @@ void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer) ...@@ -288,10 +290,12 @@ void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer)
{ {
bool isBound = context->isCurrentVertexArray(this); bool isBound = context->isCurrentVertexArray(this);
if (isBound && mState.mElementArrayBuffer.get()) if (isBound && mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::ElementArray); mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::ElementArray,
false);
mState.mElementArrayBuffer.set(context, buffer); mState.mElementArrayBuffer.set(context, buffer);
if (isBound && mState.mElementArrayBuffer.get()) if (isBound && mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onBindingChanged(context, true, BufferBinding::ElementArray); mState.mElementArrayBuffer->onBindingChanged(context, true, BufferBinding::ElementArray,
false);
mElementArrayBufferObserverBinding.bind(buffer ? buffer->getImplementation() : nullptr); mElementArrayBufferObserverBinding.bind(buffer ? buffer->getImplementation() : nullptr);
mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER); mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
} }
...@@ -319,7 +323,8 @@ gl::Error VertexArray::syncState(const Context *context) ...@@ -319,7 +323,8 @@ gl::Error VertexArray::syncState(const Context *context)
void VertexArray::onBindingChanged(const Context *context, bool bound) void VertexArray::onBindingChanged(const Context *context, bool bound)
{ {
if (mState.mElementArrayBuffer.get()) if (mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onBindingChanged(context, bound, BufferBinding::ElementArray); mState.mElementArrayBuffer->onBindingChanged(context, bound, BufferBinding::ElementArray,
false);
for (auto &binding : mState.mVertexBindings) for (auto &binding : mState.mVertexBindings)
{ {
binding.onContainerBindingChanged(context, bound); binding.onContainerBindingChanged(context, bound);
......
...@@ -43,16 +43,16 @@ VertexBinding &VertexBinding::operator=(VertexBinding &&binding) ...@@ -43,16 +43,16 @@ VertexBinding &VertexBinding::operator=(VertexBinding &&binding)
void VertexBinding::setBuffer(const gl::Context *context, Buffer *bufferIn, bool containerIsBound) void VertexBinding::setBuffer(const gl::Context *context, Buffer *bufferIn, bool containerIsBound)
{ {
if (mBuffer.get() && containerIsBound) if (mBuffer.get() && containerIsBound)
mBuffer->onBindingChanged(context, false, BufferBinding::Array); mBuffer->onBindingChanged(context, false, BufferBinding::Array, true);
mBuffer.set(context, bufferIn); mBuffer.set(context, bufferIn);
if (mBuffer.get() && containerIsBound) if (mBuffer.get() && containerIsBound)
mBuffer->onBindingChanged(context, true, BufferBinding::Array); mBuffer->onBindingChanged(context, true, BufferBinding::Array, true);
} }
void VertexBinding::onContainerBindingChanged(const Context *context, bool bound) const void VertexBinding::onContainerBindingChanged(const Context *context, bool bound) const
{ {
if (mBuffer.get()) if (mBuffer.get())
mBuffer->onBindingChanged(context, bound, BufferBinding::Array); mBuffer->onBindingChanged(context, bound, BufferBinding::Array, true);
} }
void VertexBinding::updateCachedBufferSizeMinusOffset() void VertexBinding::updateCachedBufferSizeMinusOffset()
......
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