blob: 925005a6e90221756027e61809201c1253a042e8 [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 Madille79b1e12015-11-04 16:36:37 -050014#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::_;
Jamie Madill60ec6ea2016-01-22 15:27:19 -050023using testing::NiceMock;
Jamie Madille79b1e12015-11-04 16:36:37 -050024using testing::Return;
25
26namespace
27{
28
Jamie Madille79b1e12015-11-04 16:36:37 -050029class MockValidationContext : public ValidationContext
30{
31 public:
Geoff Langeb66a6e2016-10-31 13:06:12 -040032 MockValidationContext(const Version &version,
Jamie Madilldfde6ab2016-06-09 07:07:18 -070033 State *state,
Jamie Madille79b1e12015-11-04 16:36:37 -050034 const Caps &caps,
35 const TextureCapsMap &textureCaps,
36 const Extensions &extensions,
37 const ResourceManager *resourceManager,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050038 const Limitations &limitations,
Jamie Madill01a80ee2016-11-07 12:06:18 -050039 const ResourceMap<Framebuffer> &framebufferMap,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050040 bool skipValidation);
Jamie Madille79b1e12015-11-04 16:36:37 -050041
Jamie Madill437fa652016-05-03 15:13:24 -040042 MOCK_METHOD1(handleError, void(const Error &));
Jamie Madille79b1e12015-11-04 16:36:37 -050043};
44
Geoff Langeb66a6e2016-10-31 13:06:12 -040045MockValidationContext::MockValidationContext(const Version &version,
Jamie Madilldfde6ab2016-06-09 07:07:18 -070046 State *state,
Jamie Madille79b1e12015-11-04 16:36:37 -050047 const Caps &caps,
48 const TextureCapsMap &textureCaps,
49 const Extensions &extensions,
50 const ResourceManager *resourceManager,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050051 const Limitations &limitations,
Jamie Madill01a80ee2016-11-07 12:06:18 -050052 const ResourceMap<Framebuffer> &framebufferMap,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050053 bool skipValidation)
Geoff Langeb66a6e2016-10-31 13:06:12 -040054 : ValidationContext(version,
Jamie Madille79b1e12015-11-04 16:36:37 -050055 state,
56 caps,
57 textureCaps,
58 extensions,
59 resourceManager,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050060 limitations,
Jamie Madill01a80ee2016-11-07 12:06:18 -050061 framebufferMap,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050062 skipValidation)
Jamie Madille79b1e12015-11-04 16:36:37 -050063{
64}
65
66// Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value
67// larger than MAX_ELEMENT_INDEX. Not specified in the GLES 3 spec, it's undefined behaviour,
68// but we want a test to ensure we maintain this behaviour.
69TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
70{
Jamie Madill60ec6ea2016-01-22 15:27:19 -050071 auto framebufferImpl = MakeFramebufferMock();
72 auto programImpl = MakeProgramMock();
73
Jamie Madille79b1e12015-11-04 16:36:37 -050074 // TODO(jmadill): Generalize some of this code so we can re-use it for other tests.
Jamie Madill7aea7e02016-05-10 10:39:45 -040075 NiceMock<MockGLFactory> mockFactory;
Jamie Madille79b1e12015-11-04 16:36:37 -050076 EXPECT_CALL(mockFactory, createFramebuffer(_)).WillOnce(Return(framebufferImpl));
77 EXPECT_CALL(mockFactory, createProgram(_)).WillOnce(Return(programImpl));
78 EXPECT_CALL(mockFactory, createVertexArray(_)).WillOnce(Return(nullptr));
79
80 State state;
81 Caps caps;
82 TextureCapsMap textureCaps;
83 Extensions extensions;
84 Limitations limitations;
Jamie Madill01a80ee2016-11-07 12:06:18 -050085 ResourceMap<Framebuffer> framebufferMap;
Jamie Madille79b1e12015-11-04 16:36:37 -050086
87 // Set some basic caps.
88 caps.maxElementIndex = 100;
89 caps.maxDrawBuffers = 1;
90 caps.maxColorAttachments = 1;
Geoff Langeb66a6e2016-10-31 13:06:12 -040091 state.initialize(caps, extensions, Version(3, 0), false, true);
Jamie Madille79b1e12015-11-04 16:36:37 -050092
Jamie Madill60ec6ea2016-01-22 15:27:19 -050093 NiceMock<MockTextureImpl> *textureImpl = new NiceMock<MockTextureImpl>();
Olli Etuaho82c47ad2016-04-20 18:28:47 +030094 EXPECT_CALL(mockFactory, createTexture(_)).WillOnce(Return(textureImpl));
Jamie Madille79b1e12015-11-04 16:36:37 -050095 EXPECT_CALL(*textureImpl, setStorage(_, _, _, _)).WillOnce(Return(Error(GL_NO_ERROR)));
96 EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
Jamie Madill60ec6ea2016-01-22 15:27:19 -050097
Olli Etuaho82c47ad2016-04-20 18:28:47 +030098 Texture *texture = new Texture(&mockFactory, 0, GL_TEXTURE_2D);
Jamie Madille79b1e12015-11-04 16:36:37 -050099 texture->addRef();
100 texture->setStorage(GL_TEXTURE_2D, 1, GL_RGBA8, Extents(1, 1, 0));
101
102 VertexArray *vertexArray = new VertexArray(&mockFactory, 0, 1);
103 Framebuffer *framebuffer = new Framebuffer(caps, &mockFactory, 1);
104 framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::Make2D(0), texture);
105
106 Program *program = new Program(&mockFactory, nullptr, 1);
107
108 state.setVertexArrayBinding(vertexArray);
109 state.setDrawFramebufferBinding(framebuffer);
110 state.setProgram(program);
111
Geoff Langeb66a6e2016-10-31 13:06:12 -0400112 NiceMock<MockValidationContext> testContext(Version(3, 0), &state, caps, textureCaps,
Jamie Madill01a80ee2016-11-07 12:06:18 -0500113 extensions, nullptr, limitations, framebufferMap,
114 false);
Jamie Madille79b1e12015-11-04 16:36:37 -0500115
116 // Set the expectation for the validation error here.
117 Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage);
Jamie Madill437fa652016-05-03 15:13:24 -0400118 EXPECT_CALL(testContext, handleError(expectedError)).Times(1);
Jamie Madille79b1e12015-11-04 16:36:37 -0500119
120 // Call once with maximum index, and once with an excessive index.
121 GLuint indexData[] = {0, 1, static_cast<GLuint>(caps.maxElementIndex - 1),
122 3, 4, static_cast<GLuint>(caps.maxElementIndex)};
123 IndexRange indexRange;
124 EXPECT_TRUE(ValidateDrawElements(&testContext, GL_TRIANGLES, 3, GL_UNSIGNED_INT, indexData, 1,
125 &indexRange));
126 EXPECT_FALSE(ValidateDrawElements(&testContext, GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexData, 2,
127 &indexRange));
128
129 texture->release();
Jamie Madilldaa8c272015-11-18 14:13:55 -0500130
131 state.setVertexArrayBinding(nullptr);
132 state.setDrawFramebufferBinding(nullptr);
133 state.setProgram(nullptr);
134
Jamie Madille79b1e12015-11-04 16:36:37 -0500135 SafeDelete(vertexArray);
136 SafeDelete(framebuffer);
137 SafeDelete(program);
138}
139
140} // anonymous namespace