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