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
92 {
93 std::vector<eglw::EGLAttrib> d3d1193Attribs =
94 initAttribs(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
95 EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, 9, 3);
96
97 auto *d3d1193Factory = new ANGLENativeDisplayFactory(
98 "angle-d3d11-fl93", "ANGLE D3D11 FL9_3 Display", d3d1193Attribs, &mEvents);
99 m_nativeDisplayFactoryRegistry.registerFactory(d3d1193Factory);
100 }
101 #endif // (DE_OS == DE_OS_WIN32)
102
103 #if defined(ANGLE_USE_GBM) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_WIN32)
104 {
105 std::vector<eglw::EGLAttrib> glesAttribs =
106 initAttribs(EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE);
107
108 auto *glesFactory = new ANGLENativeDisplayFactory("angle-gles", "ANGLE OpenGL ES Display",
109 glesAttribs, &mEvents);
110 m_nativeDisplayFactoryRegistry.registerFactory(glesFactory);
111 }
112 #endif
113
114 {
115 std::vector<eglw::EGLAttrib> glAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE);
116
117 auto *glFactory =
118 new ANGLENativeDisplayFactory("angle-gl", "ANGLE OpenGL Display", glAttribs, &mEvents);
119 m_nativeDisplayFactoryRegistry.registerFactory(glFactory);
120 }
121
122 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_WIN32) || (DE_OS == DE_OS_UNIX)
123 {
124 std::vector<eglw::EGLAttrib> vkAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
125
126 auto *vkFactory = new ANGLENativeDisplayFactory("angle-vulkan", "ANGLE Vulkan Display",
127 vkAttribs, &mEvents);
128 m_nativeDisplayFactoryRegistry.registerFactory(vkFactory);
129 }
130 #endif
131
132 #if (DE_OS == DE_OS_WIN32) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX)
133 {
134 std::vector<eglw::EGLAttrib> swsAttribs = initAttribs(
135 EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE);
136 m_nativeDisplayFactoryRegistry.registerFactory(new ANGLENativeDisplayFactory(
137 "angle-swiftshader", "ANGLE SwiftShader Display", swsAttribs, &mEvents));
138 }
139 #endif
140
141 #if (DE_OS == DE_OS_OSX)
142 {
143 std::vector<eglw::EGLAttrib> mtlAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE);
144
145 auto *mtlFactory = new ANGLENativeDisplayFactory("angle-metal", "ANGLE Metal Display",
146 mtlAttribs, &mEvents);
147 m_nativeDisplayFactoryRegistry.registerFactory(mtlFactory);
148 }
149 #endif
150
151 {
152 std::vector<eglw::EGLAttrib> nullAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE);
153
154 auto *nullFactory = new ANGLENativeDisplayFactory("angle-null", "ANGLE NULL Display",
155 nullAttribs, &mEvents);
156 m_nativeDisplayFactoryRegistry.registerFactory(nullFactory);
157 }
158
159 m_contextFactoryRegistry.registerFactory(
160 new eglu::GLContextFactory(m_nativeDisplayFactoryRegistry));
161
162 // Add Null context type for use in generating case lists
163 m_contextFactoryRegistry.registerFactory(new null::NullGLContextFactory());
164 }
165
~ANGLEPlatform()166 ANGLEPlatform::~ANGLEPlatform() {}
167
processEvents()168 bool ANGLEPlatform::processEvents()
169 {
170 return !mEvents.quitSignaled();
171 }
172
initAttribs(eglw::EGLAttrib type,eglw::EGLAttrib deviceType,eglw::EGLAttrib majorVersion,eglw::EGLAttrib minorVersion)173 std::vector<eglw::EGLAttrib> ANGLEPlatform::initAttribs(eglw::EGLAttrib type,
174 eglw::EGLAttrib deviceType,
175 eglw::EGLAttrib majorVersion,
176 eglw::EGLAttrib minorVersion)
177 {
178 std::vector<eglw::EGLAttrib> attribs;
179
180 attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
181 attribs.push_back(type);
182
183 if (deviceType != EGL_DONT_CARE)
184 {
185 attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
186 attribs.push_back(deviceType);
187 }
188
189 if (majorVersion != EGL_DONT_CARE)
190 {
191 attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
192 attribs.push_back(majorVersion);
193 }
194
195 if (minorVersion != EGL_DONT_CARE)
196 {
197 attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
198 attribs.push_back(minorVersion);
199 }
200
201 if (mPlatformMethods.logError)
202 {
203 static_assert(sizeof(eglw::EGLAttrib) == sizeof(angle::PlatformMethods *),
204 "Unexpected pointer size");
205 attribs.push_back(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX);
206 attribs.push_back(reinterpret_cast<eglw::EGLAttrib>(&mPlatformMethods));
207 }
208
209 if (!mEnableFeatureOverrides.empty())
210 {
211 attribs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
212 attribs.push_back(reinterpret_cast<EGLAttrib>(mEnableFeatureOverrides.data()));
213 }
214
215 attribs.push_back(EGL_NONE);
216 return attribs;
217 }
218 } // namespace tcu
219
220 // Create platform
CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc,uint32_t preRotation)221 tcu::Platform *CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc, uint32_t preRotation)
222 {
223 return new tcu::ANGLEPlatform(logErrorFunc, preRotation);
224 }
225
createPlatform()226 tcu::Platform *createPlatform()
227 {
228 return CreateANGLEPlatform(nullptr, 0);
229 }
230