Commit 9cce3cd9 by Jamie Madill Committed by Commit Bot

Update texure cache after teleting bound texture.

The texture cache could become out of sync. And we could end up dereferencing an invalid pointer. Bug: chromium:943538 Change-Id: I6a99a04e80fc551b6177e25b7bee09c6ae226340 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1541718Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 3f7ace32
......@@ -538,10 +538,19 @@ ANGLE_INLINE void State::updateActiveTextureState(const Context *context,
}
}
mTexturesIncompatibleWithSamplers[textureIndex] =
!texture->getTextureState().compatibleWithSamplerFormat(
mProgram->getState().getSamplerFormatForTextureUnitIndex(textureIndex),
sampler ? sampler->getSamplerState() : texture->getSamplerState());
if (mProgram)
{
const SamplerState &samplerState =
sampler ? sampler->getSamplerState() : texture->getSamplerState();
mTexturesIncompatibleWithSamplers[textureIndex] =
!texture->getTextureState().compatibleWithSamplerFormat(
mProgram->getState().getSamplerFormatForTextureUnitIndex(textureIndex),
samplerState);
}
else
{
mTexturesIncompatibleWithSamplers[textureIndex] = false;
}
mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
}
......@@ -1124,15 +1133,17 @@ void State::detachTexture(const Context *context, const TextureMap &zeroTextures
for (TextureType type : angle::AllEnums<TextureType>())
{
TextureBindingVector &textureVector = mSamplerTextures[type];
for (BindingPointer<Texture> &binding : textureVector)
for (size_t bindingIndex = 0; bindingIndex < textureVector.size(); ++bindingIndex)
{
BindingPointer<Texture> &binding = textureVector[bindingIndex];
if (binding.id() == texture)
{
// Zero textures are the "default" textures instead of NULL
Texture *zeroTexture = zeroTextures[type].get();
ASSERT(zeroTexture != nullptr);
// Zero textures are the "default" textures instead of NULL
binding.set(context, zeroTexture);
mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
updateActiveTexture(context, bindingIndex, zeroTexture);
}
}
}
......
......@@ -3367,6 +3367,42 @@ TEST_P(ValidationStateChangeTest, MapElementArrayBuffer)
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}
// Tests that deleting a texture successfully binds the zero texture.
TEST_P(SimpleStateChangeTest, DeleteTextureThenDraw)
{
constexpr char kFS[] =
"uniform sampler2D us; void main() { gl_FragColor = texture2D(us, vec2(0)); }";
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFS);
glUseProgram(program);
GLint loc = glGetUniformLocation(program, "us");
ASSERT_EQ(0, loc);
auto quadVertices = GetQuadVertices();
GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
ASSERT_EQ(0, posLoc);
GLBuffer buffer;
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(quadVertices[0]),
quadVertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(posLoc);
constexpr size_t kSize = 2;
std::vector<GLColor> red(kSize * kSize, GLColor::red);
GLTexture tex;
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, red.data());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glUniform1i(loc, 1);
tex.reset();
glDrawArrays(GL_TRIANGLES, 0, 3);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
}
} // anonymous namespace
ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN());
......
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