Commit 6d32cefd by Jamie Madill Committed by Commit Bot

Use Observer pattern for Buffers in front-end.

This will allow us to react to state change notifications for validation caching. It also cleans up some of the logic in the D3D11 State Manager. Bug: angleproject:2747 Change-Id: I85ed6404206c2b9bf504d552cf5751be56e62146 Reviewed-on: https://chromium-review.googlesource.com/1172086Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 70aeda49
...@@ -37,6 +37,9 @@ enum ...@@ -37,6 +37,9 @@ enum
IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS + IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS +
IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS, IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS,
// GL_EXT_geometry_shader increases the minimum value of GL_MAX_UNIFORM_BUFFER_BINDINGS to 48.
IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS = 48,
IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS = 4, IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS = 4,
// Maximum number of views which are supported by the implementation of ANGLE_multiview. // Maximum number of views which are supported by the implementation of ANGLE_multiview.
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/queryconversions.h" #include "libANGLE/queryconversions.h"
#include "libANGLE/queryutils.h" #include "libANGLE/queryutils.h"
#include "libANGLE/renderer/BufferImpl.h"
#include "libANGLE/renderer/ContextImpl.h" #include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/EGLImplFactory.h" #include "libANGLE/renderer/EGLImplFactory.h"
#include "libANGLE/renderer/Format.h" #include "libANGLE/renderer/Format.h"
...@@ -298,11 +299,17 @@ static_assert(static_cast<gl::PrimitiveMode>(10) == gl::PrimitiveMode::TriangleS ...@@ -298,11 +299,17 @@ static_assert(static_cast<gl::PrimitiveMode>(10) == gl::PrimitiveMode::TriangleS
static_assert(static_cast<gl::PrimitiveMode>(11) == gl::PrimitiveMode::EnumCount, static_assert(static_cast<gl::PrimitiveMode>(11) == gl::PrimitiveMode::EnumCount,
"gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts."); "gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts.");
constexpr angle::SubjectIndex kVertexArraySubjectIndex = gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES + 0; enum SubjectIndexes : angle::SubjectIndex
constexpr angle::SubjectIndex kReadFramebufferSubjectIndex = {
gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES + 1; kTexture0SubjectIndex = 0,
constexpr angle::SubjectIndex kDrawFramebufferSubjectIndex = kTextureMaxSubjectIndex = kTexture0SubjectIndex + gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES + 2; kUniformBuffer0SubjectIndex = kTextureMaxSubjectIndex,
kUniformBufferMaxSubjectIndex =
kUniformBuffer0SubjectIndex + gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS,
kVertexArraySubjectIndex = kUniformBufferMaxSubjectIndex,
kReadFramebufferSubjectIndex,
kDrawFramebufferSubjectIndex
};
} // anonymous namespace } // anonymous namespace
namespace gl namespace gl
...@@ -362,6 +369,12 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -362,6 +369,12 @@ Context::Context(rx::EGLImplFactory *implFactory,
// Needed to solve a Clang warning of unused variables. // Needed to solve a Clang warning of unused variables.
ANGLE_UNUSED_VARIABLE(mSavedArgsType); ANGLE_UNUSED_VARIABLE(mSavedArgsType);
ANGLE_UNUSED_VARIABLE(mParamsBuffer); ANGLE_UNUSED_VARIABLE(mParamsBuffer);
for (angle::SubjectIndex uboIndex = kUniformBuffer0SubjectIndex;
uboIndex < kUniformBufferMaxSubjectIndex; ++uboIndex)
{
mUniformBufferObserverBindings.emplace_back(this, uboIndex);
}
} }
void Context::initialize() void Context::initialize()
...@@ -3233,6 +3246,8 @@ void Context::initCaps() ...@@ -3233,6 +3246,8 @@ void Context::initCaps()
LimitCap(&mCaps.maxShaderUniformBlocks[ShaderType::Vertex], LimitCap(&mCaps.maxShaderUniformBlocks[ShaderType::Vertex],
IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS); IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
LimitCap(&mCaps.maxUniformBufferBindings, IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS);
LimitCap(&mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4); LimitCap(&mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
LimitCap(&mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4); LimitCap(&mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
...@@ -4937,8 +4952,12 @@ void Context::bindBufferRange(BufferBinding target, ...@@ -4937,8 +4952,12 @@ void Context::bindBufferRange(BufferBinding target,
GLintptr offset, GLintptr offset,
GLsizeiptr size) GLsizeiptr size)
{ {
Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer); Buffer *object = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer);
mGLState.setIndexedBufferBinding(this, target, index, bufferObject, offset, size); mGLState.setIndexedBufferBinding(this, target, index, object, offset, size);
if (target == BufferBinding::Uniform)
{
mUniformBufferObserverBindings[index].bind(object ? object->getImplementation() : nullptr);
}
} }
void Context::bindFramebuffer(GLenum target, GLuint framebuffer) void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
...@@ -7633,8 +7652,15 @@ void Context::onSubjectStateChange(const Context *context, ...@@ -7633,8 +7652,15 @@ void Context::onSubjectStateChange(const Context *context,
break; break;
default: default:
ASSERT(index < mGLState.getActiveTexturesCache().size()); if (index < kTextureMaxSubjectIndex)
mGLState.onActiveTextureStateChange(index); {
mGLState.onActiveTextureStateChange(index);
}
else
{
ASSERT(index < kUniformBufferMaxSubjectIndex);
mGLState.onUniformBufferStateChange(index - kUniformBuffer0SubjectIndex);
}
break; break;
} }
} }
......
...@@ -1693,6 +1693,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -1693,6 +1693,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
angle::ObserverBinding mVertexArrayObserverBinding; angle::ObserverBinding mVertexArrayObserverBinding;
angle::ObserverBinding mDrawFramebufferObserverBinding; angle::ObserverBinding mDrawFramebufferObserverBinding;
angle::ObserverBinding mReadFramebufferObserverBinding; angle::ObserverBinding mReadFramebufferObserverBinding;
std::vector<angle::ObserverBinding> mUniformBufferObserverBindings;
// Not really a property of context state. The size and contexts change per-api-call. // Not really a property of context state. The size and contexts change per-api-call.
mutable angle::ScratchBuffer mScratchBuffer; mutable angle::ScratchBuffer mScratchBuffer;
......
...@@ -2876,6 +2876,12 @@ void State::onActiveTextureStateChange(size_t textureIndex) ...@@ -2876,6 +2876,12 @@ void State::onActiveTextureStateChange(size_t textureIndex)
} }
} }
void State::onUniformBufferStateChange(size_t uniformBufferIndex)
{
// This could be represented by a different dirty bit. Using the same one keeps it simple.
mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
}
Error State::clearUnclearedActiveTextures(const Context *context) Error State::clearUnclearedActiveTextures(const Context *context)
{ {
ASSERT(mRobustResourceInit); ASSERT(mRobustResourceInit);
......
...@@ -474,6 +474,7 @@ class State : angle::NonCopyable ...@@ -474,6 +474,7 @@ class State : angle::NonCopyable
ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; } ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
void onActiveTextureStateChange(size_t textureIndex); void onActiveTextureStateChange(size_t textureIndex);
void onUniformBufferStateChange(size_t uniformBufferIndex);
Error clearUnclearedActiveTextures(const Context *context); Error clearUnclearedActiveTextures(const Context *context);
......
...@@ -3314,8 +3314,6 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con ...@@ -3314,8 +3314,6 @@ angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *con
default: default:
UNREACHABLE(); UNREACHABLE();
} }
mConstantBufferObserver.bindToShader(shaderType, bufferIndex, bufferStorage);
} }
return angle::Result::Continue(); return angle::Result::Continue();
...@@ -3326,8 +3324,6 @@ angle::Result StateManager11::syncUniformBuffers(const gl::Context *context) ...@@ -3326,8 +3324,6 @@ angle::Result StateManager11::syncUniformBuffers(const gl::Context *context)
gl::ShaderMap<unsigned int> shaderReservedUBOs = mRenderer->getReservedShaderUniformBuffers(); gl::ShaderMap<unsigned int> shaderReservedUBOs = mRenderer->getReservedShaderUniformBuffers();
mProgramD3D->updateUniformBufferCache(context->getCaps(), shaderReservedUBOs); mProgramD3D->updateUniformBufferCache(context->getCaps(), shaderReservedUBOs);
mConstantBufferObserver.reset();
ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Vertex)); ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Vertex));
ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Fragment)); ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Fragment));
if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry)) if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry))
...@@ -3374,60 +3370,6 @@ angle::Result StateManager11::syncTransformFeedbackBuffers(const gl::Context *co ...@@ -3374,60 +3370,6 @@ angle::Result StateManager11::syncTransformFeedbackBuffers(const gl::Context *co
return angle::Result::Continue(); return angle::Result::Continue();
} }
// ConstantBufferObserver implementation.
// TODO(jiawei.shao@intel.com): add constant buffer observers for geometry shader.
StateManager11::ConstantBufferObserver::ConstantBufferObserver()
{
for (size_t vsIndex = 0; vsIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS;
++vsIndex)
{
mShaderBindings[gl::ShaderType::Vertex].emplace_back(this, vsIndex);
}
for (size_t fsIndex = 0; fsIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS;
++fsIndex)
{
mShaderBindings[gl::ShaderType::Fragment].emplace_back(this, fsIndex);
}
}
StateManager11::ConstantBufferObserver::~ConstantBufferObserver()
{
}
void StateManager11::ConstantBufferObserver::onSubjectStateChange(const gl::Context *context,
angle::SubjectIndex index,
angle::SubjectMessage message)
{
if (message == angle::SubjectMessage::STORAGE_CHANGED)
{
StateManager11 *stateManager =
GetImplAs<Context11>(context)->getRenderer()->getStateManager();
stateManager->invalidateProgramUniformBuffers();
}
}
void StateManager11::ConstantBufferObserver::bindToShader(gl::ShaderType shaderType,
size_t index,
Buffer11 *buffer)
{
ASSERT(buffer);
ASSERT(shaderType != gl::ShaderType::InvalidEnum);
ASSERT(index < mShaderBindings[shaderType].size());
mShaderBindings[shaderType][index].bind(buffer);
}
void StateManager11::ConstantBufferObserver::reset()
{
for (std::vector<angle::ObserverBinding> &shaderBindings : mShaderBindings)
{
for (angle::ObserverBinding &shaderBinding : shaderBindings)
{
shaderBinding.bind(nullptr);
}
}
}
void StateManager11::syncPrimitiveTopology(const gl::State &glState, void StateManager11::syncPrimitiveTopology(const gl::State &glState,
gl::PrimitiveMode currentDrawMode) gl::PrimitiveMode currentDrawMode)
{ {
......
...@@ -548,24 +548,6 @@ class StateManager11 final : angle::NonCopyable ...@@ -548,24 +548,6 @@ class StateManager11 final : angle::NonCopyable
FragmentConstantBufferArray<GLintptr> mCurrentConstantBufferPSOffset; FragmentConstantBufferArray<GLintptr> mCurrentConstantBufferPSOffset;
FragmentConstantBufferArray<GLsizeiptr> mCurrentConstantBufferPSSize; FragmentConstantBufferArray<GLsizeiptr> mCurrentConstantBufferPSSize;
class ConstantBufferObserver : public angle::ObserverInterface
{
public:
ConstantBufferObserver();
~ConstantBufferObserver() override;
void onSubjectStateChange(const gl::Context *context,
angle::SubjectIndex index,
angle::SubjectMessage message) override;
void reset();
void bindToShader(gl::ShaderType shaderType, size_t index, Buffer11 *buffer);
private:
gl::ShaderMap<std::vector<angle::ObserverBinding>> mShaderBindings;
};
ConstantBufferObserver mConstantBufferObserver;
// Currently applied transform feedback buffers // Currently applied transform feedback buffers
Serial mAppliedTFSerial; Serial mAppliedTFSerial;
......
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