Revert "Inline and micro-optimize more for perf tests."

This reverts commit 57ff6f95f143bd65a0c3d12d64773f274b9935f4.

Reason for revert: Memory leaks detected during roll in https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux_chromium_asan_rel_ng/100284

Original change's description:
> Inline and micro-optimize more for perf tests.
> 
> Using a custom array instead of std::vector speeds up the resource
> manager. One reason is because calls to size() are implemented in many
> implementations as a difference between two pointers. This sub size
> implementations are slower than storing a simple size variable in a
> custom class.
> 
> Also includes more inlining of hot spots functions.
> 
> Also includes a small unit test class for ResourceMap. And an unrelated
> but small test fix for TextureLimisTest. Also a small unrelated fix for
> a Transform Feedback test.
> 
> Increase the scores of the draw call perf test with texture and buffer
> bindings and the buffer binding perf test.
> 
> Bug: angleproject:2763
> Change-Id: I41c327987db27ac45e6a62579f01e1cdc22e396c
> Reviewed-on: https://chromium-review.googlesource.com/1171510
> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
> Reviewed-by: Jamie Madill <jmadill@chromium.org>
> Commit-Queue: Jamie Madill <jmadill@chromium.org>

TBR=fjhenigman@chromium.org,ynovikov@chromium.org,jmadill@chromium.org,syoussefi@chromium.org

Change-Id: Ie047289c9bf23a842c3cbb9692c811da0534991c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: angleproject:2763
Reviewed-on: https://chromium-review.googlesource.com/1228893
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
Commit-Queue: Yuly Novikov <ynovikov@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index f20d64e..dc6326a 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -972,6 +972,11 @@
     return mState.mBuffers->getBuffer(handle);
 }
 
+Texture *Context::getTexture(GLuint handle) const
+{
+    return mState.mTextures->getTexture(handle);
+}
+
 Renderbuffer *Context::getRenderbuffer(GLuint handle) const
 {
     return mState.mRenderbuffers->getRenderbuffer(handle);
diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h
index 304317f..bfaa81d 100644
--- a/src/libANGLE/Context.h
+++ b/src/libANGLE/Context.h
@@ -474,8 +474,7 @@
     Buffer *getBuffer(GLuint handle) const;
     FenceNV *getFenceNV(GLuint handle);
     Sync *getSync(GLsync handle) const;
-    Texture *getTexture(GLuint handle) const { return mState.mTextures->getTexture(handle); }
-
+    Texture *getTexture(GLuint handle) const;
     Framebuffer *getFramebuffer(GLuint handle) const;
     Renderbuffer *getRenderbuffer(GLuint handle) const;
     VertexArray *getVertexArray(GLuint handle) const;
diff --git a/src/libANGLE/ResourceManager.cpp b/src/libANGLE/ResourceManager.cpp
index 31c4f32..b81dc84 100644
--- a/src/libANGLE/ResourceManager.cpp
+++ b/src/libANGLE/ResourceManager.cpp
@@ -242,6 +242,12 @@
     return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
 }
 
+Texture *TextureManager::getTexture(GLuint handle) const
+{
+    ASSERT(mObjectMap.query(0) == nullptr);
+    return mObjectMap.query(handle);
+}
+
 void TextureManager::signalAllTexturesDirty(const Context *context) const
 {
     for (const auto &texture : mObjectMap)
diff --git a/src/libANGLE/ResourceManager.h b/src/libANGLE/ResourceManager.h
index d4deb57..828f3fb 100644
--- a/src/libANGLE/ResourceManager.h
+++ b/src/libANGLE/ResourceManager.h
@@ -166,11 +166,7 @@
 {
   public:
     GLuint createTexture();
-    Texture *getTexture(GLuint handle) const
-    {
-        ASSERT(mObjectMap.query(0) == nullptr);
-        return mObjectMap.query(handle);
-    }
+    Texture *getTexture(GLuint handle) const;
 
     void signalAllTexturesDirty(const Context *context) const;
 
diff --git a/src/libANGLE/ResourceMap.h b/src/libANGLE/ResourceMap.h
index 7cfb9bd..b00da68 100644
--- a/src/libANGLE/ResourceMap.h
+++ b/src/libANGLE/ResourceMap.h
@@ -23,16 +23,7 @@
     ResourceMap();
     ~ResourceMap();
 
-    ANGLE_INLINE ResourceType *query(GLuint handle) const
-    {
-        if (handle < mFlatResourcesSize)
-        {
-            ResourceType *value = mFlatResources[handle];
-            return (value == InvalidPointer() ? nullptr : value);
-        }
-        auto it = mHashedResources.find(handle);
-        return (it == mHashedResources.end() ? nullptr : it->second);
-    }
+    ResourceType *query(GLuint handle) const;
 
     // Returns true if the handle was reserved. Not necessarily if the resource is created.
     bool contains(GLuint handle) const;
@@ -93,11 +84,7 @@
     // Experimental testing suggests that 16k is a reasonable upper limit.
     static constexpr size_t kFlatResourcesLimit = 0x4000;
 
-    // Size of one map element.
-    static constexpr size_t kElementSize = sizeof(ResourceType *);
-
-    size_t mFlatResourcesSize;
-    ResourceType **mFlatResources;
+    std::vector<ResourceType *> mFlatResources;
 
     // A map of GL objects indexed by object ID.
     HashMap mHashedResources;
@@ -105,11 +92,8 @@
 
 template <typename ResourceType>
 ResourceMap<ResourceType>::ResourceMap()
-    : mFlatResourcesSize(kInitialFlatResourcesSize),
-      mFlatResources(new ResourceType *[kInitialFlatResourcesSize]),
-      mHashedResources()
+    : mFlatResources(kInitialFlatResourcesSize, InvalidPointer()), mHashedResources()
 {
-    memset(mFlatResources, kInvalidPointer, mFlatResourcesSize * kElementSize);
 }
 
 template <typename ResourceType>
@@ -119,9 +103,21 @@
 }
 
 template <typename ResourceType>
+ResourceType *ResourceMap<ResourceType>::query(GLuint handle) const
+{
+    if (handle < mFlatResources.size())
+    {
+        auto value = mFlatResources[handle];
+        return (value == InvalidPointer() ? nullptr : value);
+    }
+    auto it = mHashedResources.find(handle);
+    return (it == mHashedResources.end() ? nullptr : it->second);
+}
+
+template <typename ResourceType>
 bool ResourceMap<ResourceType>::contains(GLuint handle) const
 {
-    if (handle < mFlatResourcesSize)
+    if (handle < mFlatResources.size())
     {
         return (mFlatResources[handle] != InvalidPointer());
     }
@@ -131,7 +127,7 @@
 template <typename ResourceType>
 bool ResourceMap<ResourceType>::erase(GLuint handle, ResourceType **resourceOut)
 {
-    if (handle < mFlatResourcesSize)
+    if (handle < mFlatResources.size())
     {
         auto &value = mFlatResources[handle];
         if (value == InvalidPointer())
@@ -159,25 +155,17 @@
 {
     if (handle < kFlatResourcesLimit)
     {
-        if (handle >= mFlatResourcesSize)
+        if (handle >= mFlatResources.size())
         {
             // Use power-of-two.
-            size_t newSize = mFlatResourcesSize;
+            size_t newSize = mFlatResources.size();
             while (newSize <= handle)
             {
                 newSize *= 2;
             }
-
-            ResourceType **oldResources = mFlatResources;
-
-            mFlatResources = new ResourceType *[newSize];
-            memset(&mFlatResources[mFlatResourcesSize], kInvalidPointer,
-                   (newSize - mFlatResourcesSize) * kElementSize);
-            memcpy(mFlatResources, oldResources, mFlatResourcesSize * kElementSize);
-            mFlatResourcesSize = newSize;
-            delete[] oldResources;
+            mFlatResources.resize(newSize, nullptr);
         }
-        ASSERT(mFlatResourcesSize > handle);
+        ASSERT(mFlatResources.size() > handle);
         mFlatResources[handle] = resource;
     }
     else
@@ -195,13 +183,13 @@
 template <typename ResourceType>
 typename ResourceMap<ResourceType>::Iterator ResourceMap<ResourceType>::end() const
 {
-    return Iterator(*this, static_cast<GLuint>(mFlatResourcesSize), mHashedResources.end());
+    return Iterator(*this, static_cast<GLuint>(mFlatResources.size()), mHashedResources.end());
 }
 
 template <typename ResourceType>
 typename ResourceMap<ResourceType>::Iterator ResourceMap<ResourceType>::find(GLuint handle) const
 {
-    if (handle < mFlatResourcesSize)
+    if (handle < mFlatResources.size())
     {
         return (mFlatResources[handle] != InvalidPointer()
                     ? Iterator(handle, mHashedResources.begin())
@@ -222,22 +210,21 @@
 template <typename ResourceType>
 void ResourceMap<ResourceType>::clear()
 {
-    memset(mFlatResources, kInvalidPointer, kInitialFlatResourcesSize * kElementSize);
-    mFlatResourcesSize = kInitialFlatResourcesSize;
+    mFlatResources.assign(kInitialFlatResourcesSize, InvalidPointer());
     mHashedResources.clear();
 }
 
 template <typename ResourceType>
 GLuint ResourceMap<ResourceType>::nextNonNullResource(size_t flatIndex) const
 {
-    for (size_t index = flatIndex; index < mFlatResourcesSize; index++)
+    for (size_t index = flatIndex; index < mFlatResources.size(); index++)
     {
         if (mFlatResources[index] != nullptr && mFlatResources[index] != InvalidPointer())
         {
             return static_cast<GLuint>(index);
         }
     }
-    return static_cast<GLuint>(mFlatResourcesSize);
+    return static_cast<GLuint>(mFlatResources.size());
 }
 
 template <typename ResourceType>
@@ -272,7 +259,7 @@
 template <typename ResourceType>
 typename ResourceMap<ResourceType>::Iterator &ResourceMap<ResourceType>::Iterator::operator++()
 {
-    if (mFlatIndex < static_cast<GLuint>(mOrigin.mFlatResourcesSize))
+    if (mFlatIndex < static_cast<GLuint>(mOrigin.mFlatResources.size()))
     {
         mFlatIndex = mOrigin.nextNonNullResource(mFlatIndex + 1);
     }
@@ -301,7 +288,7 @@
 template <typename ResourceType>
 void ResourceMap<ResourceType>::Iterator::updateValue()
 {
-    if (mFlatIndex < static_cast<GLuint>(mOrigin.mFlatResourcesSize))
+    if (mFlatIndex < static_cast<GLuint>(mOrigin.mFlatResources.size()))
     {
         mValue.first  = mFlatIndex;
         mValue.second = mOrigin.mFlatResources[mFlatIndex];
diff --git a/src/libANGLE/ResourceMap_unittest.cpp b/src/libANGLE/ResourceMap_unittest.cpp
deleted file mode 100644
index fd9d3e9..0000000
--- a/src/libANGLE/ResourceMap_unittest.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-//
-// Copyright 2018 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// ResourceMap_unittest:
-//   Unit tests for the ResourceMap template class.
-//
-
-#include <gtest/gtest.h>
-
-#include "libANGLE/ResourceMap.h"
-
-using namespace gl;
-
-namespace
-{
-// Tests assigning slots in the map and then deleting elements.
-TEST(ResourceMapTest, AssignAndErase)
-{
-    constexpr size_t kSize = 64;
-    ResourceMap<size_t> resourceMap;
-    std::vector<size_t> objects(kSize, 1);
-    for (size_t index = 0; index < kSize; ++index)
-    {
-        resourceMap.assign(index + 1, &objects[index]);
-    }
-
-    for (size_t index = 0; index < kSize; ++index)
-    {
-        size_t *found = nullptr;
-        ASSERT_TRUE(resourceMap.erase(index + 1, &found));
-        ASSERT_EQ(&objects[index], found);
-    }
-
-    ASSERT_TRUE(resourceMap.empty());
-}
-
-// Tests assigning slots in the map and then using clear() to free it.
-TEST(ResourceMapTest, AssignAndClear)
-{
-    constexpr size_t kSize = 64;
-    ResourceMap<size_t> resourceMap;
-    std::vector<size_t> objects(kSize, 1);
-    for (size_t index = 0; index < kSize; ++index)
-    {
-        resourceMap.assign(index + 1, &objects[index]);
-    }
-
-    resourceMap.clear();
-    ASSERT_TRUE(resourceMap.empty());
-}
-
-// Tests growing a map more than double the size.
-TEST(ResourceMapTest, BigGrowth)
-{
-    constexpr size_t kSize = 8;
-
-    ResourceMap<size_t> resourceMap;
-    std::vector<size_t> objects;
-
-    for (size_t index = 0; index < kSize; ++index)
-    {
-        objects.push_back(index);
-    }
-
-    // Assign a large value.
-    constexpr size_t kLargeIndex = 128;
-    objects.push_back(kLargeIndex);
-
-    for (size_t &object : objects)
-    {
-        resourceMap.assign(object, &object);
-    }
-
-    for (size_t object : objects)
-    {
-        size_t *found = nullptr;
-        ASSERT_TRUE(resourceMap.erase(object, &found));
-        ASSERT_EQ(object, *found);
-    }
-
-    ASSERT_TRUE(resourceMap.empty());
-}
-
-// Tests querying unassigned or erased values.
-TEST(ResourceMapTest, QueryUnassigned)
-{
-    constexpr size_t kSize = 8;
-
-    ResourceMap<size_t> resourceMap;
-    std::vector<size_t> objects;
-
-    for (size_t index = 0; index < kSize; ++index)
-    {
-        objects.push_back(index);
-    }
-
-    ASSERT_FALSE(resourceMap.contains(0));
-    ASSERT_EQ(nullptr, resourceMap.query(0));
-    ASSERT_FALSE(resourceMap.contains(100));
-    ASSERT_EQ(nullptr, resourceMap.query(100));
-
-    for (size_t &object : objects)
-    {
-        resourceMap.assign(object, &object);
-    }
-
-    ASSERT_FALSE(resourceMap.empty());
-
-    for (size_t &object : objects)
-    {
-        ASSERT_TRUE(resourceMap.contains(object));
-        ASSERT_EQ(&object, resourceMap.query(object));
-    }
-
-    ASSERT_FALSE(resourceMap.contains(10));
-    ASSERT_EQ(nullptr, resourceMap.query(10));
-    ASSERT_FALSE(resourceMap.contains(100));
-    ASSERT_EQ(nullptr, resourceMap.query(100));
-
-    for (size_t object : objects)
-    {
-        size_t *found = nullptr;
-        ASSERT_TRUE(resourceMap.erase(object, &found));
-        ASSERT_EQ(object, *found);
-    }
-
-    ASSERT_TRUE(resourceMap.empty());
-
-    ASSERT_FALSE(resourceMap.contains(0));
-    ASSERT_EQ(nullptr, resourceMap.query(0));
-    ASSERT_FALSE(resourceMap.contains(100));
-    ASSERT_EQ(nullptr, resourceMap.query(100));
-}
-}  // anonymous namespace
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 2a5b8f0..7a78ae4 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -1033,6 +1033,12 @@
     return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), type);
 }
 
+Texture *State::getSamplerTexture(unsigned int sampler, TextureType type) const
+{
+    ASSERT(sampler < mSamplerTextures[type].size());
+    return mSamplerTextures[type][sampler].get();
+}
+
 GLuint State::getSamplerTextureId(unsigned int sampler, TextureType type) const
 {
     ASSERT(sampler < mSamplerTextures[type].size());
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index 84446ec..4d1f0e6 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -162,7 +162,10 @@
     void setFragmentShaderDerivativeHint(GLenum hint);
 
     // GL_CHROMIUM_bind_generates_resource
-    bool isBindGeneratesResourceEnabled() const { return mBindGeneratesResource; }
+    bool isBindGeneratesResourceEnabled() const
+    {
+        return mBindGeneratesResource;
+    }
 
     // GL_ANGLE_client_arrays
     bool areClientArraysEnabled() const;
@@ -176,13 +179,7 @@
     unsigned int getActiveSampler() const;
     void setSamplerTexture(const Context *context, TextureType type, Texture *texture);
     Texture *getTargetTexture(TextureType type) const;
-
-    Texture *getSamplerTexture(unsigned int sampler, TextureType type) const
-    {
-        ASSERT(sampler < mSamplerTextures[type].size());
-        return mSamplerTextures[type][sampler].get();
-    }
-
+    Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
     GLuint getSamplerTextureId(unsigned int sampler, TextureType type) const;
     void detachTexture(const Context *context, const TextureMap &zeroTextures, GLuint texture);
     void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures);
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index cfc22cf..62be3fb 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -979,7 +979,7 @@
                                     gl::Texture *texture)
 {
     int d3dSamplerOffset = (type == gl::ShaderType::Fragment) ? 0 : D3DVERTEXTEXTURESAMPLER0;
-    int d3dSampler                    = index + d3dSamplerOffset;
+    int d3dSampler       = index + d3dSamplerOffset;
     IDirect3DBaseTexture9 *d3dTexture = nullptr;
     bool forceSetTexture              = false;
 
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index 30b8251..5a1521e 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -2981,6 +2981,20 @@
 
 bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
 {
+    Texture *textureObject = context->getTexture(texture);
+    if (textureObject && textureObject->getType() != target && texture != 0)
+    {
+        ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
+        return false;
+    }
+
+    if (!context->getGLState().isBindGeneratesResourceEnabled() &&
+        !context->isTextureGenerated(texture))
+    {
+        context->handleError(InvalidOperation() << "Texture was not generated");
+        return false;
+    }
+
     switch (target)
     {
         case TextureType::_2D:
@@ -3032,25 +3046,6 @@
             return false;
     }
 
-    if (texture == 0)
-    {
-        return true;
-    }
-
-    Texture *textureObject = context->getTexture(texture);
-    if (textureObject && textureObject->getType() != target)
-    {
-        ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
-        return false;
-    }
-
-    if (!context->getGLState().isBindGeneratesResourceEnabled() &&
-        !context->isTextureGenerated(texture))
-    {
-        context->handleError(InvalidOperation() << "Texture was not generated");
-        return false;
-    }
-
     return true;
 }
 
diff --git a/src/tests/angle_unittests.gni b/src/tests/angle_unittests.gni
index f475ae1..b39b5a5 100644
--- a/src/tests/angle_unittests.gni
+++ b/src/tests/angle_unittests.gni
@@ -25,7 +25,6 @@
   "../libANGLE/Observer_unittest.cpp",
   "../libANGLE/Program_unittest.cpp",
   "../libANGLE/ResourceManager_unittest.cpp",
-  "../libANGLE/ResourceMap_unittest.cpp",
   "../libANGLE/SizedMRUCache_unittest.cpp",
   "../libANGLE/Surface_unittest.cpp",
   "../libANGLE/TransformFeedback_unittest.cpp",
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
index d05ad9e..4f1cf76 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -2774,18 +2774,7 @@
         setConfigAlphaBits(8);
     }
 
-    void SetUp() override
-    {
-        ANGLETest::SetUp();
-
-        glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
-        glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
-        glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
-
-        ASSERT_GL_NO_ERROR();
-    }
-
-    void TearDown() override
+    ~TextureLimitsTest()
     {
         if (mProgram != 0)
         {
@@ -2797,8 +2786,17 @@
                 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
             }
         }
+    }
 
-        ANGLETest::TearDown();
+    void SetUp() override
+    {
+        ANGLETest::SetUp();
+
+        glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
+        glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
+        glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
+
+        ASSERT_GL_NO_ERROR();
     }
 
     void compileProgramWithTextureCounts(const std::string &vertexPrefix,
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index ae790c7..21c517b 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -3232,12 +3232,12 @@
     // Create textures and allocate storage
     GLTexture tex0;
     GLTexture tex1;
-    GLTexture tex2;
+    GLRenderbuffer rb;
     FillTexture2D(tex0.get(), width, height, GLColor::black, 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
     FillTexture2D(tex1.get(), width, height, 0x80, 0, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT,
                   GL_UNSIGNED_INT);
-    FillTexture2D(tex2.get(), width, height, 0x40, 0, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL,
-                  GL_UNSIGNED_INT_24_8);
+    glBindRenderbuffer(GL_RENDERBUFFER, rb.get());
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
     ASSERT_GL_NO_ERROR();
 
     GLFramebuffer fbo;
@@ -3252,7 +3252,7 @@
     // The same image is used as depth buffer during rendering.
     glEnable(GL_DEPTH_TEST);
     drawQuad(program.get(), "aPosition", 0.5f, 1.0f, true);
-    EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Same image as depth buffer should fail";
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     // The same image is used as depth buffer. But depth mask is false.
     glDepthMask(GL_FALSE);
@@ -3266,9 +3266,9 @@
     EXPECT_GL_NO_ERROR();
 
     // Test rendering and sampling feedback loop for stencil buffer
-    glBindTexture(GL_TEXTURE_2D, tex2.get());
+    glBindTexture(GL_RENDERBUFFER, rb.get());
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
-    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex2.get(), 0);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb.get());
     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
     constexpr GLint stencilClearValue = 0x40;
     glClearBufferiv(GL_STENCIL, 0, &stencilClearValue);
@@ -3276,7 +3276,7 @@
     // The same image is used as stencil buffer during rendering.
     glEnable(GL_STENCIL_TEST);
     drawQuad(program.get(), "aPosition", 0.5f, 1.0f, true);
-    EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Same image as stencil buffer should fail";
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 
     // The same image is used as stencil buffer. But stencil mask is zero.
     glStencilMask(0x0);