зеркало из https://github.com/AvaloniaUI/angle.git
Move out of bounds buffer access tests under correct extension
A few tests in RobustResourceInitTest are testing for out of bounds values but RobustResourceInitTest is only checking GL_ANGLE_robust_resource_initialization which does not do anything for out of bounds access. I moved them to the RobustBufferAccessBehaviorTest. Bug: angleproject:7638 Change-Id: If542ce2f1711e4b1980bf52cabfa3cff71480536 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3880833 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Gregg Tavares <gman@chromium.org>
This commit is contained in:
Родитель
526e8e6476
Коммит
61e905afea
|
@ -680,6 +680,256 @@ void main(void) {
|
|||
// No assertions, just checking for crashes.
|
||||
}
|
||||
|
||||
// Draw out-of-bounds beginning with the start offset passed in.
|
||||
// Ensure that drawArrays flags either no error or INVALID_OPERATION. In the case of
|
||||
// INVALID_OPERATION, no canvas pixels can be touched. In the case of NO_ERROR, all written values
|
||||
// must either be the zero vertex or a value in the vertex buffer. See vsCheckOutOfBounds shader.
|
||||
void DrawAndVerifyOutOfBoundsArrays(int first, int count)
|
||||
{
|
||||
glClearColor(0.0, 0.0, 1.0, 1.0); // Start with blue to indicate no pixels touched.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, first, count);
|
||||
GLenum error = glGetError();
|
||||
if (error == GL_INVALID_OPERATION)
|
||||
{
|
||||
// testPassed. drawArrays flagged INVALID_OPERATION, which is valid so long as all canvas
|
||||
// pixels were not touched.
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_GL_NO_ERROR();
|
||||
// testPassed. drawArrays flagged NO_ERROR, which is valid so long as all canvas pixels are
|
||||
// green.
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from WebGL test
|
||||
// conformance/rendering/out-of-bounds-array-buffers.html
|
||||
// This test verifies that out-of-bounds array buffers behave according to spec.
|
||||
TEST_P(RobustBufferAccessBehaviorTest, OutOfBoundsArrayBuffers)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!initExtension());
|
||||
|
||||
constexpr char vsCheckOutOfBounds[] =
|
||||
"precision mediump float;\n"
|
||||
"attribute vec2 position;\n"
|
||||
"attribute vec4 vecRandom;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"\n"
|
||||
"// Per the spec, each component can either contain existing contents\n"
|
||||
"// of the buffer or 0.\n"
|
||||
"bool testFloatComponent(float component) {\n"
|
||||
" return (component == 0.2 || component == 0.0);\n"
|
||||
"}\n"
|
||||
"" // The last component is additionally allowed to be 1.0.\n"
|
||||
"bool testLastFloatComponent(float component) {\n"
|
||||
" return testFloatComponent(component) || component == 1.0;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main() {\n"
|
||||
" if (testFloatComponent(vecRandom.x) &&\n"
|
||||
" testFloatComponent(vecRandom.y) &&\n"
|
||||
" testFloatComponent(vecRandom.z) &&\n"
|
||||
" testLastFloatComponent(vecRandom.w)) {\n"
|
||||
" v_color = vec4(0.0, 1.0, 0.0, 1.0); // green -- We're good\n"
|
||||
" } else {\n"
|
||||
" v_color = vec4(1.0, 0.0, 0.0, 1.0); // red -- Unexpected value\n"
|
||||
" }\n"
|
||||
" gl_Position = vec4(position, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
constexpr char simpleVertexColorFragmentShader[] =
|
||||
"precision mediump float;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = v_color;\n"
|
||||
"}";
|
||||
|
||||
// Setup the verification program.
|
||||
ANGLE_GL_PROGRAM(program, vsCheckOutOfBounds, simpleVertexColorFragmentShader);
|
||||
glUseProgram(program);
|
||||
|
||||
GLint kPosLoc = glGetAttribLocation(program, "position");
|
||||
ASSERT_NE(kPosLoc, -1);
|
||||
GLint kRandomLoc = glGetAttribLocation(program, "vecRandom");
|
||||
ASSERT_NE(kRandomLoc, -1);
|
||||
|
||||
// Create a buffer of 200 valid sets of quad lists.
|
||||
constexpr size_t numberOfQuads = 200;
|
||||
// Create a vertex buffer with 200 properly formed triangle quads. These quads will cover the
|
||||
// canvas texture such that every single pixel is touched by the fragment shader.
|
||||
GLBuffer glQuadBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, glQuadBuffer);
|
||||
std::array<float, numberOfQuads * 2 * 6> quadPositions;
|
||||
for (unsigned int i = 0; i < quadPositions.size(); i += 2 * 6)
|
||||
{
|
||||
quadPositions[i + 0] = -1.0; // upper left
|
||||
quadPositions[i + 1] = 1.0;
|
||||
quadPositions[i + 2] = 1.0; // upper right
|
||||
quadPositions[i + 3] = 1.0;
|
||||
quadPositions[i + 4] = -1.0; // lower left
|
||||
quadPositions[i + 5] = -1.0;
|
||||
quadPositions[i + 6] = 1.0; // upper right
|
||||
quadPositions[i + 7] = 1.0;
|
||||
quadPositions[i + 8] = 1.0; // lower right
|
||||
quadPositions[i + 9] = -1.0;
|
||||
quadPositions[i + 10] = -1.0; // lower left
|
||||
quadPositions[i + 11] = -1.0;
|
||||
}
|
||||
glBufferData(GL_ARRAY_BUFFER, quadPositions.size() * sizeof(float), quadPositions.data(),
|
||||
GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(kPosLoc);
|
||||
glVertexAttribPointer(kPosLoc, 2, GL_FLOAT, false, 0, 0);
|
||||
|
||||
// Create a small vertex buffer with determined-ahead-of-time "random" values (0.2). This buffer
|
||||
// will be the one read past the end.
|
||||
GLBuffer glVertexBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, glVertexBuffer);
|
||||
std::array<float, 6> vertexData = {0.2, 0.2, 0.2, 0.2, 0.2, 0.2};
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(float), vertexData.data(),
|
||||
GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(kRandomLoc);
|
||||
glVertexAttribPointer(kRandomLoc, 4, GL_FLOAT, false, 0, 0);
|
||||
|
||||
// Test -- Draw off the end of the vertex buffer near the beginning of the out of bounds area.
|
||||
DrawAndVerifyOutOfBoundsArrays(/*first*/ 6, /*count*/ 6);
|
||||
|
||||
// Test -- Draw off the end of the vertex buffer near the end of the out of bounds area.
|
||||
DrawAndVerifyOutOfBoundsArrays(/*first*/ (numberOfQuads - 1) * 6, /*count*/ 6);
|
||||
}
|
||||
|
||||
// Prepare an element array buffer that indexes out-of-bounds beginning with the start index passed
|
||||
// in. Ensure that drawElements flags either no error or INVALID_OPERATION. In the case of
|
||||
// INVALID_OPERATION, no canvas pixels can be touched. In the case of NO_ERROR, all written values
|
||||
// must either be the zero vertex or a value in the vertex buffer. See vsCheckOutOfBounds shader.
|
||||
void DrawAndVerifyOutOfBoundsIndex(int startIndex)
|
||||
{
|
||||
glClearColor(0.0, 0.0, 1.0, 1.0); // Start with blue to indicate no pixels touched.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Create an element array buffer with a tri-strip that starts at startIndex and make
|
||||
// it the active element array buffer.
|
||||
GLBuffer glElementArrayBuffer;
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glElementArrayBuffer);
|
||||
std::array<uint16_t, 4> quadIndices;
|
||||
for (unsigned int i = 0; i < quadIndices.size(); i++)
|
||||
{
|
||||
quadIndices[i] = startIndex + i;
|
||||
}
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, quadIndices.size() * sizeof(uint16_t), quadIndices.data(),
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, /*offset*/ 0);
|
||||
GLenum error = glGetError();
|
||||
if (error == GL_INVALID_OPERATION)
|
||||
{
|
||||
// testPassed. drawElements flagged INVALID_OPERATION, which is valid so long as all canvas
|
||||
// pixels were not touched.
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_GL_NO_ERROR();
|
||||
// testPassed. drawElements flagged NO_ERROR, which is valid so long as all canvas pixels
|
||||
// are green.
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from WebGL test
|
||||
// conformance/rendering/out-of-bounds-index-buffers.html
|
||||
// This test verifies that out-of-bounds index buffers behave according to spec.
|
||||
TEST_P(RobustBufferAccessBehaviorTest, OutOfBoundsIndexBuffers)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!initExtension());
|
||||
|
||||
constexpr char vsCheckOutOfBounds[] =
|
||||
"precision mediump float;\n"
|
||||
"attribute vec2 position;\n"
|
||||
"attribute vec4 vecRandom;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"\n"
|
||||
"// Per the spec, each component can either contain existing contents\n"
|
||||
"// of the buffer or 0.\n"
|
||||
"bool testFloatComponent(float component) {\n"
|
||||
" return (component == 0.2 || component == 0.0);\n"
|
||||
"}\n"
|
||||
"" // The last component is additionally allowed to be 1.0.\n"
|
||||
"bool testLastFloatComponent(float component) {\n"
|
||||
" return testFloatComponent(component) || component == 1.0;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main() {\n"
|
||||
" if (testFloatComponent(vecRandom.x) &&\n"
|
||||
" testFloatComponent(vecRandom.y) &&\n"
|
||||
" testFloatComponent(vecRandom.z) &&\n"
|
||||
" testLastFloatComponent(vecRandom.w)) {\n"
|
||||
" v_color = vec4(0.0, 1.0, 0.0, 1.0); // green -- We're good\n"
|
||||
" } else {\n"
|
||||
" v_color = vec4(1.0, 0.0, 0.0, 1.0); // red -- Unexpected value\n"
|
||||
" }\n"
|
||||
" gl_Position = vec4(position, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
constexpr char simpleVertexColorFragmentShader[] =
|
||||
"precision mediump float;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = v_color;\n"
|
||||
"}";
|
||||
|
||||
// Setup the verification program.
|
||||
ANGLE_GL_PROGRAM(program, vsCheckOutOfBounds, simpleVertexColorFragmentShader);
|
||||
glUseProgram(program);
|
||||
|
||||
GLint kPosLoc = glGetAttribLocation(program, "position");
|
||||
ASSERT_NE(kPosLoc, -1);
|
||||
GLint kRandomLoc = glGetAttribLocation(program, "vecRandom");
|
||||
ASSERT_NE(kRandomLoc, -1);
|
||||
|
||||
// Create a buffer of 200 valid sets of quad lists.
|
||||
constexpr size_t numberOfQuads = 200;
|
||||
// Create a vertex buffer with 200 properly formed tri-strip quads. These quads will cover the
|
||||
// canvas texture such that every single pixel is touched by the fragment shader.
|
||||
GLBuffer glQuadBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, glQuadBuffer);
|
||||
std::array<float, numberOfQuads * 2 * 4> quadPositions;
|
||||
for (unsigned int i = 0; i < quadPositions.size(); i += 2 * 4)
|
||||
{
|
||||
quadPositions[i + 0] = -1.0; // upper left
|
||||
quadPositions[i + 1] = 1.0;
|
||||
quadPositions[i + 2] = 1.0; // upper right
|
||||
quadPositions[i + 3] = 1.0;
|
||||
quadPositions[i + 4] = -1.0; // lower left
|
||||
quadPositions[i + 5] = -1.0;
|
||||
quadPositions[i + 6] = 1.0; // lower right
|
||||
quadPositions[i + 7] = -1.0;
|
||||
}
|
||||
glBufferData(GL_ARRAY_BUFFER, quadPositions.size() * sizeof(float), quadPositions.data(),
|
||||
GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(kPosLoc);
|
||||
glVertexAttribPointer(kPosLoc, 2, GL_FLOAT, false, 0, 0);
|
||||
|
||||
// Create a small vertex buffer with determined-ahead-of-time "random" values (0.2). This buffer
|
||||
// will be the one indexed off the end.
|
||||
GLBuffer glVertexBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, glVertexBuffer);
|
||||
std::array<float, 4> vertexData = {0.2, 0.2, 0.2, 0.2};
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(float), vertexData.data(),
|
||||
GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(kRandomLoc);
|
||||
glVertexAttribPointer(kRandomLoc, 4, GL_FLOAT, false, 0, 0);
|
||||
|
||||
// Test -- Index off the end of the vertex buffer near the beginning of the out of bounds area.
|
||||
DrawAndVerifyOutOfBoundsIndex(/*StartIndex*/ 4);
|
||||
|
||||
// Test -- Index off the end of the vertex buffer near the end of the out of bounds area.
|
||||
DrawAndVerifyOutOfBoundsIndex(/*StartIndex*/ numberOfQuads - 4);
|
||||
}
|
||||
|
||||
ANGLE_INSTANTIATE_TEST(RobustBufferAccessBehaviorTest,
|
||||
WithNoFixture(ES3_VULKAN()),
|
||||
WithNoFixture(ES3_OPENGL()),
|
||||
|
|
|
@ -426,256 +426,6 @@ TEST_P(RobustResourceInitTest, BufferDataZeroSize)
|
|||
glBufferData(GL_ARRAY_BUFFER, 0, nullptr, GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
// Draw out-of-bounds beginning with the start offset passed in.
|
||||
// Ensure that drawArrays flags either no error or INVALID_OPERATION. In the case of
|
||||
// INVALID_OPERATION, no canvas pixels can be touched. In the case of NO_ERROR, all written values
|
||||
// must either be the zero vertex or a value in the vertex buffer. See vsCheckOutOfBounds shader.
|
||||
void DrawAndVerifyOutOfBoundsArrays(int first, int count)
|
||||
{
|
||||
glClearColor(0.0, 0.0, 1.0, 1.0); // Start with blue to indicate no pixels touched.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, first, count);
|
||||
GLenum error = glGetError();
|
||||
if (error == GL_INVALID_OPERATION)
|
||||
{
|
||||
// testPassed. drawArrays flagged INVALID_OPERATION, which is valid so long as all canvas
|
||||
// pixels were not touched.
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_GL_NO_ERROR();
|
||||
// testPassed. drawArrays flagged NO_ERROR, which is valid so long as all canvas pixels are
|
||||
// green.
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from WebGL test
|
||||
// conformance/rendering/out-of-bounds-array-buffers.html
|
||||
// This test verifies that out-of-bounds array buffers behave according to spec.
|
||||
TEST_P(RobustResourceInitTest, OutOfBoundsArrayBuffers)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!hasGLExtension());
|
||||
|
||||
constexpr char vsCheckOutOfBounds[] =
|
||||
"precision mediump float;\n"
|
||||
"attribute vec2 position;\n"
|
||||
"attribute vec4 vecRandom;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"\n"
|
||||
"// Per the spec, each component can either contain existing contents\n"
|
||||
"// of the buffer or 0.\n"
|
||||
"bool testFloatComponent(float component) {\n"
|
||||
" return (component == 0.2 || component == 0.0);\n"
|
||||
"}\n"
|
||||
"" // The last component is additionally allowed to be 1.0.\n"
|
||||
"bool testLastFloatComponent(float component) {\n"
|
||||
" return testFloatComponent(component) || component == 1.0;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main() {\n"
|
||||
" if (testFloatComponent(vecRandom.x) &&\n"
|
||||
" testFloatComponent(vecRandom.y) &&\n"
|
||||
" testFloatComponent(vecRandom.z) &&\n"
|
||||
" testLastFloatComponent(vecRandom.w)) {\n"
|
||||
" v_color = vec4(0.0, 1.0, 0.0, 1.0); // green -- We're good\n"
|
||||
" } else {\n"
|
||||
" v_color = vec4(1.0, 0.0, 0.0, 1.0); // red -- Unexpected value\n"
|
||||
" }\n"
|
||||
" gl_Position = vec4(position, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
constexpr char simpleVertexColorFragmentShader[] =
|
||||
"precision mediump float;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = v_color;\n"
|
||||
"}";
|
||||
|
||||
// Setup the verification program.
|
||||
ANGLE_GL_PROGRAM(program, vsCheckOutOfBounds, simpleVertexColorFragmentShader);
|
||||
glUseProgram(program);
|
||||
|
||||
GLint kPosLoc = glGetAttribLocation(program, "position");
|
||||
ASSERT_NE(kPosLoc, -1);
|
||||
GLint kRandomLoc = glGetAttribLocation(program, "vecRandom");
|
||||
ASSERT_NE(kRandomLoc, -1);
|
||||
|
||||
// Create a buffer of 200 valid sets of quad lists.
|
||||
constexpr size_t numberOfQuads = 200;
|
||||
// Create a vertex buffer with 200 properly formed triangle quads. These quads will cover the
|
||||
// canvas texture such that every single pixel is touched by the fragment shader.
|
||||
GLBuffer glQuadBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, glQuadBuffer);
|
||||
std::array<float, numberOfQuads * 2 * 6> quadPositions;
|
||||
for (unsigned int i = 0; i < quadPositions.size(); i += 2 * 6)
|
||||
{
|
||||
quadPositions[i + 0] = -1.0; // upper left
|
||||
quadPositions[i + 1] = 1.0;
|
||||
quadPositions[i + 2] = 1.0; // upper right
|
||||
quadPositions[i + 3] = 1.0;
|
||||
quadPositions[i + 4] = -1.0; // lower left
|
||||
quadPositions[i + 5] = -1.0;
|
||||
quadPositions[i + 6] = 1.0; // upper right
|
||||
quadPositions[i + 7] = 1.0;
|
||||
quadPositions[i + 8] = 1.0; // lower right
|
||||
quadPositions[i + 9] = -1.0;
|
||||
quadPositions[i + 10] = -1.0; // lower left
|
||||
quadPositions[i + 11] = -1.0;
|
||||
}
|
||||
glBufferData(GL_ARRAY_BUFFER, quadPositions.size() * sizeof(float), quadPositions.data(),
|
||||
GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(kPosLoc);
|
||||
glVertexAttribPointer(kPosLoc, 2, GL_FLOAT, false, 0, 0);
|
||||
|
||||
// Create a small vertex buffer with determined-ahead-of-time "random" values (0.2). This buffer
|
||||
// will be the one read past the end.
|
||||
GLBuffer glVertexBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, glVertexBuffer);
|
||||
std::array<float, 6> vertexData = {0.2, 0.2, 0.2, 0.2, 0.2, 0.2};
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(float), vertexData.data(),
|
||||
GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(kRandomLoc);
|
||||
glVertexAttribPointer(kRandomLoc, 4, GL_FLOAT, false, 0, 0);
|
||||
|
||||
// Test -- Draw off the end of the vertex buffer near the beginning of the out of bounds area.
|
||||
DrawAndVerifyOutOfBoundsArrays(/*first*/ 6, /*count*/ 6);
|
||||
|
||||
// Test -- Draw off the end of the vertex buffer near the end of the out of bounds area.
|
||||
DrawAndVerifyOutOfBoundsArrays(/*first*/ (numberOfQuads - 1) * 6, /*count*/ 6);
|
||||
}
|
||||
|
||||
// Prepare an element array buffer that indexes out-of-bounds beginning with the start index passed
|
||||
// in. Ensure that drawElements flags either no error or INVALID_OPERATION. In the case of
|
||||
// INVALID_OPERATION, no canvas pixels can be touched. In the case of NO_ERROR, all written values
|
||||
// must either be the zero vertex or a value in the vertex buffer. See vsCheckOutOfBounds shader.
|
||||
void DrawAndVerifyOutOfBoundsIndex(int startIndex)
|
||||
{
|
||||
glClearColor(0.0, 0.0, 1.0, 1.0); // Start with blue to indicate no pixels touched.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Create an element array buffer with a tri-strip that starts at startIndex and make
|
||||
// it the active element array buffer.
|
||||
GLBuffer glElementArrayBuffer;
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glElementArrayBuffer);
|
||||
std::array<uint16_t, 4> quadIndices;
|
||||
for (unsigned int i = 0; i < quadIndices.size(); i++)
|
||||
{
|
||||
quadIndices[i] = startIndex + i;
|
||||
}
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, quadIndices.size() * sizeof(uint16_t), quadIndices.data(),
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, /*offset*/ 0);
|
||||
GLenum error = glGetError();
|
||||
if (error == GL_INVALID_OPERATION)
|
||||
{
|
||||
// testPassed. drawElements flagged INVALID_OPERATION, which is valid so long as all canvas
|
||||
// pixels were not touched.
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_GL_NO_ERROR();
|
||||
// testPassed. drawElements flagged NO_ERROR, which is valid so long as all canvas pixels
|
||||
// are green.
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from WebGL test
|
||||
// conformance/rendering/out-of-bounds-index-buffers.html
|
||||
// This test verifies that out-of-bounds index buffers behave according to spec.
|
||||
TEST_P(RobustResourceInitTest, OutOfBoundsIndexBuffers)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!hasGLExtension());
|
||||
|
||||
constexpr char vsCheckOutOfBounds[] =
|
||||
"precision mediump float;\n"
|
||||
"attribute vec2 position;\n"
|
||||
"attribute vec4 vecRandom;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"\n"
|
||||
"// Per the spec, each component can either contain existing contents\n"
|
||||
"// of the buffer or 0.\n"
|
||||
"bool testFloatComponent(float component) {\n"
|
||||
" return (component == 0.2 || component == 0.0);\n"
|
||||
"}\n"
|
||||
"" // The last component is additionally allowed to be 1.0.\n"
|
||||
"bool testLastFloatComponent(float component) {\n"
|
||||
" return testFloatComponent(component) || component == 1.0;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main() {\n"
|
||||
" if (testFloatComponent(vecRandom.x) &&\n"
|
||||
" testFloatComponent(vecRandom.y) &&\n"
|
||||
" testFloatComponent(vecRandom.z) &&\n"
|
||||
" testLastFloatComponent(vecRandom.w)) {\n"
|
||||
" v_color = vec4(0.0, 1.0, 0.0, 1.0); // green -- We're good\n"
|
||||
" } else {\n"
|
||||
" v_color = vec4(1.0, 0.0, 0.0, 1.0); // red -- Unexpected value\n"
|
||||
" }\n"
|
||||
" gl_Position = vec4(position, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
constexpr char simpleVertexColorFragmentShader[] =
|
||||
"precision mediump float;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = v_color;\n"
|
||||
"}";
|
||||
|
||||
// Setup the verification program.
|
||||
ANGLE_GL_PROGRAM(program, vsCheckOutOfBounds, simpleVertexColorFragmentShader);
|
||||
glUseProgram(program);
|
||||
|
||||
GLint kPosLoc = glGetAttribLocation(program, "position");
|
||||
ASSERT_NE(kPosLoc, -1);
|
||||
GLint kRandomLoc = glGetAttribLocation(program, "vecRandom");
|
||||
ASSERT_NE(kRandomLoc, -1);
|
||||
|
||||
// Create a buffer of 200 valid sets of quad lists.
|
||||
constexpr size_t numberOfQuads = 200;
|
||||
// Create a vertex buffer with 200 properly formed tri-strip quads. These quads will cover the
|
||||
// canvas texture such that every single pixel is touched by the fragment shader.
|
||||
GLBuffer glQuadBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, glQuadBuffer);
|
||||
std::array<float, numberOfQuads * 2 * 4> quadPositions;
|
||||
for (unsigned int i = 0; i < quadPositions.size(); i += 2 * 4)
|
||||
{
|
||||
quadPositions[i + 0] = -1.0; // upper left
|
||||
quadPositions[i + 1] = 1.0;
|
||||
quadPositions[i + 2] = 1.0; // upper right
|
||||
quadPositions[i + 3] = 1.0;
|
||||
quadPositions[i + 4] = -1.0; // lower left
|
||||
quadPositions[i + 5] = -1.0;
|
||||
quadPositions[i + 6] = 1.0; // lower right
|
||||
quadPositions[i + 7] = -1.0;
|
||||
}
|
||||
glBufferData(GL_ARRAY_BUFFER, quadPositions.size() * sizeof(float), quadPositions.data(),
|
||||
GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(kPosLoc);
|
||||
glVertexAttribPointer(kPosLoc, 2, GL_FLOAT, false, 0, 0);
|
||||
|
||||
// Create a small vertex buffer with determined-ahead-of-time "random" values (0.2). This buffer
|
||||
// will be the one indexed off the end.
|
||||
GLBuffer glVertexBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, glVertexBuffer);
|
||||
std::array<float, 4> vertexData = {0.2, 0.2, 0.2, 0.2};
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(float), vertexData.data(),
|
||||
GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(kRandomLoc);
|
||||
glVertexAttribPointer(kRandomLoc, 4, GL_FLOAT, false, 0, 0);
|
||||
|
||||
// Test -- Index off the end of the vertex buffer near the beginning of the out of bounds area.
|
||||
DrawAndVerifyOutOfBoundsIndex(/*StartIndex*/ 4);
|
||||
|
||||
// Test -- Index off the end of the vertex buffer near the end of the out of bounds area.
|
||||
DrawAndVerifyOutOfBoundsIndex(/*StartIndex*/ numberOfQuads - 4);
|
||||
}
|
||||
|
||||
// Regression test for images being recovered from storage not re-syncing to storage after being
|
||||
// initialized
|
||||
TEST_P(RobustResourceInitTestES3, D3D11RecoverFromStorageBug)
|
||||
|
|
Загрузка…
Ссылка в новой задаче