blob: 1b4a640bc23b9e6d1abe5eb08b362362cc818f8f [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,
45 const Limitations &limitations);
46
47 MOCK_METHOD1(recordError, void(const Error &));
48};
49
50MockValidationContext::MockValidationContext(GLint clientVersion,
51 const State &state,
52 const Caps &caps,
53 const TextureCapsMap &textureCaps,
54 const Extensions &extensions,
55 const ResourceManager *resourceManager,
56 const Limitations &limitations)
57 : ValidationContext(clientVersion,
58 state,
59 caps,
60 textureCaps,
61 extensions,
62 resourceManager,
63 limitations)
64{
65}
66
67// Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value
68// larger than MAX_ELEMENT_INDEX. Not specified in the GLES 3 spec, it's undefined behaviour,
69// but we want a test to ensure we maintain this behaviour.
70TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
71{
72 // TODO(jmadill): Generalize some of this code so we can re-use it for other tests.
73 MockFramebufferImpl *framebufferImpl = new MockFramebufferImpl();
74 EXPECT_CALL(*framebufferImpl, onUpdateColorAttachment(_)).Times(1).RetiresOnSaturation();
75 EXPECT_CALL(*framebufferImpl, checkStatus())
76 .Times(2)
77 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
78 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE));
79 EXPECT_CALL(*framebufferImpl, destroy()).Times(1).RetiresOnSaturation();
80
81 MockProgramImpl *programImpl = new MockProgramImpl();
82 EXPECT_CALL(*programImpl, destroy());
83
84 MockFactory mockFactory;
85 EXPECT_CALL(mockFactory, createFramebuffer(_)).WillOnce(Return(framebufferImpl));
86 EXPECT_CALL(mockFactory, createProgram(_)).WillOnce(Return(programImpl));
87 EXPECT_CALL(mockFactory, createVertexArray(_)).WillOnce(Return(nullptr));
88
89 State state;
90 Caps caps;
91 TextureCapsMap textureCaps;
92 Extensions extensions;
93 Limitations limitations;
94
95 // Set some basic caps.
96 caps.maxElementIndex = 100;
97 caps.maxDrawBuffers = 1;
98 caps.maxColorAttachments = 1;
99 state.initialize(caps, 3);
100
101 MockTextureImpl *textureImpl = new MockTextureImpl();
102 EXPECT_CALL(*textureImpl, setStorage(_, _, _, _)).WillOnce(Return(Error(GL_NO_ERROR)));
103 EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
104 Texture *texture = new Texture(textureImpl, 0, GL_TEXTURE_2D);
105 texture->addRef();
106 texture->setStorage(GL_TEXTURE_2D, 1, GL_RGBA8, Extents(1, 1, 0));
107
108 VertexArray *vertexArray = new VertexArray(&mockFactory, 0, 1);
109 Framebuffer *framebuffer = new Framebuffer(caps, &mockFactory, 1);
110 framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::Make2D(0), texture);
111
112 Program *program = new Program(&mockFactory, nullptr, 1);
113
114 state.setVertexArrayBinding(vertexArray);
115 state.setDrawFramebufferBinding(framebuffer);
116 state.setProgram(program);
117
118 MockValidationContext testContext(3, state, caps, textureCaps, extensions, nullptr,
119 limitations);
120
121 // Set the expectation for the validation error here.
122 Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage);
123 EXPECT_CALL(testContext, recordError(expectedError)).Times(1);
124
125 // Call once with maximum index, and once with an excessive index.
126 GLuint indexData[] = {0, 1, static_cast<GLuint>(caps.maxElementIndex - 1),
127 3, 4, static_cast<GLuint>(caps.maxElementIndex)};
128 IndexRange indexRange;
129 EXPECT_TRUE(ValidateDrawElements(&testContext, GL_TRIANGLES, 3, GL_UNSIGNED_INT, indexData, 1,
130 &indexRange));
131 EXPECT_FALSE(ValidateDrawElements(&testContext, GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexData, 2,
132 &indexRange));
133
134 texture->release();
Jamie Madilldaa8c272015-11-18 14:13:55 -0500135
136 state.setVertexArrayBinding(nullptr);
137 state.setDrawFramebufferBinding(nullptr);
138 state.setProgram(nullptr);
139
Jamie Madille79b1e12015-11-04 16:36:37 -0500140 SafeDelete(vertexArray);
141 SafeDelete(framebuffer);
142 SafeDelete(program);
143}
144
145} // anonymous namespace