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);