Commit 39967e4e by Jamie Madill Committed by Commit Bot

GL: Use dirty bits for texture and sampler bindings.

In StateManagerGL, use the texture, sampler and program binding dirty bits to set a dirty bool that is checked once per draw call. This completes the GL back-end texture dirty bits. BUG=angleproject:1387 Change-Id: I619a89bf98ded5e55353f6ca44e814605f7ce492 Reviewed-on: https://chromium-review.googlesource.com/648055 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 06ef36b9
...@@ -165,7 +165,8 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, ...@@ -165,7 +165,8 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
mIsSideBySideDrawFramebuffer(false), mIsSideBySideDrawFramebuffer(false),
mIsMultiviewEnabled(extensions.multiview), mIsMultiviewEnabled(extensions.multiview),
mLocalDirtyBits(), mLocalDirtyBits(),
mMultiviewDirtyBits() mMultiviewDirtyBits(),
mProgramTexturesAndSamplersDirty(true)
{ {
ASSERT(mFunctions); ASSERT(mFunctions);
ASSERT(extensions.maxViews >= 1u); ASSERT(extensions.maxViews >= 1u);
...@@ -380,6 +381,7 @@ void StateManagerGL::forceUseProgram(GLuint program) ...@@ -380,6 +381,7 @@ void StateManagerGL::forceUseProgram(GLuint program)
{ {
mProgram = program; mProgram = program;
mFunctions->useProgram(mProgram); mFunctions->useProgram(mProgram);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_PROGRAM_BINDING);
} }
void StateManagerGL::bindVertexArray(GLuint vao, GLuint elementArrayBuffer) void StateManagerGL::bindVertexArray(GLuint vao, GLuint elementArrayBuffer)
...@@ -447,6 +449,7 @@ void StateManagerGL::bindTexture(GLenum type, GLuint texture) ...@@ -447,6 +449,7 @@ void StateManagerGL::bindTexture(GLenum type, GLuint texture)
{ {
mTextures[type][mTextureUnitIndex] = texture; mTextures[type][mTextureUnitIndex] = texture;
mFunctions->bindTexture(type, texture); mFunctions->bindTexture(type, texture);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
} }
} }
...@@ -456,6 +459,7 @@ void StateManagerGL::bindSampler(size_t unit, GLuint sampler) ...@@ -456,6 +459,7 @@ void StateManagerGL::bindSampler(size_t unit, GLuint sampler)
{ {
mSamplers[unit] = sampler; mSamplers[unit] = sampler;
mFunctions->bindSampler(static_cast<GLuint>(unit), sampler); mFunctions->bindSampler(static_cast<GLuint>(unit), sampler);
mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLER_BINDINGS);
} }
} }
...@@ -871,50 +875,10 @@ void StateManagerGL::setGenericShaderState(const gl::Context *context) ...@@ -871,50 +875,10 @@ void StateManagerGL::setGenericShaderState(const gl::Context *context)
} }
} }
const auto &completeTextures = glState.getCompleteTextureCache(); if (mProgramTexturesAndSamplersDirty)
for (const gl::SamplerBinding &samplerBinding : program->getSamplerBindings())
{ {
if (samplerBinding.unreferenced) updateProgramTextureAndSamplerBindings(context);
continue; mProgramTexturesAndSamplersDirty = false;
GLenum textureType = samplerBinding.textureType;
for (GLuint textureUnitIndex : samplerBinding.boundTextureUnits)
{
gl::Texture *texture = completeTextures[textureUnitIndex];
// A nullptr texture indicates incomplete.
if (texture != nullptr)
{
const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
ASSERT(!texture->hasAnyDirtyBit());
ASSERT(!textureGL->hasAnyDirtyBit());
if (mTextures.at(textureType)[textureUnitIndex] != textureGL->getTextureID())
{
activeTexture(textureUnitIndex);
bindTexture(textureType, textureGL->getTextureID());
}
}
else
{
if (mTextures.at(textureType)[textureUnitIndex] != 0)
{
activeTexture(textureUnitIndex);
bindTexture(textureType, 0);
}
}
const gl::Sampler *sampler = glState.getSampler(textureUnitIndex);
if (sampler != nullptr)
{
SamplerGL *samplerGL = GetImplAs<SamplerGL>(sampler);
bindSampler(textureUnitIndex, samplerGL->getSamplerID());
}
else
{
bindSampler(textureUnitIndex, 0);
}
}
} }
// TODO(xinghua.cao@intel.com): Track image units state with dirty bits to // TODO(xinghua.cao@intel.com): Track image units state with dirty bits to
...@@ -962,6 +926,58 @@ void StateManagerGL::setGenericShaderState(const gl::Context *context) ...@@ -962,6 +926,58 @@ void StateManagerGL::setGenericShaderState(const gl::Context *context)
} }
} }
void StateManagerGL::updateProgramTextureAndSamplerBindings(const gl::Context *context)
{
const gl::State &glState = context->getGLState();
const gl::Program *program = glState.getProgram();
const auto &completeTextures = glState.getCompleteTextureCache();
for (const gl::SamplerBinding &samplerBinding : program->getSamplerBindings())
{
if (samplerBinding.unreferenced)
continue;
GLenum textureType = samplerBinding.textureType;
for (GLuint textureUnitIndex : samplerBinding.boundTextureUnits)
{
gl::Texture *texture = completeTextures[textureUnitIndex];
// A nullptr texture indicates incomplete.
if (texture != nullptr)
{
const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
ASSERT(!texture->hasAnyDirtyBit());
ASSERT(!textureGL->hasAnyDirtyBit());
if (mTextures.at(textureType)[textureUnitIndex] != textureGL->getTextureID())
{
activeTexture(textureUnitIndex);
bindTexture(textureType, textureGL->getTextureID());
}
}
else
{
if (mTextures.at(textureType)[textureUnitIndex] != 0)
{
activeTexture(textureUnitIndex);
bindTexture(textureType, 0);
}
}
const gl::Sampler *sampler = glState.getSampler(textureUnitIndex);
if (sampler != nullptr)
{
SamplerGL *samplerGL = GetImplAs<SamplerGL>(sampler);
bindSampler(textureUnitIndex, samplerGL->getSamplerID());
}
else
{
bindSampler(textureUnitIndex, 0);
}
}
}
}
gl::Error StateManagerGL::setGenericDrawState(const gl::Context *context) gl::Error StateManagerGL::setGenericDrawState(const gl::Context *context)
{ {
setGenericShaderState(context); setGenericShaderState(context);
...@@ -1901,15 +1917,16 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -1901,15 +1917,16 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt
// TODO: implement this // TODO: implement this
break; break;
case gl::State::DIRTY_BIT_PROGRAM_BINDING: case gl::State::DIRTY_BIT_PROGRAM_BINDING:
// TODO(jmadill): implement this mProgramTexturesAndSamplersDirty = true;
break; break;
case gl::State::DIRTY_BIT_TEXTURE_BINDINGS: case gl::State::DIRTY_BIT_TEXTURE_BINDINGS:
// TODO(jmadill): implement this mProgramTexturesAndSamplersDirty = true;
break; break;
case gl::State::DIRTY_BIT_SAMPLER_BINDINGS: case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
// TODO(jmadill): implement this mProgramTexturesAndSamplersDirty = true;
break; break;
case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE: case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
mProgramTexturesAndSamplersDirty = true;
propagateNumViewsToVAO(state.getProgram(), propagateNumViewsToVAO(state.getProgram(),
GetImplAs<VertexArrayGL>(state.getVertexArray())); GetImplAs<VertexArrayGL>(state.getVertexArray()));
updateMultiviewBaseViewLayerIndexUniform( updateMultiviewBaseViewLayerIndexUniform(
......
...@@ -200,6 +200,8 @@ class StateManagerGL final : angle::NonCopyable ...@@ -200,6 +200,8 @@ class StateManagerGL final : angle::NonCopyable
const gl::Framebuffer &drawFramebuffer); const gl::Framebuffer &drawFramebuffer);
void propagateNumViewsToVAO(const gl::Program *program, VertexArrayGL *vao); void propagateNumViewsToVAO(const gl::Program *program, VertexArrayGL *vao);
void updateProgramTextureAndSamplerBindings(const gl::Context *context);
enum MultiviewDirtyBitType enum MultiviewDirtyBitType
{ {
MULTIVIEW_DIRTY_BIT_SIDE_BY_SIDE_LAYOUT, MULTIVIEW_DIRTY_BIT_SIDE_BY_SIDE_LAYOUT,
...@@ -350,6 +352,8 @@ class StateManagerGL final : angle::NonCopyable ...@@ -350,6 +352,8 @@ class StateManagerGL final : angle::NonCopyable
// ANGLE_multiview dirty bits. // ANGLE_multiview dirty bits.
angle::BitSet<MULTIVIEW_DIRTY_BIT_MAX> mMultiviewDirtyBits; angle::BitSet<MULTIVIEW_DIRTY_BIT_MAX> mMultiviewDirtyBits;
bool mProgramTexturesAndSamplersDirty;
}; };
} }
......
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