blob: 8d8d13ad5c3c213f1d662ec32b62892a893731bf [file] [log] [blame]
Jamie Madille79b1e12015-11-04 16:36:37 -05001//
2// Copyright 2015 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// validationES unit tests:
7// Unit tests for general ES validation functions.
8//
9
10#include <gmock/gmock.h>
11#include <gtest/gtest.h>
12
13#include "libANGLE/Data.h"
14#include "libANGLE/renderer/FramebufferImpl_mock.h"
15#include "libANGLE/renderer/ProgramImpl_mock.h"
16#include "libANGLE/renderer/TextureImpl_mock.h"
17#include "libANGLE/validationES.h"
18#include "tests/angle_unittests_utils.h"
19
20using namespace gl;
21using namespace rx;
22using testing::_;
23using testing::Return;
24
25namespace
26{
27
28class MockFactory : public NullFactory
29{
30 public:
31 MOCK_METHOD1(createFramebuffer, FramebufferImpl *(const gl::Framebuffer::Data &));
32 MOCK_METHOD1(createProgram, ProgramImpl *(const gl::Program::Data &));
33 MOCK_METHOD1(createVertexArray, VertexArrayImpl *(const gl::VertexArray::Data &));
34};
35
36class MockValidationContext : public ValidationContext
37{
38 public:
39 MockValidationContext(GLint clientVersion,
40 const State &state,
41 const Caps &caps,
42 const TextureCapsMap &textureCaps,
43 const Extensions &extensions,
44 const ResourceManager *resourceManager,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050045 const Limitations &limitations,
46 bool skipValidation);
Jamie Madille79b1e12015-11-04 16:36:37 -050047
48 MOCK_METHOD1(recordError, void(const Error &));
49};
50
51MockValidationContext::MockValidationContext(GLint clientVersion,
52 const State &state,
53 const Caps &caps,
54 const TextureCapsMap &textureCaps,
55 const Extensions &extensions,
56 const ResourceManager *resourceManager,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050057 const Limitations &limitations,
58 bool skipValidation)
Jamie Madille79b1e12015-11-04 16:36:37 -050059 : ValidationContext(clientVersion,
60 state,
61 caps,
62 textureCaps,
63 extensions,
64 resourceManager,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050065 limitations,
66 skipValidation)
Jamie Madille79b1e12015-11-04 16:36:37 -050067{
68}
69
70// Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value
71// larger than MAX_ELEMENT_INDEX. Not specified in the GLES 3 spec, it's undefined behaviour,
72// but we want a test to ensure we maintain this behaviour.
73TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
74{
75 // TODO(jmadill): Generalize some of this code so we can re-use it for other tests.
76 MockFramebufferImpl *framebufferImpl = new MockFramebufferImpl();
77 EXPECT_CALL(*framebufferImpl, onUpdateColorAttachment(_)).Times(1).RetiresOnSaturation();
78 EXPECT_CALL(*framebufferImpl, checkStatus())
79 .Times(2)
Jamie Madillcc86d642015-11-24 13:00:07 -050080 .WillOnce(Return(true))
81 .WillOnce(Return(true));
Jamie Madille79b1e12015-11-04 16:36:37 -050082 EXPECT_CALL(*framebufferImpl, destroy()).Times(1).RetiresOnSaturation();
83
84 MockProgramImpl *programImpl = new MockProgramImpl();
85 EXPECT_CALL(*programImpl, destroy());
86
87 MockFactory mockFactory;
88 EXPECT_CALL(mockFactory, createFramebuffer(_)).WillOnce(Return(framebufferImpl));
89 EXPECT_CALL(mockFactory, createProgram(_)).WillOnce(Return(programImpl));
90 EXPECT_CALL(mockFactory, createVertexArray(_)).WillOnce(Return(nullptr));
91
92 State state;
93 Caps caps;
94 TextureCapsMap textureCaps;
95 Extensions extensions;
96 Limitations limitations;
97
98 // Set some basic caps.
99 caps.maxElementIndex = 100;
100 caps.maxDrawBuffers = 1;
101 caps.maxColorAttachments = 1;
Geoff Lang70d0f492015-12-10 17:45:46 -0500102 state.initialize(caps, extensions, 3, false);
Jamie Madille79b1e12015-11-04 16:36:37 -0500103
104 MockTextureImpl *textureImpl = new MockTextureImpl();
105 EXPECT_CALL(*textureImpl, setStorage(_, _, _, _)).WillOnce(Return(Error(GL_NO_ERROR)));
106 EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
107 Texture *texture = new Texture(textureImpl, 0, GL_TEXTURE_2D);
108 texture->addRef();
109 texture->setStorage(GL_TEXTURE_2D, 1, GL_RGBA8, Extents(1, 1, 0));
110
111 VertexArray *vertexArray = new VertexArray(&mockFactory, 0, 1);
112 Framebuffer *framebuffer = new Framebuffer(caps, &mockFactory, 1);
113 framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::Make2D(0), texture);
114
115 Program *program = new Program(&mockFactory, nullptr, 1);
116
117 state.setVertexArrayBinding(vertexArray);
118 state.setDrawFramebufferBinding(framebuffer);
119 state.setProgram(program);
120
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500121 MockValidationContext testContext(3, state, caps, textureCaps, extensions, nullptr, limitations,
122 false);
Jamie Madille79b1e12015-11-04 16:36:37 -0500123
124 // Set the expectation for the validation error here.
125 Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage);
126 EXPECT_CALL(testContext, recordError(expectedError)).Times(1);
127
128 // Call once with maximum index, and once with an excessive index.
129 GLuint indexData[] = {0, 1, static_cast<GLuint>(caps.maxElementIndex - 1),
130 3, 4, static_cast<GLuint>(caps.maxElementIndex)};
131 IndexRange indexRange;
132 EXPECT_TRUE(ValidateDrawElements(&testContext, GL_TRIANGLES, 3, GL_UNSIGNED_INT, indexData, 1,
133 &indexRange));
134 EXPECT_FALSE(ValidateDrawElements(&testContext, GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexData, 2,
135 &indexRange));
136
137 texture->release();
Jamie Madilldaa8c272015-11-18 14:13:55 -0500138
139 state.setVertexArrayBinding(nullptr);
140 state.setDrawFramebufferBinding(nullptr);
141 state.setProgram(nullptr);
142
Jamie Madille79b1e12015-11-04 16:36:37 -0500143 SafeDelete(vertexArray);
144 SafeDelete(framebuffer);
145 SafeDelete(program);
146}
147
148} // anonymous namespace