• 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 
16 #include "libANGLE/Display.h"
17 #include "libANGLE/renderer/wgpu/ContextWgpu.h"
18 #include "libANGLE/renderer/wgpu/DeviceWgpu.h"
19 #include "libANGLE/renderer/wgpu/DisplayWgpu_api.h"
20 #include "libANGLE/renderer/wgpu/ImageWgpu.h"
21 #include "libANGLE/renderer/wgpu/SurfaceWgpu.h"
22 
23 namespace rx
24 {
25 
26 static wgpu::AdapterType adapterType = wgpu::AdapterType::Unknown;
27 
DisplayWgpu(const egl::DisplayState & state)28 DisplayWgpu::DisplayWgpu(const egl::DisplayState &state) : DisplayImpl(state) {}
29 
~DisplayWgpu()30 DisplayWgpu::~DisplayWgpu() {}
31 
initialize(egl::Display * display)32 egl::Error DisplayWgpu::initialize(egl::Display *display)
33 {
34     egl::Error create_device_err = createWgpuDevice();
35     if (create_device_err.isError())
36     {
37         return create_device_err;
38     }
39     mQueue = mDevice.GetQueue();
40     return egl::NoError();
41 }
42 
terminate()43 void DisplayWgpu::terminate() {}
44 
makeCurrent(egl::Display * display,egl::Surface * drawSurface,egl::Surface * readSurface,gl::Context * context)45 egl::Error DisplayWgpu::makeCurrent(egl::Display *display,
46                                     egl::Surface *drawSurface,
47                                     egl::Surface *readSurface,
48                                     gl::Context *context)
49 {
50     // Ensure that the correct global DebugAnnotator is installed when the end2end tests change
51     // the ANGLE back-end (done frequently).
52     display->setGlobalDebugAnnotator();
53 
54     return egl::NoError();
55 }
56 
generateConfigs()57 egl::ConfigSet DisplayWgpu::generateConfigs()
58 {
59     egl::Config config;
60     config.renderTargetFormat    = GL_RGBA8;
61     config.depthStencilFormat    = GL_DEPTH24_STENCIL8;
62     config.bufferSize            = 32;
63     config.redSize               = 8;
64     config.greenSize             = 8;
65     config.blueSize              = 8;
66     config.alphaSize             = 8;
67     config.alphaMaskSize         = 0;
68     config.bindToTextureRGB      = EGL_TRUE;
69     config.bindToTextureRGBA     = EGL_TRUE;
70     config.colorBufferType       = EGL_RGB_BUFFER;
71     config.configCaveat          = EGL_NONE;
72     config.conformant            = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
73     config.depthSize             = 24;
74     config.level                 = 0;
75     config.matchNativePixmap     = EGL_NONE;
76     config.maxPBufferWidth       = 0;
77     config.maxPBufferHeight      = 0;
78     config.maxPBufferPixels      = 0;
79     config.maxSwapInterval       = 1;
80     config.minSwapInterval       = 1;
81     config.nativeRenderable      = EGL_TRUE;
82     config.nativeVisualID        = 0;
83     config.nativeVisualType      = EGL_NONE;
84     config.renderableType        = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
85     config.sampleBuffers         = 0;
86     config.samples               = 0;
87     config.stencilSize           = 8;
88     config.surfaceType           = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
89     config.optimalOrientation    = 0;
90     config.transparentType       = EGL_NONE;
91     config.transparentRedValue   = 0;
92     config.transparentGreenValue = 0;
93     config.transparentBlueValue  = 0;
94 
95     egl::ConfigSet configSet;
96     configSet.add(config);
97     return configSet;
98 }
99 
testDeviceLost()100 bool DisplayWgpu::testDeviceLost()
101 {
102     return false;
103 }
104 
restoreLostDevice(const egl::Display * display)105 egl::Error DisplayWgpu::restoreLostDevice(const egl::Display *display)
106 {
107     return egl::NoError();
108 }
109 
isValidNativeWindow(EGLNativeWindowType window) const110 bool DisplayWgpu::isValidNativeWindow(EGLNativeWindowType window) const
111 {
112     return true;
113 }
114 
getRendererDescription()115 std::string DisplayWgpu::getRendererDescription()
116 {
117     return "Wgpu";
118 }
119 
getVendorString()120 std::string DisplayWgpu::getVendorString()
121 {
122     return "Wgpu";
123 }
124 
getVersionString(bool includeFullVersion)125 std::string DisplayWgpu::getVersionString(bool includeFullVersion)
126 {
127     return std::string();
128 }
129 
createDevice()130 DeviceImpl *DisplayWgpu::createDevice()
131 {
132     return new DeviceWgpu();
133 }
134 
waitClient(const gl::Context * context)135 egl::Error DisplayWgpu::waitClient(const gl::Context *context)
136 {
137     return egl::NoError();
138 }
139 
waitNative(const gl::Context * context,EGLint engine)140 egl::Error DisplayWgpu::waitNative(const gl::Context *context, EGLint engine)
141 {
142     return egl::NoError();
143 }
144 
getMaxSupportedESVersion() const145 gl::Version DisplayWgpu::getMaxSupportedESVersion() const
146 {
147     return gl::Version(3, 2);
148 }
149 
getMaxSupportedDesktopVersion() const150 Optional<gl::Version> DisplayWgpu::getMaxSupportedDesktopVersion() const
151 {
152     return Optional<gl::Version>::Invalid();
153 }
154 
getMaxConformantESVersion() const155 gl::Version DisplayWgpu::getMaxConformantESVersion() const
156 {
157     return getMaxSupportedESVersion();
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 new SurfaceWgpu(state);
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 SurfaceWgpu(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     return new SurfaceWgpu(state);
179 }
180 
createPixmapSurface(const egl::SurfaceState & state,NativePixmapType nativePixmap,const egl::AttributeMap & attribs)181 SurfaceImpl *DisplayWgpu::createPixmapSurface(const egl::SurfaceState &state,
182                                               NativePixmapType nativePixmap,
183                                               const egl::AttributeMap &attribs)
184 {
185     return new SurfaceWgpu(state);
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 
getInstance() const218 wgpu::Instance DisplayWgpu::getInstance() const
219 {
220     return mInstance->Get();
221 }
222 
generateExtensions(egl::DisplayExtensions * outExtensions) const223 void DisplayWgpu::generateExtensions(egl::DisplayExtensions *outExtensions) const
224 {
225     outExtensions->createContextRobustness            = true;
226     outExtensions->postSubBuffer                      = true;
227     outExtensions->createContext                      = true;
228     outExtensions->image                              = true;
229     outExtensions->imageBase                          = true;
230     outExtensions->glTexture2DImage                   = true;
231     outExtensions->glTextureCubemapImage              = true;
232     outExtensions->glTexture3DImage                   = true;
233     outExtensions->glRenderbufferImage                = true;
234     outExtensions->getAllProcAddresses                = true;
235     outExtensions->noConfigContext                    = true;
236     outExtensions->directComposition                  = true;
237     outExtensions->createContextNoError               = true;
238     outExtensions->createContextWebGLCompatibility    = true;
239     outExtensions->createContextBindGeneratesResource = true;
240     outExtensions->swapBuffersWithDamage              = true;
241     outExtensions->pixelFormatFloat                   = true;
242     outExtensions->surfacelessContext                 = true;
243     outExtensions->displayTextureShareGroup           = true;
244     outExtensions->displaySemaphoreShareGroup         = true;
245     outExtensions->createContextClientArrays          = true;
246     outExtensions->programCacheControlANGLE           = true;
247     outExtensions->robustResourceInitializationANGLE  = true;
248 }
249 
generateCaps(egl::Caps * outCaps) const250 void DisplayWgpu::generateCaps(egl::Caps *outCaps) const
251 {
252     outCaps->textureNPOT = true;
253 }
254 
createWgpuDevice()255 egl::Error DisplayWgpu::createWgpuDevice()
256 {
257     dawnProcSetProcs(&dawn::native::GetProcs());
258 
259     WGPUInstanceDescriptor instanceDescriptor{};
260     instanceDescriptor.features.timedWaitAnyEnable = true;
261     mInstance = std::make_unique<dawn::native::Instance>(&instanceDescriptor);
262 
263     // Get an adapter for the backend to use, and create the device.
264     auto adapters = mInstance->EnumerateAdapters();
265     wgpu::DawnAdapterPropertiesPowerPreference power_props{};
266     wgpu::AdapterProperties adapterProperties{};
267     adapterProperties.nextInChain = &power_props;
268 
269     auto isAdapterType = [&adapterProperties](const auto &adapter) -> bool {
270         // picks the first adapter when adapterType is unknown.
271         if (adapterType == wgpu::AdapterType::Unknown)
272         {
273             return true;
274         }
275         adapter.GetProperties(&adapterProperties);
276         return adapterProperties.adapterType == adapterType;
277     };
278 
279     auto preferredAdapter = std::find_if(adapters.begin(), adapters.end(), isAdapterType);
280     if (preferredAdapter == adapters.end())
281     {
282         fprintf(stderr, "Failed to find an adapter! Please try another adapter type.\n");
283         return egl::EglNotInitialized();
284     }
285 
286     WGPUDeviceDescriptor deviceDesc = {};
287     mDevice = wgpu::Device::Acquire(preferredAdapter->CreateDevice(&deviceDesc));
288     mDevice.SetUncapturedErrorCallback(
289         [](WGPUErrorType type, const char *message, void *userdata) {
290             ERR() << "Error: " << type << " - message: " << message;
291         },
292         nullptr);
293     return egl::NoError();
294 }
295 
CreateWgpuDisplay(const egl::DisplayState & state)296 DisplayImpl *CreateWgpuDisplay(const egl::DisplayState &state)
297 {
298     return new DisplayWgpu(state);
299 }
300 
301 }  // namespace rx
302