blob: 586bd71a69e3726689736ffe3ca3fe278ed98b29 [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
Jamie Madill9082b982016-04-27 15:21:51 -040013#include "libANGLE/ContextState.h"
Jamie Madill192745a2016-12-22 15:58:21 -050014#include "libANGLE/VaryingPacking.h"
Jamie Madille79b1e12015-11-04 16:36:37 -050015#include "libANGLE/renderer/FramebufferImpl_mock.h"
16#include "libANGLE/renderer/ProgramImpl_mock.h"
17#include "libANGLE/renderer/TextureImpl_mock.h"
18#include "libANGLE/validationES.h"
19#include "tests/angle_unittests_utils.h"
20
21using namespace gl;
22using namespace rx;
23using testing::_;
Jamie Madill60ec6ea2016-01-22 15:27:19 -050024using testing::NiceMock;
Jamie Madille79b1e12015-11-04 16:36:37 -050025using testing::Return;
26
27namespace
28{
29
Jamie Madille79b1e12015-11-04 16:36:37 -050030class MockValidationContext : public ValidationContext
31{
32 public:
Geoff Lang4ddf5af2016-12-01 14:30:44 -050033 MockValidationContext(const ValidationContext *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -050034 TextureManager *shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -050035 const Version &version,
Jamie Madilldfde6ab2016-06-09 07:07:18 -070036 State *state,
Jamie Madille79b1e12015-11-04 16:36:37 -050037 const Caps &caps,
38 const TextureCapsMap &textureCaps,
39 const Extensions &extensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050040 const Limitations &limitations,
Geoff Lang4ddf5af2016-12-01 14:30:44 -050041 bool skipValidation)
42 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -050043 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -050044 version,
45 state,
46 caps,
47 textureCaps,
48 extensions,
49 limitations,
Geoff Lang4ddf5af2016-12-01 14:30:44 -050050 skipValidation)
51 {
52 }
Jamie Madille79b1e12015-11-04 16:36:37 -050053
Jamie Madill437fa652016-05-03 15:13:24 -040054 MOCK_METHOD1(handleError, void(const Error &));
Jamie Madille79b1e12015-11-04 16:36:37 -050055};
56
Jamie Madille79b1e12015-11-04 16:36:37 -050057// Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value
58// larger than MAX_ELEMENT_INDEX. Not specified in the GLES 3 spec, it's undefined behaviour,
59// but we want a test to ensure we maintain this behaviour.
60TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
61{
Jamie Madill60ec6ea2016-01-22 15:27:19 -050062 auto framebufferImpl = MakeFramebufferMock();
63 auto programImpl = MakeProgramMock();
64
Jamie Madille79b1e12015-11-04 16:36:37 -050065 // TODO(jmadill): Generalize some of this code so we can re-use it for other tests.
Jamie Madill7aea7e02016-05-10 10:39:45 -040066 NiceMock<MockGLFactory> mockFactory;
Jamie Madille79b1e12015-11-04 16:36:37 -050067 EXPECT_CALL(mockFactory, createFramebuffer(_)).WillOnce(Return(framebufferImpl));
68 EXPECT_CALL(mockFactory, createProgram(_)).WillOnce(Return(programImpl));
69 EXPECT_CALL(mockFactory, createVertexArray(_)).WillOnce(Return(nullptr));
70
71 State state;
72 Caps caps;
73 TextureCapsMap textureCaps;
74 Extensions extensions;
75 Limitations limitations;
76
77 // Set some basic caps.
78 caps.maxElementIndex = 100;
79 caps.maxDrawBuffers = 1;
80 caps.maxColorAttachments = 1;
Geoff Langeb66a6e2016-10-31 13:06:12 -040081 state.initialize(caps, extensions, Version(3, 0), false, true);
Jamie Madille79b1e12015-11-04 16:36:37 -050082
Jamie Madill60ec6ea2016-01-22 15:27:19 -050083 NiceMock<MockTextureImpl> *textureImpl = new NiceMock<MockTextureImpl>();
Olli Etuaho82c47ad2016-04-20 18:28:47 +030084 EXPECT_CALL(mockFactory, createTexture(_)).WillOnce(Return(textureImpl));
Jamie Madill8897afa2017-02-06 17:17:23 -050085 EXPECT_CALL(*textureImpl, setStorage(_, _, _, _, _)).WillOnce(Return(NoError()));
Jamie Madille79b1e12015-11-04 16:36:37 -050086 EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
Jamie Madill60ec6ea2016-01-22 15:27:19 -050087
Olli Etuaho82c47ad2016-04-20 18:28:47 +030088 Texture *texture = new Texture(&mockFactory, 0, GL_TEXTURE_2D);
Jamie Madille79b1e12015-11-04 16:36:37 -050089 texture->addRef();
Jamie Madill8897afa2017-02-06 17:17:23 -050090 texture->setStorage(nullptr, GL_TEXTURE_2D, 1, GL_RGBA8, Extents(1, 1, 0));
Jamie Madille79b1e12015-11-04 16:36:37 -050091
92 VertexArray *vertexArray = new VertexArray(&mockFactory, 0, 1);
93 Framebuffer *framebuffer = new Framebuffer(caps, &mockFactory, 1);
94 framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::Make2D(0), texture);
95
96 Program *program = new Program(&mockFactory, nullptr, 1);
97
98 state.setVertexArrayBinding(vertexArray);
99 state.setDrawFramebufferBinding(framebuffer);
100 state.setProgram(program);
101
Geoff Langce02f082017-02-06 16:46:21 -0500102 NiceMock<MockValidationContext> testContext(nullptr, nullptr, Version(3, 0), &state, caps,
103 textureCaps, extensions, limitations, false);
Jamie Madille79b1e12015-11-04 16:36:37 -0500104
105 // Set the expectation for the validation error here.
106 Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage);
Jamie Madill437fa652016-05-03 15:13:24 -0400107 EXPECT_CALL(testContext, handleError(expectedError)).Times(1);
Jamie Madille79b1e12015-11-04 16:36:37 -0500108
109 // Call once with maximum index, and once with an excessive index.
110 GLuint indexData[] = {0, 1, static_cast<GLuint>(caps.maxElementIndex - 1),
111 3, 4, static_cast<GLuint>(caps.maxElementIndex)};
112 IndexRange indexRange;
113 EXPECT_TRUE(ValidateDrawElements(&testContext, GL_TRIANGLES, 3, GL_UNSIGNED_INT, indexData, 1,
114 &indexRange));
115 EXPECT_FALSE(ValidateDrawElements(&testContext, GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexData, 2,
116 &indexRange));
117
118 texture->release();
Jamie Madilldaa8c272015-11-18 14:13:55 -0500119
120 state.setVertexArrayBinding(nullptr);
121 state.setDrawFramebufferBinding(nullptr);
122 state.setProgram(nullptr);
123
Jamie Madille79b1e12015-11-04 16:36:37 -0500124 SafeDelete(vertexArray);
125 SafeDelete(framebuffer);
126 SafeDelete(program);
127}
128
129} // anonymous namespace