Hash :
40e4bc63
Author :
Date :
2022-11-09T12:40:48
Make DrawRangeElements validation consistent with DrawElements According to the WebGL specification, when an empty buffer is bound to GL_ELEMENT_ARRAY_BUFFER binding point, one of the possibilities is to return an error when trying to draw with an index count other than zero. This is the behavior of DrawElements variants but not DrawRangeElements. This change brings variants of DrawRangeElements behavior in line with that of DrawElements. Bug: angleproject:7822 Change-Id: I6844efd1038d95c652b72e52209dfdd74f006f9b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4015418 Reviewed-by: Geoff Lang <geofflang@chromium.org> Reviewed-by: Kenneth Russell <kbr@chromium.org> Commit-Queue: Alexey Knyazev <lexa.knyazev@gmail.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
//
// Copyright 2022 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.
//
// DrawElementsTest:
// Tests for indexed draws.
//
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
using namespace angle;
namespace
{
enum class DrawCallVariants
{
DrawRangeElements,
DrawRangeElementsBaseVertex,
DrawRangeElementsBaseVertexEXT,
DrawRangeElementsBaseVertexOES,
};
class DrawRangeElementsTest : public ANGLETest<>
{
protected:
DrawRangeElementsTest()
{
setWindowWidth(64);
setWindowHeight(64);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
void drawRangeElementsVariant(DrawCallVariants drawCallVariant, GLsizei count, GLint baseVertex)
{
switch (drawCallVariant)
{
case DrawCallVariants::DrawRangeElements:
glDrawRangeElements(GL_TRIANGLES, 0, 1000, count, GL_UNSIGNED_BYTE, nullptr);
break;
case DrawCallVariants::DrawRangeElementsBaseVertex:
glDrawRangeElementsBaseVertex(GL_TRIANGLES, 0, 1000, count, GL_UNSIGNED_BYTE,
nullptr, baseVertex);
break;
case DrawCallVariants::DrawRangeElementsBaseVertexEXT:
glDrawRangeElementsBaseVertexEXT(GL_TRIANGLES, 0, 1000, count, GL_UNSIGNED_BYTE,
nullptr, baseVertex);
break;
case DrawCallVariants::DrawRangeElementsBaseVertexOES:
glDrawRangeElementsBaseVertexOES(GL_TRIANGLES, 0, 1000, count, GL_UNSIGNED_BYTE,
nullptr, baseVertex);
break;
}
}
void doDrawRangeElementsVariant(DrawCallVariants drawCallVariant)
{
constexpr char kVS[] =
"attribute vec3 a_pos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(a_pos, 1.0);\n"
"}\n";
ANGLE_GL_PROGRAM(program, kVS, essl1_shaders::fs::Blue());
GLint posLocation = glGetAttribLocation(program, "a_pos");
ASSERT_NE(-1, posLocation);
glUseProgram(program);
const auto &vertices = GetQuadVertices();
GLBuffer vertexBuffer;
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
GL_STATIC_DRAW);
glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posLocation);
ASSERT_GL_NO_ERROR();
GLBuffer indexBuffer;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
drawRangeElementsVariant(drawCallVariant, 1, 0);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
// count == 0 so it's fine to have no data in the element array buffer bound.
drawRangeElementsVariant(drawCallVariant, 0, 0);
ASSERT_GL_NO_ERROR();
}
};
class WebGLDrawRangeElementsTest : public DrawRangeElementsTest
{
public:
WebGLDrawRangeElementsTest() { setWebGLCompatibilityEnabled(true); }
};
// Test that glDrawRangeElements generates an error when trying to draw from an
// empty element array buffer with count other than 0 and no error when count
// equals 0.
TEST_P(WebGLDrawRangeElementsTest, DrawRangeElementArrayZeroCount)
{
ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
doDrawRangeElementsVariant(DrawCallVariants::DrawRangeElements);
}
// Test that glDrawRangeElementsBaseVertex generates an error when trying to
// draw from an empty element array buffer with count other than 0 and no error
// when count equals 0.
TEST_P(WebGLDrawRangeElementsTest, DrawRangeElementBaseVertexArrayZeroCount)
{
doDrawRangeElementsVariant(DrawCallVariants::DrawRangeElementsBaseVertex);
}
// Test that glDrawRangeElementsBaseVertexEXT generates an error when trying to
// draw from an empty element array buffer with count other than 0 and no error
// when count equals 0.
TEST_P(WebGLDrawRangeElementsTest, DrawRangeElementBaseVertexEXTArrayZeroCount)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_elements_base_vertex"));
doDrawRangeElementsVariant(DrawCallVariants::DrawRangeElementsBaseVertexEXT);
}
// Test that glDrawRangeElementsBaseVertexOES generates an error when trying to
// draw from an empty element array buffer with count other than 0 and no error
// when count equals 0.
TEST_P(WebGLDrawRangeElementsTest, DrawRangeElementBaseVertexOESArrayZeroCount)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_OES_draw_elements_base_vertex"));
doDrawRangeElementsVariant(DrawCallVariants::DrawRangeElementsBaseVertexOES);
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrawRangeElementsTest);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(WebGLDrawRangeElementsTest);
} // namespace