1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21 #include "tcuANGLEPlatform.h"
22
23 #include <EGL/egl.h>
24 #include <EGL/eglext.h>
25
26 #include "egluGLContextFactory.hpp"
27 #include "tcuANGLENativeDisplayFactory.h"
28 #include "tcuNullContextFactory.hpp"
29 #include "util/test_utils.h"
30
31 static_assert(EGL_DONT_CARE == -1, "Unexpected value for EGL_DONT_CARE");
32
33 namespace tcu
34 {
ANGLEPlatform(angle::LogErrorFunc logErrorFunc,uint32_t preRotation)35 ANGLEPlatform::ANGLEPlatform(angle::LogErrorFunc logErrorFunc, uint32_t preRotation)
36 {
37 angle::SetLowPriorityProcess();
38
39 mPlatformMethods.logError = logErrorFunc;
40
41 // Enable non-conformant ES versions and extensions for testing. Our test expectations would
42 // suppress failing tests, but allowing continuous testing of the pieces that are implemented.
43 mEnableFeatureOverrides.push_back("exposeNonConformantExtensionsAndVersions");
44
45 // Create pre-rotation attributes.
46 switch (preRotation)
47 {
48 case 90:
49 mEnableFeatureOverrides.push_back("emulatedPrerotation90");
50 break;
51 case 180:
52 mEnableFeatureOverrides.push_back("emulatedPrerotation180");
53 break;
54 case 270:
55 mEnableFeatureOverrides.push_back("emulatedPrerotation270");
56 break;
57 default:
58 break;
59 }
60
61 mEnableFeatureOverrides.push_back(nullptr);
62
63 #if (DE_OS == DE_OS_WIN32)
64 {
65 std::vector<eglw::EGLAttrib> d3d11Attribs = initAttribs(
66 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE);
67
68 auto *d3d11Factory = new ANGLENativeDisplayFactory("angle-d3d11", "ANGLE D3D11 Display",
69 d3d11Attribs, &mEvents);
70 m_nativeDisplayFactoryRegistry.registerFactory(d3d11Factory);
71 }
72
73 {
74 std::vector<eglw::EGLAttrib> d3d11Attribs =
75 initAttribs(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
76 EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE);
77
78 auto *d3d11Factory = new ANGLENativeDisplayFactory(
79 "angle-d3d11-ref", "ANGLE D3D11 Reference Display", d3d11Attribs, &mEvents);
80 m_nativeDisplayFactoryRegistry.registerFactory(d3d11Factory);
81 }
82
83 {
84 std::vector<eglw::EGLAttrib> d3d9Attribs = initAttribs(
85 EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE);
86
87 auto *d3d9Factory = new ANGLENativeDisplayFactory("angle-d3d9", "ANGLE D3D9 Display",
88 d3d9Attribs, &mEvents);
89 m_nativeDisplayFactoryRegistry.registerFactory(d3d9Factory);
90 }
91 #endif // (DE_OS == DE_OS_WIN32)
92
93 #if defined(ANGLE_USE_GBM) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_WIN32)
94 {
95 std::vector<eglw::EGLAttrib> glesAttribs =
96 initAttribs(EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE);
97
98 auto *glesFactory = new ANGLENativeDisplayFactory("angle-gles", "ANGLE OpenGL ES Display",
99 glesAttribs, &mEvents);
100 m_nativeDisplayFactoryRegistry.registerFactory(glesFactory);
101 }
102 #endif
103
104 {
105 std::vector<eglw::EGLAttrib> glAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE);
106
107 auto *glFactory =
108 new ANGLENativeDisplayFactory("angle-gl", "ANGLE OpenGL Display", glAttribs, &mEvents);
109 m_nativeDisplayFactoryRegistry.registerFactory(glFactory);
110 }
111
112 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_WIN32) || (DE_OS == DE_OS_UNIX)
113 {
114 std::vector<eglw::EGLAttrib> vkAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
115
116 auto *vkFactory = new ANGLENativeDisplayFactory("angle-vulkan", "ANGLE Vulkan Display",
117 vkAttribs, &mEvents);
118 m_nativeDisplayFactoryRegistry.registerFactory(vkFactory);
119 }
120 #endif
121
122 #if (DE_OS == DE_OS_WIN32) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX)
123 {
124 std::vector<eglw::EGLAttrib> swsAttribs = initAttribs(
125 EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE);
126 m_nativeDisplayFactoryRegistry.registerFactory(new ANGLENativeDisplayFactory(
127 "angle-swiftshader", "ANGLE SwiftShader Display", swsAttribs, &mEvents));
128 }
129 #endif
130
131 #if (DE_OS == DE_OS_OSX)
132 {
133 std::vector<eglw::EGLAttrib> mtlAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE);
134
135 auto *mtlFactory = new ANGLENativeDisplayFactory("angle-metal", "ANGLE Metal Display",
136 mtlAttribs, &mEvents);
137 m_nativeDisplayFactoryRegistry.registerFactory(mtlFactory);
138 }
139 #endif
140
141 {
142 std::vector<eglw::EGLAttrib> nullAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE);
143
144 auto *nullFactory = new ANGLENativeDisplayFactory("angle-null", "ANGLE NULL Display",
145 nullAttribs, &mEvents);
146 m_nativeDisplayFactoryRegistry.registerFactory(nullFactory);
147 }
148
149 m_contextFactoryRegistry.registerFactory(
150 new eglu::GLContextFactory(m_nativeDisplayFactoryRegistry));
151
152 // Add Null context type for use in generating case lists
153 m_contextFactoryRegistry.registerFactory(new null::NullGLContextFactory());
154 }
155
~ANGLEPlatform()156 ANGLEPlatform::~ANGLEPlatform() {}
157
processEvents()158 bool ANGLEPlatform::processEvents()
159 {
160 return !mEvents.quitSignaled();
161 }
162
initAttribs(eglw::EGLAttrib type,eglw::EGLAttrib deviceType,eglw::EGLAttrib majorVersion,eglw::EGLAttrib minorVersion)163 std::vector<eglw::EGLAttrib> ANGLEPlatform::initAttribs(eglw::EGLAttrib type,
164 eglw::EGLAttrib deviceType,
165 eglw::EGLAttrib majorVersion,
166 eglw::EGLAttrib minorVersion)
167 {
168 std::vector<eglw::EGLAttrib> attribs;
169
170 attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
171 attribs.push_back(type);
172
173 if (deviceType != EGL_DONT_CARE)
174 {
175 attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
176 attribs.push_back(deviceType);
177 }
178
179 if (majorVersion != EGL_DONT_CARE)
180 {
181 attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
182 attribs.push_back(majorVersion);
183 }
184
185 if (minorVersion != EGL_DONT_CARE)
186 {
187 attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
188 attribs.push_back(minorVersion);
189 }
190
191 if (mPlatformMethods.logError)
192 {
193 static_assert(sizeof(eglw::EGLAttrib) == sizeof(angle::PlatformMethods *),
194 "Unexpected pointer size");
195 attribs.push_back(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX);
196 attribs.push_back(reinterpret_cast<eglw::EGLAttrib>(&mPlatformMethods));
197 }
198
199 if (!mEnableFeatureOverrides.empty())
200 {
201 attribs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
202 attribs.push_back(reinterpret_cast<EGLAttrib>(mEnableFeatureOverrides.data()));
203 }
204
205 attribs.push_back(EGL_NONE);
206 return attribs;
207 }
208 } // namespace tcu
209
210 // Create platform
CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc,uint32_t preRotation)211 tcu::Platform *CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc, uint32_t preRotation)
212 {
213 return new tcu::ANGLEPlatform(logErrorFunc, preRotation);
214 }
215
createPlatform()216 tcu::Platform *createPlatform()
217 {
218 return CreateANGLEPlatform(nullptr, 0);
219 }
220