1 //
2 // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // DisplayWgpu.cpp:
7 // Implements the class methods for DisplayWgpu.
8 //
9
10 #include "libANGLE/renderer/wgpu/DisplayWgpu.h"
11
12 #include <dawn/dawn_proc.h>
13
14 #include "common/debug.h"
15 #include "common/platform.h"
16
17 #include "libANGLE/Display.h"
18 #include "libANGLE/renderer/wgpu/ContextWgpu.h"
19 #include "libANGLE/renderer/wgpu/DeviceWgpu.h"
20 #include "libANGLE/renderer/wgpu/DisplayWgpu_api.h"
21 #include "libANGLE/renderer/wgpu/ImageWgpu.h"
22 #include "libANGLE/renderer/wgpu/SurfaceWgpu.h"
23
24 namespace rx
25 {
26
DisplayWgpu(const egl::DisplayState & state)27 DisplayWgpu::DisplayWgpu(const egl::DisplayState &state) : DisplayImpl(state) {}
28
~DisplayWgpu()29 DisplayWgpu::~DisplayWgpu() {}
30
initialize(egl::Display * display)31 egl::Error DisplayWgpu::initialize(egl::Display *display)
32 {
33 ANGLE_TRY(createWgpuDevice());
34
35 mQueue = mDevice.GetQueue();
36 mFormatTable.initialize();
37
38 wgpu::SupportedLimits supportedLimits;
39 mDevice.GetLimits(&supportedLimits);
40 mLimitsWgpu = supportedLimits.limits;
41
42 webgpu::GenerateCaps(mLimitsWgpu, &mGLCaps, &mGLTextureCaps, &mGLExtensions, &mGLLimitations,
43 &mEGLCaps, &mEGLExtensions, &mMaxSupportedClientVersion);
44
45 return egl::NoError();
46 }
47
terminate()48 void DisplayWgpu::terminate() {}
49
makeCurrent(egl::Display * display,egl::Surface * drawSurface,egl::Surface * readSurface,gl::Context * context)50 egl::Error DisplayWgpu::makeCurrent(egl::Display *display,
51 egl::Surface *drawSurface,
52 egl::Surface *readSurface,
53 gl::Context *context)
54 {
55 // Ensure that the correct global DebugAnnotator is installed when the end2end tests change
56 // the ANGLE back-end (done frequently).
57 display->setGlobalDebugAnnotator();
58
59 return egl::NoError();
60 }
61
generateConfigs()62 egl::ConfigSet DisplayWgpu::generateConfigs()
63 {
64 egl::Config config;
65 config.renderTargetFormat = GL_BGRA8_EXT;
66 config.depthStencilFormat = GL_DEPTH24_STENCIL8;
67 config.bufferSize = 32;
68 config.redSize = 8;
69 config.greenSize = 8;
70 config.blueSize = 8;
71 config.alphaSize = 8;
72 config.alphaMaskSize = 0;
73 config.bindToTextureRGB = EGL_TRUE;
74 config.bindToTextureRGBA = EGL_TRUE;
75 config.colorBufferType = EGL_RGB_BUFFER;
76 config.configCaveat = EGL_NONE;
77 config.conformant = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
78 config.depthSize = 24;
79 config.level = 0;
80 config.matchNativePixmap = EGL_NONE;
81 config.maxPBufferWidth = 0;
82 config.maxPBufferHeight = 0;
83 config.maxPBufferPixels = 0;
84 config.maxSwapInterval = 1;
85 config.minSwapInterval = 1;
86 config.nativeRenderable = EGL_TRUE;
87 config.nativeVisualID = 0;
88 config.nativeVisualType = EGL_NONE;
89 config.renderableType = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
90 config.sampleBuffers = 0;
91 config.samples = 0;
92 config.stencilSize = 8;
93 config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
94 config.optimalOrientation = 0;
95 config.transparentType = EGL_NONE;
96 config.transparentRedValue = 0;
97 config.transparentGreenValue = 0;
98 config.transparentBlueValue = 0;
99
100 egl::ConfigSet configSet;
101 configSet.add(config);
102 return configSet;
103 }
104
testDeviceLost()105 bool DisplayWgpu::testDeviceLost()
106 {
107 return false;
108 }
109
restoreLostDevice(const egl::Display * display)110 egl::Error DisplayWgpu::restoreLostDevice(const egl::Display *display)
111 {
112 return egl::NoError();
113 }
114
isValidNativeWindow(EGLNativeWindowType window) const115 bool DisplayWgpu::isValidNativeWindow(EGLNativeWindowType window) const
116 {
117 return true;
118 }
119
getRendererDescription()120 std::string DisplayWgpu::getRendererDescription()
121 {
122 return "Wgpu";
123 }
124
getVendorString()125 std::string DisplayWgpu::getVendorString()
126 {
127 return "Wgpu";
128 }
129
getVersionString(bool includeFullVersion)130 std::string DisplayWgpu::getVersionString(bool includeFullVersion)
131 {
132 return std::string();
133 }
134
createDevice()135 DeviceImpl *DisplayWgpu::createDevice()
136 {
137 return new DeviceWgpu();
138 }
139
waitClient(const gl::Context * context)140 egl::Error DisplayWgpu::waitClient(const gl::Context *context)
141 {
142 return egl::NoError();
143 }
144
waitNative(const gl::Context * context,EGLint engine)145 egl::Error DisplayWgpu::waitNative(const gl::Context *context, EGLint engine)
146 {
147 return egl::NoError();
148 }
149
getMaxSupportedESVersion() const150 gl::Version DisplayWgpu::getMaxSupportedESVersion() const
151 {
152 return mMaxSupportedClientVersion;
153 }
154
getMaxConformantESVersion() const155 gl::Version DisplayWgpu::getMaxConformantESVersion() const
156 {
157 return mMaxSupportedClientVersion;
158 }
159
createWindowSurface(const egl::SurfaceState & state,EGLNativeWindowType window,const egl::AttributeMap & attribs)160 SurfaceImpl *DisplayWgpu::createWindowSurface(const egl::SurfaceState &state,
161 EGLNativeWindowType window,
162 const egl::AttributeMap &attribs)
163 {
164 return CreateWgpuWindowSurface(state, window);
165 }
166
createPbufferSurface(const egl::SurfaceState & state,const egl::AttributeMap & attribs)167 SurfaceImpl *DisplayWgpu::createPbufferSurface(const egl::SurfaceState &state,
168 const egl::AttributeMap &attribs)
169 {
170 return new OffscreenSurfaceWgpu(state);
171 }
172
createPbufferFromClientBuffer(const egl::SurfaceState & state,EGLenum buftype,EGLClientBuffer buffer,const egl::AttributeMap & attribs)173 SurfaceImpl *DisplayWgpu::createPbufferFromClientBuffer(const egl::SurfaceState &state,
174 EGLenum buftype,
175 EGLClientBuffer buffer,
176 const egl::AttributeMap &attribs)
177 {
178 UNIMPLEMENTED();
179 return nullptr;
180 }
181
createPixmapSurface(const egl::SurfaceState & state,NativePixmapType nativePixmap,const egl::AttributeMap & attribs)182 SurfaceImpl *DisplayWgpu::createPixmapSurface(const egl::SurfaceState &state,
183 NativePixmapType nativePixmap,
184 const egl::AttributeMap &attribs)
185 {
186 UNIMPLEMENTED();
187 return nullptr;
188 }
189
createImage(const egl::ImageState & state,const gl::Context * context,EGLenum target,const egl::AttributeMap & attribs)190 ImageImpl *DisplayWgpu::createImage(const egl::ImageState &state,
191 const gl::Context *context,
192 EGLenum target,
193 const egl::AttributeMap &attribs)
194 {
195 return new ImageWgpu(state);
196 }
197
createContext(const gl::State & state,gl::ErrorSet * errorSet,const egl::Config * configuration,const gl::Context * shareContext,const egl::AttributeMap & attribs)198 rx::ContextImpl *DisplayWgpu::createContext(const gl::State &state,
199 gl::ErrorSet *errorSet,
200 const egl::Config *configuration,
201 const gl::Context *shareContext,
202 const egl::AttributeMap &attribs)
203 {
204 return new ContextWgpu(state, errorSet, this);
205 }
206
createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,const egl::AttributeMap & attribs)207 StreamProducerImpl *DisplayWgpu::createStreamProducerD3DTexture(
208 egl::Stream::ConsumerType consumerType,
209 const egl::AttributeMap &attribs)
210 {
211 UNIMPLEMENTED();
212 return nullptr;
213 }
214
createShareGroup(const egl::ShareGroupState & state)215 ShareGroupImpl *DisplayWgpu::createShareGroup(const egl::ShareGroupState &state)
216 {
217 return new ShareGroupWgpu(state);
218 }
219
getWindowSystem() const220 angle::NativeWindowSystem DisplayWgpu::getWindowSystem() const
221 {
222 #if defined(ANGLE_PLATFORM_LINUX)
223 # if defined(ANGLE_USE_X11)
224 return angle::NativeWindowSystem::X11;
225 # elif defined(ANGLE_USE_WAYLAND)
226 return angle::NativeWindowSystem::Wayland;
227 # endif
228 #else
229 return angle::NativeWindowSystem::Other;
230 #endif
231 }
232
generateExtensions(egl::DisplayExtensions * outExtensions) const233 void DisplayWgpu::generateExtensions(egl::DisplayExtensions *outExtensions) const
234 {
235 *outExtensions = mEGLExtensions;
236 }
237
generateCaps(egl::Caps * outCaps) const238 void DisplayWgpu::generateCaps(egl::Caps *outCaps) const
239 {
240 *outCaps = mEGLCaps;
241 }
242
createWgpuDevice()243 egl::Error DisplayWgpu::createWgpuDevice()
244 {
245 dawnProcSetProcs(&dawn::native::GetProcs());
246
247 dawn::native::DawnInstanceDescriptor dawnInstanceDescriptor;
248
249 wgpu::InstanceDescriptor instanceDescriptor;
250 instanceDescriptor.features.timedWaitAnyEnable = true;
251 instanceDescriptor.nextInChain = &dawnInstanceDescriptor;
252 mInstance = wgpu::CreateInstance(&instanceDescriptor);
253
254 struct RequestAdapterResult
255 {
256 WGPURequestAdapterStatus status;
257 wgpu::Adapter adapter;
258 std::string message;
259 };
260 RequestAdapterResult adapterResult;
261
262 wgpu::RequestAdapterOptions requestAdapterOptions;
263
264 wgpu::RequestAdapterCallbackInfo callbackInfo;
265 callbackInfo.mode = wgpu::CallbackMode::WaitAnyOnly;
266 callbackInfo.callback = [](WGPURequestAdapterStatus status, WGPUAdapter adapter,
267 char const *message, void *userdata) {
268 RequestAdapterResult *result = reinterpret_cast<RequestAdapterResult *>(userdata);
269 result->status = status;
270 result->adapter = wgpu::Adapter::Acquire(adapter);
271 result->message = message ? message : "";
272 };
273 callbackInfo.userdata = &adapterResult;
274
275 wgpu::FutureWaitInfo futureWaitInfo;
276 futureWaitInfo.future = mInstance.RequestAdapter(&requestAdapterOptions, callbackInfo);
277
278 wgpu::WaitStatus status = mInstance.WaitAny(1, &futureWaitInfo, -1);
279 if (webgpu::IsWgpuError(status))
280 {
281 return egl::EglBadAlloc() << "Failed to get WebGPU adapter: " << adapterResult.message;
282 }
283
284 mAdapter = adapterResult.adapter;
285
286 std::vector<wgpu::FeatureName> requiredFeatures; // empty for now
287
288 wgpu::DeviceDescriptor deviceDesc;
289 deviceDesc.requiredFeatureCount = requiredFeatures.size();
290 deviceDesc.requiredFeatures = requiredFeatures.data();
291
292 mDevice = mAdapter.CreateDevice(&deviceDesc);
293 mDevice.SetUncapturedErrorCallback(
294 [](WGPUErrorType type, const char *message, void *userdata) {
295 ERR() << "Error: " << type << " - message: " << message;
296 },
297 nullptr);
298 return egl::NoError();
299 }
300
CreateWgpuDisplay(const egl::DisplayState & state)301 DisplayImpl *CreateWgpuDisplay(const egl::DisplayState &state)
302 {
303 return new DisplayWgpu(state);
304 }
305
306 } // namespace rx
307