xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/wgpu/DisplayWgpu.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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