Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/egl_tests/EGLProgramCacheControlTest.cpp
1693 views
1
//
2
// Copyright 2017 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
// EGLProgramCacheControlTest:
7
// Unit tests for the EGL_ANGLE_program_cache_control extension.
8
9
#include "common/angleutils.h"
10
#include "test_utils/ANGLETest.h"
11
#include "test_utils/gl_raii.h"
12
#include "util/EGLWindow.h"
13
14
using namespace angle;
15
16
constexpr EGLint kEnabledCacheSize = 0x10000;
17
constexpr char kEGLExtName[] = "EGL_ANGLE_program_cache_control";
18
19
void TestCacheProgram(PlatformMethods *platform,
20
const ProgramKeyType &key,
21
size_t programSize,
22
const uint8_t *programBytes);
23
24
class EGLProgramCacheControlTest : public ANGLETest
25
{
26
public:
27
void onCache(const ProgramKeyType &key, size_t programSize, const uint8_t *programBytes)
28
{
29
mCachedKey = key;
30
mCachedBinary.assign(&programBytes[0], &programBytes[programSize]);
31
}
32
33
protected:
34
EGLProgramCacheControlTest()
35
{
36
// Test flakiness was noticed when reusing displays.
37
forceNewDisplay();
38
setDeferContextInit(true);
39
setContextProgramCacheEnabled(true);
40
gDefaultPlatformMethods.cacheProgram = TestCacheProgram;
41
}
42
43
void testSetUp() override
44
{
45
if (extensionAvailable())
46
{
47
EGLDisplay display = getEGLWindow()->getDisplay();
48
eglProgramCacheResizeANGLE(display, kEnabledCacheSize, EGL_PROGRAM_CACHE_RESIZE_ANGLE);
49
ASSERT_EGL_SUCCESS();
50
}
51
52
ASSERT_TRUE(getEGLWindow()->initializeContext());
53
}
54
55
void testTearDown() override { gDefaultPlatformMethods.cacheProgram = DefaultCacheProgram; }
56
57
bool extensionAvailable()
58
{
59
EGLDisplay display = getEGLWindow()->getDisplay();
60
return IsEGLDisplayExtensionEnabled(display, kEGLExtName);
61
}
62
63
bool programBinaryAvailable()
64
{
65
return (getClientMajorVersion() >= 3 || IsGLExtensionEnabled("GL_OES_get_program_binary"));
66
}
67
68
ProgramKeyType mCachedKey;
69
std::vector<uint8_t> mCachedBinary;
70
};
71
72
void TestCacheProgram(PlatformMethods *platform,
73
const ProgramKeyType &key,
74
size_t programSize,
75
const uint8_t *programBytes)
76
{
77
auto *testPlatformContext = static_cast<TestPlatformContext *>(platform->context);
78
auto *testCase =
79
reinterpret_cast<EGLProgramCacheControlTest *>(testPlatformContext->currentTest);
80
testCase->onCache(key, programSize, programBytes);
81
}
82
83
// Tests error conditions of the APIs.
84
TEST_P(EGLProgramCacheControlTest, NegativeAPI)
85
{
86
ANGLE_SKIP_TEST_IF(!extensionAvailable());
87
88
constexpr char kDefaultKey[] = "defaultMakeItLongEnough";
89
constexpr char kDefaultBinary[] = "defaultMakeItLongEnough";
90
constexpr EGLint kDefaultKeySize = static_cast<EGLint>(ArraySize(kDefaultKey));
91
constexpr EGLint kDefaultBinarySize = static_cast<EGLint>(ArraySize(kDefaultBinary));
92
93
// Test that passing an invalid display to the entry point methods fails.
94
eglProgramCacheGetAttribANGLE(EGL_NO_DISPLAY, EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE);
95
EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
96
97
eglProgramCachePopulateANGLE(EGL_NO_DISPLAY, kDefaultKey, kDefaultKeySize, kDefaultBinary,
98
kDefaultBinarySize);
99
EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
100
101
EGLint tempKeySize = 0;
102
EGLint tempBinarySize = 0;
103
eglProgramCacheQueryANGLE(EGL_NO_DISPLAY, 0, nullptr, &tempKeySize, nullptr, &tempBinarySize);
104
EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
105
106
eglProgramCacheResizeANGLE(EGL_NO_DISPLAY, 0, EGL_PROGRAM_CACHE_TRIM_ANGLE);
107
EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
108
109
// Test querying properties with bad parameters.
110
EGLDisplay display = getEGLWindow()->getDisplay();
111
eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_RESIZE_ANGLE);
112
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
113
114
// Test populating with invalid parameters.
115
EGLint keySize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE);
116
EXPECT_GT(kDefaultKeySize, keySize);
117
eglProgramCachePopulateANGLE(display, kDefaultKey, keySize + 1, kDefaultBinary,
118
kDefaultBinarySize);
119
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
120
121
eglProgramCachePopulateANGLE(display, kDefaultKey, keySize, kDefaultBinary, -1);
122
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
123
124
eglProgramCachePopulateANGLE(display, nullptr, keySize, kDefaultBinary, kDefaultBinarySize);
125
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
126
127
eglProgramCachePopulateANGLE(display, kDefaultKey, keySize, nullptr, kDefaultBinarySize);
128
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
129
130
// Test querying cache entries with invalid parameters.
131
eglProgramCachePopulateANGLE(display, kDefaultKey, keySize, kDefaultBinary, kDefaultBinarySize);
132
ASSERT_EGL_SUCCESS();
133
134
EGLint cacheSize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_SIZE_ANGLE);
135
ASSERT_EQ(1, cacheSize);
136
137
eglProgramCacheQueryANGLE(display, -1, nullptr, &tempKeySize, nullptr, &tempBinarySize);
138
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
139
140
eglProgramCacheQueryANGLE(display, 1, nullptr, &tempKeySize, nullptr, &tempBinarySize);
141
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
142
143
eglProgramCacheQueryANGLE(display, 0, nullptr, nullptr, nullptr, &tempBinarySize);
144
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
145
146
eglProgramCacheQueryANGLE(display, 0, nullptr, &tempKeySize, nullptr, nullptr);
147
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
148
149
eglProgramCacheQueryANGLE(display, 0, nullptr, &tempKeySize, nullptr, &tempBinarySize);
150
ASSERT_EGL_SUCCESS();
151
ASSERT_EQ(keySize, tempKeySize);
152
ASSERT_EQ(kDefaultBinarySize, tempBinarySize);
153
154
std::vector<uint8_t> tempKey(tempKeySize + 5);
155
std::vector<uint8_t> tempBinary(tempBinarySize + 5);
156
157
tempKeySize--;
158
159
eglProgramCacheQueryANGLE(display, 0, tempKey.data(), &tempKeySize, tempBinary.data(),
160
&tempBinarySize);
161
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
162
163
tempKeySize++;
164
tempBinarySize--;
165
166
eglProgramCacheQueryANGLE(display, 0, tempKey.data(), &tempKeySize, tempBinary.data(),
167
&tempBinarySize);
168
EXPECT_EGL_ERROR(EGL_BAD_ACCESS);
169
170
// Test resizing with invalid parameters.
171
eglProgramCacheResizeANGLE(display, -1, EGL_PROGRAM_CACHE_TRIM_ANGLE);
172
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
173
174
eglProgramCacheResizeANGLE(display, 0, EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE);
175
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
176
}
177
178
// Tests a basic use case.
179
TEST_P(EGLProgramCacheControlTest, SaveAndReload)
180
{
181
ANGLE_SKIP_TEST_IF(!extensionAvailable() || !programBinaryAvailable());
182
183
constexpr char kVS[] = "attribute vec4 position; void main() { gl_Position = position; }";
184
constexpr char kFS[] = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
185
186
// Link a program, which will miss the cache.
187
{
188
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
189
glClear(GL_COLOR_BUFFER_BIT);
190
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
191
192
ANGLE_GL_PROGRAM(program, kVS, kFS);
193
drawQuad(program, "position", 0.5f);
194
EXPECT_GL_NO_ERROR();
195
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
196
}
197
198
EGLDisplay display = getEGLWindow()->getDisplay();
199
EGLint cacheSize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_SIZE_ANGLE);
200
EXPECT_EQ(1, cacheSize);
201
202
EGLint keySize = 0;
203
EGLint binarySize = 0;
204
eglProgramCacheQueryANGLE(display, 0, nullptr, &keySize, nullptr, &binarySize);
205
EXPECT_EQ(static_cast<EGLint>(mCachedKey.size()), keySize);
206
ASSERT_EGL_SUCCESS();
207
208
ProgramKeyType keyBuffer;
209
std::vector<uint8_t> binaryBuffer(binarySize);
210
eglProgramCacheQueryANGLE(display, 0, keyBuffer.data(), &keySize, binaryBuffer.data(),
211
&binarySize);
212
ASSERT_EGL_SUCCESS();
213
214
EXPECT_EQ(mCachedKey, keyBuffer);
215
EXPECT_EQ(mCachedBinary, binaryBuffer);
216
217
// Restart EGL and GL.
218
recreateTestFixture();
219
220
// Warm up the cache.
221
EGLint newCacheSize = eglProgramCacheGetAttribANGLE(display, EGL_PROGRAM_CACHE_SIZE_ANGLE);
222
EXPECT_EQ(0, newCacheSize);
223
eglProgramCachePopulateANGLE(display, keyBuffer.data(), keySize, binaryBuffer.data(),
224
binarySize);
225
226
mCachedBinary.clear();
227
228
// Link a program, which will hit the cache.
229
{
230
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
231
glClear(GL_COLOR_BUFFER_BIT);
232
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
233
234
ANGLE_GL_PROGRAM(program, kVS, kFS);
235
drawQuad(program, "position", 0.5f);
236
EXPECT_GL_NO_ERROR();
237
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
238
}
239
240
// Verify no new shader was compiled.
241
EXPECT_TRUE(mCachedBinary.empty());
242
}
243
244
// Tests that trying to link a program without correct shaders doesn't buggily call the cache.
245
TEST_P(EGLProgramCacheControlTest, LinkProgramWithBadShaders)
246
{
247
ANGLE_SKIP_TEST_IF(!extensionAvailable());
248
249
GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
250
251
GLuint program = glCreateProgram();
252
glAttachShader(program, shader);
253
glLinkProgram(program);
254
255
GLint linkStatus = 0;
256
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
257
EXPECT_GL_FALSE(linkStatus);
258
EXPECT_GL_NO_ERROR();
259
260
glDeleteShader(shader);
261
glDeleteProgram(program);
262
}
263
264
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLProgramCacheControlTest);
265
ANGLE_INSTANTIATE_TEST(EGLProgramCacheControlTest,
266
ES2_D3D9(),
267
ES2_D3D11(),
268
ES2_OPENGL(),
269
ES2_VULKAN());
270
271