Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/egl_tests/EGLPresentPathD3D11Test.cpp
1693 views
1
//
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
7
#include "test_utils/ANGLETest.h"
8
9
#include <d3d11.h>
10
#include <cstdint>
11
12
#include "util/OSWindow.h"
13
#include "util/com_utils.h"
14
15
using namespace angle;
16
17
class EGLPresentPathD3D11 : public ANGLETest
18
{
19
protected:
20
EGLPresentPathD3D11()
21
: mDisplay(EGL_NO_DISPLAY),
22
mContext(EGL_NO_CONTEXT),
23
mSurface(EGL_NO_SURFACE),
24
mOffscreenSurfaceD3D11Texture(nullptr),
25
mConfig(0),
26
mOSWindow(nullptr),
27
mWindowWidth(0)
28
{}
29
30
void testSetUp() override
31
{
32
mOSWindow = OSWindow::New();
33
mWindowWidth = 64;
34
mOSWindow->initialize("EGLPresentPathD3D11", mWindowWidth, mWindowWidth);
35
}
36
37
void initializeEGL(bool usePresentPathFast)
38
{
39
int clientVersion = GetParam().majorVersion;
40
41
// Set up EGL Display
42
EGLint displayAttribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,
43
GetParam().getRenderer(),
44
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
45
GetParam().eglParameters.majorVersion,
46
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
47
GetParam().eglParameters.majorVersion,
48
EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
49
usePresentPathFast ? EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE
50
: EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE,
51
EGL_NONE};
52
mDisplay =
53
eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttribs);
54
ASSERT_TRUE(EGL_NO_DISPLAY != mDisplay);
55
ASSERT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
56
57
// Choose the EGL config
58
EGLint numConfigs;
59
EGLint configAttribs[] = {EGL_RED_SIZE,
60
8,
61
EGL_GREEN_SIZE,
62
8,
63
EGL_BLUE_SIZE,
64
8,
65
EGL_ALPHA_SIZE,
66
8,
67
EGL_RENDERABLE_TYPE,
68
clientVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT,
69
EGL_SURFACE_TYPE,
70
EGL_PBUFFER_BIT,
71
EGL_NONE};
72
ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, configAttribs, &mConfig, 1, &numConfigs));
73
ASSERT_EQ(1, numConfigs);
74
75
// Set up the EGL context
76
EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, clientVersion, EGL_NONE};
77
mContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttribs);
78
ASSERT_TRUE(EGL_NO_CONTEXT != mContext);
79
}
80
81
void createWindowSurface()
82
{
83
mSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), nullptr);
84
}
85
86
void createPbufferFromClientBufferSurface()
87
{
88
EGLAttrib device = 0;
89
EGLAttrib angleDevice = 0;
90
91
EXPECT_TRUE(IsEGLClientExtensionEnabled("EGL_EXT_device_query"));
92
93
ASSERT_EGL_TRUE(eglQueryDisplayAttribEXT(mDisplay, EGL_DEVICE_EXT, &angleDevice));
94
ASSERT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
95
EGL_D3D11_DEVICE_ANGLE, &device));
96
ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
97
98
D3D11_TEXTURE2D_DESC textureDesc = {0};
99
textureDesc.Width = mWindowWidth;
100
textureDesc.Height = mWindowWidth;
101
textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
102
textureDesc.MipLevels = 1;
103
textureDesc.ArraySize = 1;
104
textureDesc.SampleDesc.Count = 1;
105
textureDesc.SampleDesc.Quality = 0;
106
textureDesc.Usage = D3D11_USAGE_DEFAULT;
107
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
108
textureDesc.CPUAccessFlags = 0;
109
textureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
110
111
ASSERT_TRUE(SUCCEEDED(
112
d3d11Device->CreateTexture2D(&textureDesc, nullptr, &mOffscreenSurfaceD3D11Texture)));
113
114
IDXGIResource *dxgiResource =
115
DynamicCastComObject<IDXGIResource>(mOffscreenSurfaceD3D11Texture);
116
ASSERT_NE(nullptr, dxgiResource);
117
118
HANDLE sharedHandle = 0;
119
ASSERT_TRUE(SUCCEEDED(dxgiResource->GetSharedHandle(&sharedHandle)));
120
SafeRelease(dxgiResource);
121
122
EGLint pBufferAttributes[] = {EGL_WIDTH, mWindowWidth, EGL_HEIGHT,
123
mWindowWidth, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
124
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_NONE};
125
126
mSurface = eglCreatePbufferFromClientBuffer(mDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
127
sharedHandle, mConfig, pBufferAttributes);
128
ASSERT_TRUE(EGL_NO_SURFACE != mSurface);
129
}
130
131
void makeCurrent() { ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)); }
132
133
void testTearDown() override
134
{
135
SafeRelease(mOffscreenSurfaceD3D11Texture);
136
137
if (mDisplay != EGL_NO_DISPLAY)
138
{
139
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
140
141
if (mSurface != EGL_NO_SURFACE)
142
{
143
eglDestroySurface(mDisplay, mSurface);
144
mSurface = EGL_NO_SURFACE;
145
}
146
147
if (mContext != EGL_NO_CONTEXT)
148
{
149
ASSERT_EGL_TRUE(
150
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
151
eglDestroyContext(mDisplay, mContext);
152
mContext = EGL_NO_CONTEXT;
153
}
154
155
eglTerminate(mDisplay);
156
mDisplay = EGL_NO_DISPLAY;
157
}
158
159
mOSWindow->destroy();
160
OSWindow::Delete(&mOSWindow);
161
}
162
163
void drawQuadUsingGL()
164
{
165
GLuint m2DProgram;
166
GLint mTexture2DUniformLocation;
167
168
constexpr char kVS[] =
169
R"(precision highp float;
170
attribute vec4 position;
171
varying vec2 texcoord;
172
173
void main()
174
{
175
gl_Position = vec4(position.xy, 0.0, 1.0);
176
texcoord = (position.xy * 0.5) + 0.5;
177
})";
178
179
constexpr char kFS[] =
180
R"(precision highp float;
181
uniform sampler2D tex;
182
varying vec2 texcoord;
183
184
void main()
185
{
186
gl_FragColor = texture2D(tex, texcoord);
187
})";
188
189
m2DProgram = CompileProgram(kVS, kFS);
190
mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex");
191
192
uint8_t textureInitData[16] = {
193
255, 0, 0, 255, // Red
194
0, 255, 0, 255, // Green
195
0, 0, 255, 255, // Blue
196
255, 255, 0, 255 // Red + Green
197
};
198
199
// Create a simple RGBA texture
200
GLuint tex = 0;
201
glGenTextures(1, &tex);
202
glBindTexture(GL_TEXTURE_2D, tex);
203
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
204
textureInitData);
205
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
206
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
207
ASSERT_GL_NO_ERROR();
208
209
// Draw a quad using the texture
210
glClear(GL_COLOR_BUFFER_BIT);
211
glUseProgram(m2DProgram);
212
glUniform1i(mTexture2DUniformLocation, 0);
213
214
GLint positionLocation = glGetAttribLocation(m2DProgram, "position");
215
glUseProgram(m2DProgram);
216
const GLfloat vertices[] = {
217
-1.0f, 1.0f, 0.5f, -1.0f, -1.0f, 0.5f, 1.0f, -1.0f, 0.5f,
218
-1.0f, 1.0f, 0.5f, 1.0f, -1.0f, 0.5f, 1.0f, 1.0f, 0.5f,
219
};
220
221
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
222
glEnableVertexAttribArray(positionLocation);
223
224
glDrawArrays(GL_TRIANGLES, 0, 6);
225
ASSERT_GL_NO_ERROR();
226
227
glDeleteProgram(m2DProgram);
228
}
229
230
void checkPixelsUsingGL()
231
{
232
// Note that the texture is in BGRA format
233
EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); // Red
234
EXPECT_PIXEL_EQ(mWindowWidth - 1, 0, 0, 255, 0, 255); // Green
235
EXPECT_PIXEL_EQ(0, mWindowWidth - 1, 0, 0, 255, 255); // Blue
236
EXPECT_PIXEL_EQ(mWindowWidth - 1, mWindowWidth - 1, 255, 255, 0, 255); // Red + green
237
}
238
239
void checkPixelsUsingD3D(bool usingPresentPathFast)
240
{
241
ASSERT_NE(nullptr, mOffscreenSurfaceD3D11Texture);
242
243
D3D11_TEXTURE2D_DESC textureDesc = {0};
244
ID3D11Device *device;
245
ID3D11DeviceContext *context;
246
mOffscreenSurfaceD3D11Texture->GetDesc(&textureDesc);
247
mOffscreenSurfaceD3D11Texture->GetDevice(&device);
248
device->GetImmediateContext(&context);
249
ASSERT_NE(nullptr, device);
250
ASSERT_NE(nullptr, context);
251
252
textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
253
textureDesc.Usage = D3D11_USAGE_STAGING;
254
textureDesc.BindFlags = 0;
255
textureDesc.MiscFlags = 0;
256
ID3D11Texture2D *cpuTexture = nullptr;
257
ASSERT_TRUE(SUCCEEDED(device->CreateTexture2D(&textureDesc, nullptr, &cpuTexture)));
258
259
context->CopyResource(cpuTexture, mOffscreenSurfaceD3D11Texture);
260
261
D3D11_MAPPED_SUBRESOURCE mappedSubresource;
262
context->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mappedSubresource);
263
ASSERT_EQ(static_cast<UINT>(mWindowWidth * 4), mappedSubresource.RowPitch);
264
ASSERT_EQ(static_cast<UINT>(mWindowWidth * mWindowWidth * 4), mappedSubresource.DepthPitch);
265
266
angle::GLColor *byteData = reinterpret_cast<angle::GLColor *>(mappedSubresource.pData);
267
268
// Note that the texture is in BGRA format, although the GLColor struct is RGBA
269
GLColor expectedTopLeftPixel = GLColor(0, 0, 255, 255); // Red
270
GLColor expectedTopRightPixel = GLColor(0, 255, 0, 255); // Green
271
GLColor expectedBottomLeftPixel = GLColor(255, 0, 0, 255); // Blue
272
GLColor expectedBottomRightPixel = GLColor(0, 255, 255, 255); // Red + Green
273
274
if (usingPresentPathFast)
275
{
276
// Invert the expected values
277
GLColor tempTopLeft = expectedTopLeftPixel;
278
GLColor tempTopRight = expectedTopRightPixel;
279
expectedTopLeftPixel = expectedBottomLeftPixel;
280
expectedTopRightPixel = expectedBottomRightPixel;
281
expectedBottomLeftPixel = tempTopLeft;
282
expectedBottomRightPixel = tempTopRight;
283
}
284
285
EXPECT_EQ(expectedTopLeftPixel, byteData[0]);
286
EXPECT_EQ(expectedTopRightPixel, byteData[(mWindowWidth - 1)]);
287
EXPECT_EQ(expectedBottomLeftPixel, byteData[(mWindowWidth - 1) * mWindowWidth]);
288
EXPECT_EQ(expectedBottomRightPixel,
289
byteData[(mWindowWidth - 1) * mWindowWidth + (mWindowWidth - 1)]);
290
291
context->Unmap(cpuTexture, 0);
292
SafeRelease(cpuTexture);
293
SafeRelease(device);
294
SafeRelease(context);
295
}
296
297
EGLDisplay mDisplay;
298
EGLContext mContext;
299
EGLSurface mSurface;
300
ID3D11Texture2D *mOffscreenSurfaceD3D11Texture;
301
EGLConfig mConfig;
302
OSWindow *mOSWindow;
303
GLint mWindowWidth;
304
};
305
306
// Test that rendering basic content onto a window surface when present path fast
307
// is enabled works as expected
308
TEST_P(EGLPresentPathD3D11, WindowPresentPathFast)
309
{
310
initializeEGL(true);
311
createWindowSurface();
312
makeCurrent();
313
314
drawQuadUsingGL();
315
316
checkPixelsUsingGL();
317
}
318
319
// Test that rendering basic content onto a client buffer surface when present path fast
320
// works as expected, and is also oriented the correct way around
321
TEST_P(EGLPresentPathD3D11, ClientBufferPresentPathFast)
322
{
323
initializeEGL(true);
324
createPbufferFromClientBufferSurface();
325
makeCurrent();
326
327
drawQuadUsingGL();
328
329
checkPixelsUsingGL();
330
checkPixelsUsingD3D(true);
331
}
332
333
// Test that rendering basic content onto a window surface when present path fast
334
// is disabled works as expected
335
TEST_P(EGLPresentPathD3D11, WindowPresentPathCopy)
336
{
337
initializeEGL(false);
338
createWindowSurface();
339
makeCurrent();
340
341
drawQuadUsingGL();
342
343
checkPixelsUsingGL();
344
}
345
346
// Test that rendering basic content onto a client buffer surface when present path
347
// fast is disabled works as expected, and is also oriented the correct way around
348
TEST_P(EGLPresentPathD3D11, ClientBufferPresentPathCopy)
349
{
350
initializeEGL(false);
351
createPbufferFromClientBufferSurface();
352
makeCurrent();
353
354
drawQuadUsingGL();
355
356
checkPixelsUsingGL();
357
checkPixelsUsingD3D(false);
358
}
359
360
ANGLE_INSTANTIATE_TEST(EGLPresentPathD3D11, WithNoFixture(ES2_D3D11()));
361
362