blob: d0e601c2667919b9a5dccb5a1e450a089f99847b [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"
Brandon Jones6cad5662017-06-14 13:25:13 -070014#include "libANGLE/ErrorStrings.h"
Jamie Madill192745a2016-12-22 15:58:21 -050015#include "libANGLE/VaryingPacking.h"
Jamie Madille79b1e12015-11-04 16:36:37 -050016#include "libANGLE/renderer/FramebufferImpl_mock.h"
17#include "libANGLE/renderer/ProgramImpl_mock.h"
18#include "libANGLE/renderer/TextureImpl_mock.h"
19#include "libANGLE/validationES.h"
20#include "tests/angle_unittests_utils.h"
21
22using namespace gl;
23using namespace rx;
24using testing::_;
Jamie Madill60ec6ea2016-01-22 15:27:19 -050025using testing::NiceMock;
Jamie Madille79b1e12015-11-04 16:36:37 -050026using testing::Return;
27
28namespace
29{
30
Jamie Madille79b1e12015-11-04 16:36:37 -050031class MockValidationContext : public ValidationContext
32{
33 public:
Geoff Lang4ddf5af2016-12-01 14:30:44 -050034 MockValidationContext(const ValidationContext *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -050035 TextureManager *shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -050036 const Version &version,
Jamie Madilldfde6ab2016-06-09 07:07:18 -070037 State *state,
Jamie Madille79b1e12015-11-04 16:36:37 -050038 const Caps &caps,
39 const TextureCapsMap &textureCaps,
40 const Extensions &extensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -050041 const Limitations &limitations,
Geoff Lang4ddf5af2016-12-01 14:30:44 -050042 bool skipValidation)
43 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -050044 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -050045 version,
46 state,
47 caps,
48 textureCaps,
49 extensions,
50 limitations,
Geoff Lang4ddf5af2016-12-01 14:30:44 -050051 skipValidation)
52 {
53 }
Jamie Madille79b1e12015-11-04 16:36:37 -050054
Jamie Madill4c19a8a2017-07-24 11:46:06 -040055 MOCK_METHOD1(handleError, Error(const Error &));
Jamie Madille79b1e12015-11-04 16:36:37 -050056};
57
Jamie Madille79b1e12015-11-04 16:36:37 -050058// Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value
59// larger than MAX_ELEMENT_INDEX. Not specified in the GLES 3 spec, it's undefined behaviour,
60// but we want a test to ensure we maintain this behaviour.
Jamie Madillfa416b12017-04-06 11:34:17 -040061// TODO(jmadill): Re-enable when framebuffer sync state doesn't happen in validation.
Jamie Madill4928b7c2017-06-20 12:57:39 -040062// Also broken because of change of api of the state initialize method.
Jamie Madillfa416b12017-04-06 11:34:17 -040063TEST(ValidationESTest, DISABLED_DrawElementsWithMaxIndexGivesError)
Jamie Madille79b1e12015-11-04 16:36:37 -050064{
Jamie Madill60ec6ea2016-01-22 15:27:19 -050065 auto framebufferImpl = MakeFramebufferMock();
66 auto programImpl = MakeProgramMock();
67
Jamie Madille79b1e12015-11-04 16:36:37 -050068 // TODO(jmadill): Generalize some of this code so we can re-use it for other tests.
Jamie Madill7aea7e02016-05-10 10:39:45 -040069 NiceMock<MockGLFactory> mockFactory;
Jamie Madille79b1e12015-11-04 16:36:37 -050070 EXPECT_CALL(mockFactory, createFramebuffer(_)).WillOnce(Return(framebufferImpl));
71 EXPECT_CALL(mockFactory, createProgram(_)).WillOnce(Return(programImpl));
72 EXPECT_CALL(mockFactory, createVertexArray(_)).WillOnce(Return(nullptr));
73
74 State state;
75 Caps caps;
76 TextureCapsMap textureCaps;
77 Extensions extensions;
78 Limitations limitations;
79
80 // Set some basic caps.
81 caps.maxElementIndex = 100;
82 caps.maxDrawBuffers = 1;
83 caps.maxColorAttachments = 1;
Jamie Madillc43be722017-07-13 16:22:14 -040084 state.initialize(nullptr, false, true, true, false, false);
Jamie Madille79b1e12015-11-04 16:36:37 -050085
Jamie Madill60ec6ea2016-01-22 15:27:19 -050086 NiceMock<MockTextureImpl> *textureImpl = new NiceMock<MockTextureImpl>();
Olli Etuaho82c47ad2016-04-20 18:28:47 +030087 EXPECT_CALL(mockFactory, createTexture(_)).WillOnce(Return(textureImpl));
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050088 EXPECT_CALL(*textureImpl, setStorage(_, _, _, _, _)).WillOnce(Return(gl::NoError()));
Jamie Madille79b1e12015-11-04 16:36:37 -050089 EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
Jamie Madill60ec6ea2016-01-22 15:27:19 -050090
Olli Etuaho82c47ad2016-04-20 18:28:47 +030091 Texture *texture = new Texture(&mockFactory, 0, GL_TEXTURE_2D);
Jamie Madille79b1e12015-11-04 16:36:37 -050092 texture->addRef();
Jamie Madill8897afa2017-02-06 17:17:23 -050093 texture->setStorage(nullptr, GL_TEXTURE_2D, 1, GL_RGBA8, Extents(1, 1, 0));
Jamie Madille79b1e12015-11-04 16:36:37 -050094
Jiawei-Shao2597fb62016-12-09 16:38:02 +080095 VertexArray *vertexArray = new VertexArray(&mockFactory, 0, 1, 1);
Jamie Madille79b1e12015-11-04 16:36:37 -050096 Framebuffer *framebuffer = new Framebuffer(caps, &mockFactory, 1);
Jamie Madilla02315b2017-02-23 14:14:47 -050097 framebuffer->setAttachment(nullptr, GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::Make2D(0),
98 texture);
Jamie Madille79b1e12015-11-04 16:36:37 -050099
100 Program *program = new Program(&mockFactory, nullptr, 1);
101
102 state.setVertexArrayBinding(vertexArray);
103 state.setDrawFramebufferBinding(framebuffer);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500104 state.setProgram(nullptr, program);
Jamie Madille79b1e12015-11-04 16:36:37 -0500105
Geoff Langce02f082017-02-06 16:46:21 -0500106 NiceMock<MockValidationContext> testContext(nullptr, nullptr, Version(3, 0), &state, caps,
107 textureCaps, extensions, limitations, false);
Jamie Madille79b1e12015-11-04 16:36:37 -0500108
109 // Set the expectation for the validation error here.
Brandon Jones6cad5662017-06-14 13:25:13 -0700110
111 Error expectedError(gl::InvalidOperation() << kErrorExceedsMaxElement);
Jamie Madill437fa652016-05-03 15:13:24 -0400112 EXPECT_CALL(testContext, handleError(expectedError)).Times(1);
Jamie Madille79b1e12015-11-04 16:36:37 -0500113
114 // Call once with maximum index, and once with an excessive index.
115 GLuint indexData[] = {0, 1, static_cast<GLuint>(caps.maxElementIndex - 1),
116 3, 4, static_cast<GLuint>(caps.maxElementIndex)};
Jamie Madill9c9b40a2017-04-26 16:31:57 -0400117 EXPECT_TRUE(
118 ValidateDrawElementsCommon(&testContext, GL_TRIANGLES, 3, GL_UNSIGNED_INT, indexData, 1));
119 EXPECT_FALSE(
120 ValidateDrawElementsCommon(&testContext, GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexData, 2));
Jamie Madille79b1e12015-11-04 16:36:37 -0500121
Jamie Madill4928b7c2017-06-20 12:57:39 -0400122 texture->release(nullptr);
Jamie Madilldaa8c272015-11-18 14:13:55 -0500123
124 state.setVertexArrayBinding(nullptr);
125 state.setDrawFramebufferBinding(nullptr);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500126 state.setProgram(nullptr, nullptr);
Jamie Madilldaa8c272015-11-18 14:13:55 -0500127
Jamie Madill4928b7c2017-06-20 12:57:39 -0400128 vertexArray->onDestroy(nullptr);
129 framebuffer->onDestroy(nullptr);
130 program->onDestroy(nullptr);
Jamie Madille79b1e12015-11-04 16:36:37 -0500131}
132
133} // anonymous namespace