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 // Create pre-rotation attributes.
42 switch (preRotation)
43 {
44 case 90:
45 mEnableFeatureOverrides.push_back("emulated_prerotation_90");
46 break;
47 case 180:
48 mEnableFeatureOverrides.push_back("emulated_prerotation_180");
49 break;
50 case 270:
51 mEnableFeatureOverrides.push_back("emulated_prerotation_270");
52 break;
53 default:
54 break;
55 }
56 if (!mEnableFeatureOverrides.empty())
57 {
58 mEnableFeatureOverrides.push_back(nullptr);
59 }
60
61 #if (DE_OS == DE_OS_WIN32)
62 {
63 std::vector<eglw::EGLAttrib> d3d11Attribs = initAttribs(
64 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE);
65
66 auto *d3d11Factory = new ANGLENativeDisplayFactory("angle-d3d11", "ANGLE D3D11 Display",
67 d3d11Attribs, &mEvents);
68 m_nativeDisplayFactoryRegistry.registerFactory(d3d11Factory);
69 }
70
71 {
72 std::vector<eglw::EGLAttrib> d3d9Attribs = initAttribs(
73 EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE);
74
75 auto *d3d9Factory = new ANGLENativeDisplayFactory("angle-d3d9", "ANGLE D3D9 Display",
76 d3d9Attribs, &mEvents);
77 m_nativeDisplayFactoryRegistry.registerFactory(d3d9Factory);
78 }
79
80 {
81 std::vector<eglw::EGLAttrib> d3d1193Attribs =
82 initAttribs(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
83 EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, 9, 3);
84
85 auto *d3d1193Factory = new ANGLENativeDisplayFactory(
86 "angle-d3d11-fl93", "ANGLE D3D11 FL9_3 Display", d3d1193Attribs, &mEvents);
87 m_nativeDisplayFactoryRegistry.registerFactory(d3d1193Factory);
88 }
89 #endif // (DE_OS == DE_OS_WIN32)
90
91 #if defined(ANGLE_USE_GBM) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_WIN32)
92 {
93 std::vector<eglw::EGLAttrib> glesAttribs =
94 initAttribs(EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE);
95
96 auto *glesFactory = new ANGLENativeDisplayFactory("angle-gles", "ANGLE OpenGL ES Display",
97 glesAttribs, &mEvents);
98 m_nativeDisplayFactoryRegistry.registerFactory(glesFactory);
99 }
100 #endif
101
102 {
103 std::vector<eglw::EGLAttrib> glAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE);
104
105 auto *glFactory =
106 new ANGLENativeDisplayFactory("angle-gl", "ANGLE OpenGL Display", glAttribs, &mEvents);
107 m_nativeDisplayFactoryRegistry.registerFactory(glFactory);
108 }
109
110 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_WIN32) || (DE_OS == DE_OS_UNIX)
111 {
112 std::vector<eglw::EGLAttrib> vkAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
113
114 auto *vkFactory = new ANGLENativeDisplayFactory("angle-vulkan", "ANGLE Vulkan Display",
115 vkAttribs, &mEvents);
116 m_nativeDisplayFactoryRegistry.registerFactory(vkFactory);
117 }
118 #endif
119
120 #if (DE_OS == DE_OS_WIN32) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX)
121 {
122 std::vector<eglw::EGLAttrib> swsAttribs = initAttribs(
123 EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE);
124 m_nativeDisplayFactoryRegistry.registerFactory(new ANGLENativeDisplayFactory(
125 "angle-swiftshader", "ANGLE SwiftShader Display", swsAttribs, &mEvents));
126 }
127 #endif
128
129 #if (DE_OS == DE_OS_OSX)
130 {
131 std::vector<eglw::EGLAttrib> mtlAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE);
132
133 auto *mtlFactory = new ANGLENativeDisplayFactory("angle-metal", "ANGLE Metal Display",
134 mtlAttribs, &mEvents);
135 m_nativeDisplayFactoryRegistry.registerFactory(mtlFactory);
136 }
137 #endif
138
139 {
140 std::vector<eglw::EGLAttrib> nullAttribs = initAttribs(EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE);
141
142 auto *nullFactory = new ANGLENativeDisplayFactory("angle-null", "ANGLE NULL Display",
143 nullAttribs, &mEvents);
144 m_nativeDisplayFactoryRegistry.registerFactory(nullFactory);
145 }
146
147 m_contextFactoryRegistry.registerFactory(
148 new eglu::GLContextFactory(m_nativeDisplayFactoryRegistry));
149
150 // Add Null context type for use in generating case lists
151 m_contextFactoryRegistry.registerFactory(new null::NullGLContextFactory());
152 }
153
~ANGLEPlatform()154 ANGLEPlatform::~ANGLEPlatform() {}
155
processEvents()156 bool ANGLEPlatform::processEvents()
157 {
158 return !mEvents.quitSignaled();
159 }
160
initAttribs(eglw::EGLAttrib type,eglw::EGLAttrib deviceType,eglw::EGLAttrib majorVersion,eglw::EGLAttrib minorVersion)161 std::vector<eglw::EGLAttrib> ANGLEPlatform::initAttribs(eglw::EGLAttrib type,
162 eglw::EGLAttrib deviceType,
163 eglw::EGLAttrib majorVersion,
164 eglw::EGLAttrib minorVersion)
165 {
166 std::vector<eglw::EGLAttrib> attribs;
167
168 attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
169 attribs.push_back(type);
170
171 if (deviceType != EGL_DONT_CARE)
172 {
173 attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
174 attribs.push_back(deviceType);
175 }
176
177 if (majorVersion != EGL_DONT_CARE)
178 {
179 attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
180 attribs.push_back(majorVersion);
181 }
182
183 if (minorVersion != EGL_DONT_CARE)
184 {
185 attribs.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
186 attribs.push_back(minorVersion);
187 }
188
189 if (mPlatformMethods.logError)
190 {
191 static_assert(sizeof(eglw::EGLAttrib) == sizeof(angle::PlatformMethods *),
192 "Unexpected pointer size");
193 attribs.push_back(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX);
194 attribs.push_back(reinterpret_cast<eglw::EGLAttrib>(&mPlatformMethods));
195 }
196
197 if (!mEnableFeatureOverrides.empty())
198 {
199 attribs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
200 attribs.push_back(reinterpret_cast<EGLAttrib>(mEnableFeatureOverrides.data()));
201 }
202
203 attribs.push_back(EGL_NONE);
204 return attribs;
205 }
206 } // namespace tcu
207
208 // Create platform
CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc,uint32_t preRotation)209 tcu::Platform *CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc, uint32_t preRotation)
210 {
211 return new tcu::ANGLEPlatform(logErrorFunc, preRotation);
212 }
213
createPlatform()214 tcu::Platform *createPlatform()
215 {
216 return CreateANGLEPlatform(nullptr, 0);
217 }
218