blob: ef049f99c263499f872ec2dbb5adecef260b3912 [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::_;
Jamie Madill60ec6ea2016-01-22 15:27:19 -050023using testing::NiceMock;
Jamie Madille79b1e12015-11-04 16:36:37 -050024using testing::Return;
25
26namespace
27{
28
29class MockFactory : public NullFactory
30{
31 public:
32 MOCK_METHOD1(createFramebuffer, FramebufferImpl *(const gl::Framebuffer::Data &));
33 MOCK_METHOD1(createProgram, ProgramImpl *(const gl::Program::Data &));
34 MOCK_METHOD1(createVertexArray, VertexArrayImpl *(const gl::VertexArray::Data &));
35};
36
37class MockValidationContext : public ValidationContext
38{
39 public:
40 MockValidationContext(GLint clientVersion,
41 const State &state,
42 const Caps &caps,
43 const TextureCapsMap &textureCaps,
44 const Extensions &extensions,
45 const ResourceManager *resourceManager,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050046 const Limitations &limitations,
47 bool skipValidation);
Jamie Madille79b1e12015-11-04 16:36:37 -050048
49 MOCK_METHOD1(recordError, void(const Error &));
50};
51
52MockValidationContext::MockValidationContext(GLint clientVersion,
53 const State &state,
54 const Caps &caps,
55 const TextureCapsMap &textureCaps,
56 const Extensions &extensions,
57 const ResourceManager *resourceManager,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050058 const Limitations &limitations,
59 bool skipValidation)
Jamie Madille79b1e12015-11-04 16:36:37 -050060 : ValidationContext(clientVersion,
61 state,
62 caps,
63 textureCaps,
64 extensions,
65 resourceManager,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050066 limitations,
67 skipValidation)
Jamie Madille79b1e12015-11-04 16:36:37 -050068{
69}
70
71// Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value
72// larger than MAX_ELEMENT_INDEX. Not specified in the GLES 3 spec, it's undefined behaviour,
73// but we want a test to ensure we maintain this behaviour.
74TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError)
75{
Jamie Madill60ec6ea2016-01-22 15:27:19 -050076 auto framebufferImpl = MakeFramebufferMock();
77 auto programImpl = MakeProgramMock();
78
Jamie Madille79b1e12015-11-04 16:36:37 -050079 // TODO(jmadill): Generalize some of this code so we can re-use it for other tests.
Jamie Madill60ec6ea2016-01-22 15:27:19 -050080 NiceMock<MockFactory> mockFactory;
Jamie Madille79b1e12015-11-04 16:36:37 -050081 EXPECT_CALL(mockFactory, createFramebuffer(_)).WillOnce(Return(framebufferImpl));
82 EXPECT_CALL(mockFactory, createProgram(_)).WillOnce(Return(programImpl));
83 EXPECT_CALL(mockFactory, createVertexArray(_)).WillOnce(Return(nullptr));
84
85 State state;
86 Caps caps;
87 TextureCapsMap textureCaps;
88 Extensions extensions;
89 Limitations limitations;
90
91 // Set some basic caps.
92 caps.maxElementIndex = 100;
93 caps.maxDrawBuffers = 1;
94 caps.maxColorAttachments = 1;
Geoff Lang70d0f492015-12-10 17:45:46 -050095 state.initialize(caps, extensions, 3, false);
Jamie Madille79b1e12015-11-04 16:36:37 -050096
Jamie Madill60ec6ea2016-01-22 15:27:19 -050097 NiceMock<MockTextureImpl> *textureImpl = new NiceMock<MockTextureImpl>();
Jamie Madille79b1e12015-11-04 16:36:37 -050098 EXPECT_CALL(*textureImpl, setStorage(_, _, _, _)).WillOnce(Return(Error(GL_NO_ERROR)));
99 EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500100
Jamie Madille79b1e12015-11-04 16:36:37 -0500101 Texture *texture = new Texture(textureImpl, 0, GL_TEXTURE_2D);
102 texture->addRef();
103 texture->setStorage(GL_TEXTURE_2D, 1, GL_RGBA8, Extents(1, 1, 0));
104
105 VertexArray *vertexArray = new VertexArray(&mockFactory, 0, 1);
106 Framebuffer *framebuffer = new Framebuffer(caps, &mockFactory, 1);
107 framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::Make2D(0), texture);
108
109 Program *program = new Program(&mockFactory, nullptr, 1);
110
111 state.setVertexArrayBinding(vertexArray);
112 state.setDrawFramebufferBinding(framebuffer);
113 state.setProgram(program);
114
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500115 NiceMock<MockValidationContext> testContext(3, state, caps, textureCaps, extensions, nullptr,
116 limitations, false);
Jamie Madille79b1e12015-11-04 16:36:37 -0500117
118 // Set the expectation for the validation error here.
119 Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage);
120 EXPECT_CALL(testContext, recordError(expectedError)).Times(1);
121
122 // Call once with maximum index, and once with an excessive index.
123 GLuint indexData[] = {0, 1, static_cast<GLuint>(caps.maxElementIndex - 1),
124 3, 4, static_cast<GLuint>(caps.maxElementIndex)};
125 IndexRange indexRange;
126 EXPECT_TRUE(ValidateDrawElements(&testContext, GL_TRIANGLES, 3, GL_UNSIGNED_INT, indexData, 1,
127 &indexRange));
128 EXPECT_FALSE(ValidateDrawElements(&testContext, GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexData, 2,
129 &indexRange));
130
131 texture->release();
Jamie Madilldaa8c272015-11-18 14:13:55 -0500132
133 state.setVertexArrayBinding(nullptr);
134 state.setDrawFramebufferBinding(nullptr);
135 state.setProgram(nullptr);
136
Jamie Madille79b1e12015-11-04 16:36:37 -0500137 SafeDelete(vertexArray);
138 SafeDelete(framebuffer);
139 SafeDelete(program);
140}
141
142} // anonymous namespace