blob: 077d747902152b61019aa1900af32b4d96e43d77 [file] [log] [blame]
Jamie Madill87717702015-04-13 13:50:24 -04001//
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// IndexDataManagerPerfTest:
7// Performance test for index buffer management.
8//
9
10#include "ANGLEPerfTest.h"
11
12#include <gmock/gmock.h>
13
14#include "libANGLE/renderer/d3d/BufferD3D.h"
15#include "libANGLE/renderer/d3d/IndexBuffer.h"
16#include "libANGLE/renderer/d3d/IndexDataManager.h"
17
18using namespace testing;
19
20namespace
21{
22
23class MockIndexBuffer : public rx::IndexBuffer
24{
25 public:
26 MockIndexBuffer(unsigned int bufferSize, GLenum indexType)
27 : mBufferSize(bufferSize),
28 mIndexType(indexType)
29 {
30 }
31
32 MOCK_METHOD3(initialize, gl::Error(unsigned int, GLenum, bool));
33 MOCK_METHOD3(mapBuffer, gl::Error(unsigned int, unsigned int, void**));
34 MOCK_METHOD0(unmapBuffer, gl::Error());
35 MOCK_METHOD0(discard, gl::Error());
36 MOCK_METHOD2(setSize, gl::Error(unsigned int, GLenum));
37
38 // inlined for speed
39 GLenum getIndexType() const override { return mIndexType; }
40 unsigned int getBufferSize() const override { return mBufferSize; }
41
42 private:
43 unsigned int mBufferSize;
44 GLenum mIndexType;
45};
46
47class MockBufferFactoryD3D : public rx::BufferFactoryD3D
48{
49 public:
50 MockBufferFactoryD3D(unsigned int bufferSize, GLenum indexType)
51 : mBufferSize(bufferSize),
52 mIndexType(indexType)
53 {
54 }
55
56 MOCK_METHOD0(createVertexBuffer, rx::VertexBuffer*());
57 MOCK_CONST_METHOD1(getVertexConversionType, rx::VertexConversionType(const gl::VertexFormat &));
58 MOCK_CONST_METHOD1(getVertexComponentType, GLenum(const gl::VertexFormat &));
59
60 // Dependency injection
61 rx::IndexBuffer* createIndexBuffer() override
62 {
63 return new MockIndexBuffer(mBufferSize, mIndexType);
64 }
65
66 private:
67 unsigned int mBufferSize;
68 GLenum mIndexType;
69};
70
71class MockBufferD3D : public rx::BufferD3D
72{
73 public:
74 MockBufferD3D(rx::BufferFactoryD3D *factory, size_t bufferSize)
75 : BufferD3D(factory),
76 mBufferSize(bufferSize)
77 {
78 }
79
80 // BufferImpl
81 MOCK_METHOD3(setData, gl::Error(const void*, size_t, GLenum));
82 MOCK_METHOD3(setSubData, gl::Error(const void*, size_t, size_t));
83 MOCK_METHOD4(copySubData, gl::Error(BufferImpl*, GLintptr, GLintptr, GLsizeiptr));
84 MOCK_METHOD2(map, gl::Error(GLenum, GLvoid **));
85 MOCK_METHOD4(mapRange, gl::Error(size_t, size_t, GLbitfield, GLvoid **));
86 MOCK_METHOD1(unmap, gl::Error(GLboolean *));
87
88 // BufferD3D
89 MOCK_METHOD0(markTransformFeedbackUsage, void());
90
91 // inlined for speed
92 bool supportsDirectBinding() const override { return false; }
93 size_t getSize() const override { return mBufferSize; }
94 gl::Error getData(const uint8_t **) override { return gl::Error(GL_NO_ERROR); }
95
96 private:
97 size_t mBufferSize;
98};
99
100class IndexDataManagerPerfTest : public ANGLEPerfTest
101{
102 public:
103 IndexDataManagerPerfTest();
104
105 void step(float dt, double totalTime) override;
106
107 rx::IndexDataManager mIndexDataManager;
108 GLsizei mIndexCount;
109 unsigned int mBufferSize;
110 MockBufferFactoryD3D mMockFactory;
111 gl::Buffer mIndexBuffer;
112 std::vector<GLshort> mIndexData;
113};
114
115MockBufferD3D *InitMockBufferD3D(MockBufferFactoryD3D *mockFactory, unsigned int bufferSize)
116{
117 MockBufferD3D *mockBufferD3D = new MockBufferD3D(mockFactory, static_cast<size_t>(bufferSize));
118
119 EXPECT_CALL(*mockFactory, createVertexBuffer()).WillOnce(Return(nullptr)).RetiresOnSaturation();
120 mockBufferD3D->initializeStaticData();
121
122 return mockBufferD3D;
123}
124
125IndexDataManagerPerfTest::IndexDataManagerPerfTest()
126 : ANGLEPerfTest("IndexDataManger", "_run"),
127 mIndexDataManager(&mMockFactory, rx::RENDERER_D3D11),
128 mIndexCount(4000),
129 mBufferSize(mIndexCount * 2),
130 mMockFactory(mBufferSize, GL_UNSIGNED_SHORT),
131 mIndexBuffer(InitMockBufferD3D(&mMockFactory, mBufferSize), 1),
132 mIndexData(mIndexCount)
133{
134 for (GLsizei index = 0; index < mIndexCount; ++index)
135 {
136 mIndexData[index] = static_cast<GLshort>(index);
137 }
138}
139
140void IndexDataManagerPerfTest::step(float dt, double totalTime)
141{
142 rx::TranslatedIndexData translatedIndexData;
143
144 for (unsigned int iteration = 0; iteration < 100; ++iteration)
145 {
146 if (!mIndexBuffer.getIndexRangeCache()->findRange(GL_UNSIGNED_SHORT, 0, mIndexCount, &translatedIndexData.indexRange))
147 {
148 translatedIndexData.indexRange = rx::IndexRangeCache::ComputeRange(GL_UNSIGNED_SHORT, &mIndexData[0], mIndexCount);
149 mIndexBuffer.getIndexRangeCache()->addRange(GL_UNSIGNED_SHORT, 0, mIndexCount, translatedIndexData.indexRange);
150 }
151
152 mIndexDataManager.prepareIndexData(GL_UNSIGNED_SHORT, mIndexCount, &mIndexBuffer, nullptr, &translatedIndexData);
153 }
154
155 if (mTimer->getElapsedTime() >= 5.0)
156 {
157 mRunning = false;
158 }
159}
160
161TEST_F(IndexDataManagerPerfTest, Run)
162{
163 run();
164}
165
166}