• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     mDevice.GetLimits(&mLimitsWgpu);
39 
40     webgpu::GenerateCaps(mLimitsWgpu, &mGLCaps, &mGLTextureCaps, &mGLExtensions, &mGLLimitations,
41                          &mEGLCaps, &mEGLExtensions, &mMaxSupportedClientVersion);
42 
43     return egl::NoError();
44 }
45 
terminate()46 void DisplayWgpu::terminate() {}
47 
makeCurrent(egl::Display * display,egl::Surface * drawSurface,egl::Surface * readSurface,gl::Context * context)48 egl::Error DisplayWgpu::makeCurrent(egl::Display *display,
49                                     egl::Surface *drawSurface,
50                                     egl::Surface *readSurface,
51                                     gl::Context *context)
52 {
53     // Ensure that the correct global DebugAnnotator is installed when the end2end tests change
54     // the ANGLE back-end (done frequently).
55     display->setGlobalDebugAnnotator();
56 
57     return egl::NoError();
58 }
59 
generateConfigs()60 egl::ConfigSet DisplayWgpu::generateConfigs()
61 {
62     egl::Config config;
63     config.renderTargetFormat    = GL_BGRA8_EXT;
64     config.depthStencilFormat    = GL_DEPTH24_STENCIL8;
65     config.bufferSize            = 32;
66     config.redSize               = 8;
67     config.greenSize             = 8;
68     config.blueSize              = 8;
69     config.alphaSize             = 8;
70     config.alphaMaskSize         = 0;
71     config.bindToTextureRGB      = EGL_TRUE;
72     config.bindToTextureRGBA     = EGL_TRUE;
73     config.colorBufferType       = EGL_RGB_BUFFER;
74     config.configCaveat          = EGL_NONE;
75     config.conformant            = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
76     config.depthSize             = 24;
77     config.level                 = 0;
78     config.matchNativePixmap     = EGL_NONE;
79     config.maxPBufferWidth       = 0;
80     config.maxPBufferHeight      = 0;
81     config.maxPBufferPixels      = 0;
82     config.maxSwapInterval       = 1;
83     config.minSwapInterval       = 1;
84     config.nativeRenderable      = EGL_TRUE;
85     config.nativeVisualID        = 0;
86     config.nativeVisualType      = EGL_NONE;
87     config.renderableType        = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
88     config.sampleBuffers         = 0;
89     config.samples               = 0;
90     config.stencilSize           = 8;
91     config.surfaceType           = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
92     config.optimalOrientation    = 0;
93     config.transparentType       = EGL_NONE;
94     config.transparentRedValue   = 0;
95     config.transparentGreenValue = 0;
96     config.transparentBlueValue  = 0;
97 
98     egl::ConfigSet configSet;
99     configSet.add(config);
100     return configSet;
101 }
102 
testDeviceLost()103 bool DisplayWgpu::testDeviceLost()
104 {
105     return false;
106 }
107 
restoreLostDevice(const egl::Display * display)108 egl::Error DisplayWgpu::restoreLostDevice(const egl::Display *display)
109 {
110     return egl::NoError();
111 }
112 
isValidNativeWindow(EGLNativeWindowType window) const113 bool DisplayWgpu::isValidNativeWindow(EGLNativeWindowType window) const
114 {
115     return true;
116 }
117 
getRendererDescription()118 std::string DisplayWgpu::getRendererDescription()
119 {
120     return "Wgpu";
121 }
122 
getVendorString()123 std::string DisplayWgpu::getVendorString()
124 {
125     return "Wgpu";
126 }
127 
getVersionString(bool includeFullVersion)128 std::string DisplayWgpu::getVersionString(bool includeFullVersion)
129 {
130     return std::string();
131 }
132 
createDevice()133 DeviceImpl *DisplayWgpu::createDevice()
134 {
135     return new DeviceWgpu();
136 }
137 
waitClient(const gl::Context * context)138 egl::Error DisplayWgpu::waitClient(const gl::Context *context)
139 {
140     return egl::NoError();
141 }
142 
waitNative(const gl::Context * context,EGLint engine)143 egl::Error DisplayWgpu::waitNative(const gl::Context *context, EGLint engine)
144 {
145     return egl::NoError();
146 }
147 
getMaxSupportedESVersion() const148 gl::Version DisplayWgpu::getMaxSupportedESVersion() const
149 {
150     return mMaxSupportedClientVersion;
151 }
152 
getMaxConformantESVersion() const153 gl::Version DisplayWgpu::getMaxConformantESVersion() const
154 {
155     return mMaxSupportedClientVersion;
156 }
157 
createWindowSurface(const egl::SurfaceState & state,EGLNativeWindowType window,const egl::AttributeMap & attribs)158 SurfaceImpl *DisplayWgpu::createWindowSurface(const egl::SurfaceState &state,
159                                               EGLNativeWindowType window,
160                                               const egl::AttributeMap &attribs)
161 {
162     return CreateWgpuWindowSurface(state, window);
163 }
164 
createPbufferSurface(const egl::SurfaceState & state,const egl::AttributeMap & attribs)165 SurfaceImpl *DisplayWgpu::createPbufferSurface(const egl::SurfaceState &state,
166                                                const egl::AttributeMap &attribs)
167 {
168     return new OffscreenSurfaceWgpu(state);
169 }
170 
createPbufferFromClientBuffer(const egl::SurfaceState & state,EGLenum buftype,EGLClientBuffer buffer,const egl::AttributeMap & attribs)171 SurfaceImpl *DisplayWgpu::createPbufferFromClientBuffer(const egl::SurfaceState &state,
172                                                         EGLenum buftype,
173                                                         EGLClientBuffer buffer,
174                                                         const egl::AttributeMap &attribs)
175 {
176     UNIMPLEMENTED();
177     return nullptr;
178 }
179 
createPixmapSurface(const egl::SurfaceState & state,NativePixmapType nativePixmap,const egl::AttributeMap & attribs)180 SurfaceImpl *DisplayWgpu::createPixmapSurface(const egl::SurfaceState &state,
181                                               NativePixmapType nativePixmap,
182                                               const egl::AttributeMap &attribs)
183 {
184     UNIMPLEMENTED();
185     return nullptr;
186 }
187 
createImage(const egl::ImageState & state,const gl::Context * context,EGLenum target,const egl::AttributeMap & attribs)188 ImageImpl *DisplayWgpu::createImage(const egl::ImageState &state,
189                                     const gl::Context *context,
190                                     EGLenum target,
191                                     const egl::AttributeMap &attribs)
192 {
193     return new ImageWgpu(state);
194 }
195 
createContext(const gl::State & state,gl::ErrorSet * errorSet,const egl::Config * configuration,const gl::Context * shareContext,const egl::AttributeMap & attribs)196 rx::ContextImpl *DisplayWgpu::createContext(const gl::State &state,
197                                             gl::ErrorSet *errorSet,
198                                             const egl::Config *configuration,
199                                             const gl::Context *shareContext,
200                                             const egl::AttributeMap &attribs)
201 {
202     return new ContextWgpu(state, errorSet, this);
203 }
204 
createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,const egl::AttributeMap & attribs)205 StreamProducerImpl *DisplayWgpu::createStreamProducerD3DTexture(
206     egl::Stream::ConsumerType consumerType,
207     const egl::AttributeMap &attribs)
208 {
209     UNIMPLEMENTED();
210     return nullptr;
211 }
212 
createShareGroup(const egl::ShareGroupState & state)213 ShareGroupImpl *DisplayWgpu::createShareGroup(const egl::ShareGroupState &state)
214 {
215     return new ShareGroupWgpu(state);
216 }
217 
getWindowSystem() const218 angle::NativeWindowSystem DisplayWgpu::getWindowSystem() const
219 {
220 #if defined(ANGLE_PLATFORM_LINUX)
221 #    if defined(ANGLE_USE_X11)
222     return angle::NativeWindowSystem::X11;
223 #    elif defined(ANGLE_USE_WAYLAND)
224     return angle::NativeWindowSystem::Wayland;
225 #    endif
226 #else
227     return angle::NativeWindowSystem::Other;
228 #endif
229 }
230 
generateExtensions(egl::DisplayExtensions * outExtensions) const231 void DisplayWgpu::generateExtensions(egl::DisplayExtensions *outExtensions) const
232 {
233     *outExtensions = mEGLExtensions;
234 }
235 
generateCaps(egl::Caps * outCaps) const236 void DisplayWgpu::generateCaps(egl::Caps *outCaps) const
237 {
238     *outCaps = mEGLCaps;
239 }
240 
createWgpuDevice()241 egl::Error DisplayWgpu::createWgpuDevice()
242 {
243     dawnProcSetProcs(&dawn::native::GetProcs());
244 
245     dawn::native::DawnInstanceDescriptor dawnInstanceDescriptor;
246 
247     wgpu::InstanceDescriptor instanceDescriptor;
248     instanceDescriptor.capabilities.timedWaitAnyEnable = true;
249     instanceDescriptor.nextInChain                 = &dawnInstanceDescriptor;
250     mInstance                                      = wgpu::CreateInstance(&instanceDescriptor);
251 
252     struct RequestAdapterResult
253     {
254         wgpu::RequestAdapterStatus status;
255         wgpu::Adapter adapter;
256         std::string message;
257     };
258     RequestAdapterResult adapterResult;
259 
260     wgpu::RequestAdapterOptions requestAdapterOptions;
261 
262     wgpu::RequestAdapterCallback<RequestAdapterResult *> *requestAdapterCallback =
263         [](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, wgpu::StringView message,
264            RequestAdapterResult *result) {
265             result->status  = status;
266             result->adapter = adapter;
267             result->message = message;
268         };
269     wgpu::FutureWaitInfo futureWaitInfo;
270     futureWaitInfo.future =
271         mInstance.RequestAdapter(&requestAdapterOptions, wgpu::CallbackMode::WaitAnyOnly,
272                                  requestAdapterCallback, &adapterResult);
273 
274     wgpu::WaitStatus status = mInstance.WaitAny(1, &futureWaitInfo, -1);
275     if (webgpu::IsWgpuError(status))
276     {
277         std::ostringstream err;
278         err << "Failed to get WebGPU adapter: " << adapterResult.message;
279         return egl::Error(EGL_BAD_ALLOC, err.str());
280     }
281 
282     mAdapter = adapterResult.adapter;
283 
284     std::vector<wgpu::FeatureName> requiredFeatures;  // empty for now
285 
286     wgpu::DeviceDescriptor deviceDesc;
287     deviceDesc.requiredFeatureCount = requiredFeatures.size();
288     deviceDesc.requiredFeatures     = requiredFeatures.data();
289     deviceDesc.SetUncapturedErrorCallback(
290         [](const wgpu::Device &device, wgpu::ErrorType type, wgpu::StringView message) {
291             ERR() << "Error: " << static_cast<std::underlying_type<wgpu::ErrorType>::type>(type)
292                   << " - message: " << std::string(message);
293         });
294 
295     mDevice = mAdapter.CreateDevice(&deviceDesc);
296     return egl::NoError();
297 }
298 
CreateWgpuDisplay(const egl::DisplayState & state)299 DisplayImpl *CreateWgpuDisplay(const egl::DisplayState &state)
300 {
301     return new DisplayWgpu(state);
302 }
303 
304 }  // namespace rx
305