1 //
2 // Copyright 2022 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // DrawElementsTest:
7 // Tests for indexed draws.
8 //
9
10 #include "test_utils/ANGLETest.h"
11 #include "test_utils/gl_raii.h"
12
13 using namespace angle;
14
15 namespace
16 {
17
18 enum class DrawCallVariants
19 {
20 DrawRangeElements,
21 DrawRangeElementsBaseVertex,
22 DrawRangeElementsBaseVertexEXT,
23 DrawRangeElementsBaseVertexOES,
24 };
25
26 class DrawRangeElementsTest : public ANGLETest<>
27 {
28 protected:
DrawRangeElementsTest()29 DrawRangeElementsTest()
30 {
31 setWindowWidth(64);
32 setWindowHeight(64);
33 setConfigRedBits(8);
34 setConfigGreenBits(8);
35 setConfigBlueBits(8);
36 setConfigAlphaBits(8);
37 }
38
drawRangeElementsVariant(DrawCallVariants drawCallVariant,GLsizei count,GLint baseVertex)39 void drawRangeElementsVariant(DrawCallVariants drawCallVariant, GLsizei count, GLint baseVertex)
40 {
41 switch (drawCallVariant)
42 {
43 case DrawCallVariants::DrawRangeElements:
44 glDrawRangeElements(GL_TRIANGLES, 0, 1000, count, GL_UNSIGNED_BYTE, nullptr);
45 break;
46 case DrawCallVariants::DrawRangeElementsBaseVertex:
47 glDrawRangeElementsBaseVertex(GL_TRIANGLES, 0, 1000, count, GL_UNSIGNED_BYTE,
48 nullptr, baseVertex);
49 break;
50 case DrawCallVariants::DrawRangeElementsBaseVertexEXT:
51 glDrawRangeElementsBaseVertexEXT(GL_TRIANGLES, 0, 1000, count, GL_UNSIGNED_BYTE,
52 nullptr, baseVertex);
53 break;
54 case DrawCallVariants::DrawRangeElementsBaseVertexOES:
55 glDrawRangeElementsBaseVertexOES(GL_TRIANGLES, 0, 1000, count, GL_UNSIGNED_BYTE,
56 nullptr, baseVertex);
57 break;
58 }
59 }
60
doDrawRangeElementsVariant(DrawCallVariants drawCallVariant)61 void doDrawRangeElementsVariant(DrawCallVariants drawCallVariant)
62 {
63 constexpr char kVS[] =
64 "attribute vec3 a_pos;\n"
65 "void main()\n"
66 "{\n"
67 " gl_Position = vec4(a_pos, 1.0);\n"
68 "}\n";
69
70 ANGLE_GL_PROGRAM(program, kVS, essl1_shaders::fs::Blue());
71
72 GLint posLocation = glGetAttribLocation(program, "a_pos");
73 ASSERT_NE(-1, posLocation);
74 glUseProgram(program);
75
76 const auto &vertices = GetQuadVertices();
77
78 GLBuffer vertexBuffer;
79 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
80 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
81 GL_STATIC_DRAW);
82
83 glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
84 glEnableVertexAttribArray(posLocation);
85 ASSERT_GL_NO_ERROR();
86
87 GLBuffer indexBuffer;
88 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
89
90 drawRangeElementsVariant(drawCallVariant, 1, 0);
91 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
92
93 // count == 0 so it's fine to have no data in the element array buffer bound.
94 drawRangeElementsVariant(drawCallVariant, 0, 0);
95 ASSERT_GL_NO_ERROR();
96 }
97 };
98
99 class WebGLDrawRangeElementsTest : public DrawRangeElementsTest
100 {
101 public:
WebGLDrawRangeElementsTest()102 WebGLDrawRangeElementsTest() { setWebGLCompatibilityEnabled(true); }
103 };
104
105 // Test that glDrawRangeElements generates an error when trying to draw from an
106 // empty element array buffer with count other than 0 and no error when count
107 // equals 0.
TEST_P(WebGLDrawRangeElementsTest,DrawRangeElementArrayZeroCount)108 TEST_P(WebGLDrawRangeElementsTest, DrawRangeElementArrayZeroCount)
109 {
110 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
111
112 doDrawRangeElementsVariant(DrawCallVariants::DrawRangeElements);
113 }
114
115 // Test that glDrawRangeElementsBaseVertex generates an error when trying to
116 // draw from an empty element array buffer with count other than 0 and no error
117 // when count equals 0.
TEST_P(WebGLDrawRangeElementsTest,DrawRangeElementBaseVertexArrayZeroCount)118 TEST_P(WebGLDrawRangeElementsTest, DrawRangeElementBaseVertexArrayZeroCount)
119 {
120 doDrawRangeElementsVariant(DrawCallVariants::DrawRangeElementsBaseVertex);
121 }
122
123 // Test that glDrawRangeElementsBaseVertexEXT generates an error when trying to
124 // draw from an empty element array buffer with count other than 0 and no error
125 // when count equals 0.
TEST_P(WebGLDrawRangeElementsTest,DrawRangeElementBaseVertexEXTArrayZeroCount)126 TEST_P(WebGLDrawRangeElementsTest, DrawRangeElementBaseVertexEXTArrayZeroCount)
127 {
128 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_elements_base_vertex"));
129
130 doDrawRangeElementsVariant(DrawCallVariants::DrawRangeElementsBaseVertexEXT);
131 }
132
133 // Test that glDrawRangeElementsBaseVertexOES generates an error when trying to
134 // draw from an empty element array buffer with count other than 0 and no error
135 // when count equals 0.
TEST_P(WebGLDrawRangeElementsTest,DrawRangeElementBaseVertexOESArrayZeroCount)136 TEST_P(WebGLDrawRangeElementsTest, DrawRangeElementBaseVertexOESArrayZeroCount)
137 {
138 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_OES_draw_elements_base_vertex"));
139
140 doDrawRangeElementsVariant(DrawCallVariants::DrawRangeElementsBaseVertexOES);
141 }
142
143 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrawRangeElementsTest);
144 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(WebGLDrawRangeElementsTest);
145
146 } // namespace
147