Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/egl_tests/EGLSyncControlTest.cpp
1693 views
1
//
2
// Copyright 2016 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
7
// EGLSyncControlTest.cpp:
8
// Tests pertaining to eglGetSyncValuesCHROMIUM.
9
10
#include <d3d11.h>
11
12
#include "test_utils/ANGLETest.h"
13
#include "util/OSWindow.h"
14
#include "util/com_utils.h"
15
16
using namespace angle;
17
18
class EGLSyncControlTest : public testing::Test
19
{
20
protected:
21
EGLSyncControlTest() {}
22
23
void SetUp() override
24
{
25
mD3D11Module = LoadLibrary(TEXT("d3d11.dll"));
26
if (mD3D11Module == nullptr)
27
{
28
std::cout << "Unable to LoadLibrary D3D11" << std::endl;
29
return;
30
}
31
32
mD3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
33
GetProcAddress(mD3D11Module, "D3D11CreateDevice"));
34
if (mD3D11CreateDevice == nullptr)
35
{
36
std::cout << "Could not retrieve D3D11CreateDevice from d3d11.dll" << std::endl;
37
return;
38
}
39
40
mD3D11Available = true;
41
42
const char *extensionString =
43
static_cast<const char *>(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));
44
if (strstr(extensionString, "EGL_ANGLE_device_creation"))
45
{
46
if (strstr(extensionString, "EGL_ANGLE_device_creation_d3d11"))
47
{
48
mDeviceCreationD3D11ExtAvailable = true;
49
}
50
}
51
}
52
53
void TearDown() override
54
{
55
SafeRelease(mDevice);
56
SafeRelease(mDeviceContext);
57
58
OSWindow::Delete(&mOSWindow);
59
60
if (mSurface != EGL_NO_SURFACE)
61
{
62
eglDestroySurface(mDisplay, mSurface);
63
mSurface = EGL_NO_SURFACE;
64
}
65
66
if (mContext != EGL_NO_CONTEXT)
67
{
68
eglDestroyContext(mDisplay, mContext);
69
mContext = EGL_NO_CONTEXT;
70
}
71
72
if (mDisplay != EGL_NO_DISPLAY)
73
{
74
eglTerminate(mDisplay);
75
mDisplay = EGL_NO_DISPLAY;
76
}
77
}
78
79
void CreateD3D11Device()
80
{
81
ASSERT_TRUE(mD3D11Available);
82
ASSERT_EQ(nullptr, mDevice); // The device shouldn't be created twice
83
84
HRESULT hr =
85
mD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, 0, nullptr, 0,
86
D3D11_SDK_VERSION, &mDevice, &mFeatureLevel, &mDeviceContext);
87
88
ASSERT_TRUE(SUCCEEDED(hr));
89
}
90
91
void InitializeDisplay()
92
{
93
EGLint displayAttribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,
94
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
95
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
96
EGL_DONT_CARE,
97
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE,
98
EGL_DONT_CARE,
99
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
100
EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,
101
EGL_NONE};
102
103
// Create an OS Window
104
mOSWindow = OSWindow::New();
105
mOSWindow->initialize("EGLSyncControlTest", 64, 64);
106
mOSWindow->setVisible(true);
107
108
// Create an EGLDisplay using the EGLDevice
109
mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
110
reinterpret_cast<void *>(mOSWindow->getNativeDisplay()),
111
displayAttribs);
112
ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
113
114
EGLint majorVersion, minorVersion;
115
ASSERT_TRUE(eglInitialize(mDisplay, &majorVersion, &minorVersion) == EGL_TRUE);
116
}
117
118
void CreateWindowSurface()
119
{
120
eglBindAPI(EGL_OPENGL_ES_API);
121
ASSERT_EGL_SUCCESS();
122
123
// Choose a config
124
const EGLint configAttributes[] = {EGL_NONE};
125
126
EGLint configCount = 0;
127
ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount));
128
129
const EGLint surfaceAttributes[] = {EGL_DIRECT_COMPOSITION_ANGLE, EGL_TRUE, EGL_NONE};
130
131
// Create window surface
132
mSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(),
133
surfaceAttributes);
134
if (mSurface == nullptr)
135
{
136
std::cout << "Unable to create window surface with Direct Composition" << std::endl;
137
return;
138
}
139
140
mDirectCompositionSurfaceAvailable = true;
141
142
// Create EGL context
143
EGLint contextAttibutes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
144
145
mContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);
146
ASSERT_EGL_SUCCESS();
147
148
// Make the surface current
149
eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
150
ASSERT_EGL_SUCCESS();
151
}
152
153
bool mD3D11Available = false;
154
HMODULE mD3D11Module = nullptr;
155
PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice = nullptr;
156
157
ID3D11Device *mDevice = nullptr;
158
ID3D11DeviceContext *mDeviceContext = nullptr;
159
D3D_FEATURE_LEVEL mFeatureLevel;
160
161
bool mDeviceCreationD3D11ExtAvailable = false;
162
163
bool mDirectCompositionSurfaceAvailable = false;
164
165
OSWindow *mOSWindow = nullptr;
166
167
EGLDisplay mDisplay = EGL_NO_DISPLAY;
168
EGLSurface mSurface = EGL_NO_SURFACE;
169
EGLContext mContext = EGL_NO_CONTEXT;
170
EGLConfig mConfig = 0;
171
};
172
173
// Basic test for eglGetSyncValuesCHROMIUM extension. Verifies that eglGetSyncValuesCHROMIUM
174
// can be called on DX11 with direct composition and that it returns reasonable enough values.
175
TEST_F(EGLSyncControlTest, DISABLED_SyncValuesTest)
176
{
177
static const DWORD kPollInterval = 10;
178
static const int kNumPollIterations = 100;
179
180
if (!mD3D11Available)
181
{
182
std::cout << "D3D11 not available, skipping test" << std::endl;
183
return;
184
}
185
186
CreateD3D11Device();
187
InitializeDisplay();
188
CreateWindowSurface();
189
190
if (!mDirectCompositionSurfaceAvailable)
191
{
192
std::cout << "Direct Composition surface not available, skipping test" << std::endl;
193
return;
194
}
195
196
const char *extensionString =
197
static_cast<const char *>(eglQueryString(mDisplay, EGL_EXTENSIONS));
198
ASSERT_TRUE(strstr(extensionString, "EGL_CHROMIUM_sync_control"));
199
200
EGLuint64KHR ust = 0, msc = 0, sbc = 0;
201
// It appears there is a race condition so the very first call to eglGetSyncValuesCHROMIUM
202
// can fail within D3D with DXGI_ERROR_FRAME_STATISTICS_DISJOINT.
203
// Should that be handled inside eglGetSyncValuesCHROMIUM?
204
eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust, &msc, &sbc);
205
206
ASSERT_EGL_TRUE(eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust, &msc, &sbc));
207
// Initial msc and sbc value should be true. Initial ust value is unspecified.
208
ASSERT_EQ(0ull, msc);
209
ASSERT_EQ(0ull, sbc);
210
211
// Perform some very basic rendering.
212
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
213
glClear(GL_COLOR_BUFFER_BIT);
214
ASSERT_GL_NO_ERROR();
215
216
ASSERT_EGL_TRUE(eglSwapBuffers(mDisplay, mSurface));
217
218
// Poll until sbc value increases. Normally it should change within 16-17 ms.
219
for (int i = 0; i < kNumPollIterations; i++)
220
{
221
::Sleep(kPollInterval);
222
ASSERT_EGL_TRUE(eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust, &msc, &sbc));
223
if (sbc > 0)
224
break;
225
}
226
227
// sbc should change to 1. msc and ust to some non-zero values.
228
ASSERT_EQ(1ull, sbc);
229
ASSERT_GT(ust, 0ull);
230
ASSERT_GT(msc, 0ull);
231
232
// Perform more rendering.
233
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
234
glClear(GL_COLOR_BUFFER_BIT);
235
ASSERT_GL_NO_ERROR();
236
237
ASSERT_EGL_TRUE(eglSwapBuffers(mDisplay, mSurface));
238
239
// Poll until sbc value increases. Normally it should change within 16-17 ms.
240
EGLuint64KHR ust2 = 0, msc2 = 0, sbc2 = 0;
241
for (int i = 0; i < kNumPollIterations; i++)
242
{
243
::Sleep(kPollInterval);
244
ASSERT_EGL_TRUE(eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust2, &msc2, &sbc2));
245
if (sbc2 > sbc)
246
break;
247
}
248
249
// sbc2 should be 2. msc2 and ust2 should be greater than previous msc and ust values.
250
ASSERT_EQ(2ull, sbc2);
251
ASSERT_GT(ust2, ust);
252
ASSERT_GT(msc2, msc);
253
}
254
255