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