• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "dawn/webgpu_cpp.h"
9 #include "tools/gpu/dawn/DawnTestContext.h"
10 
11 #ifdef SK_BUILD_FOR_UNIX
12 #include "GL/glx.h"
13 #endif
14 
15 #ifdef SK_BUILD_FOR_WIN
16 #include <windows.h>
17 #endif
18 
19 #define USE_OPENGL_BACKEND 0
20 
21 #ifdef SK_DAWN
22 #include "dawn/webgpu.h"
23 #include "dawn/dawn_proc.h"
24 #include "include/gpu/GrDirectContext.h"
25 #include "tools/AutoreleasePool.h"
26 #if USE_OPENGL_BACKEND
27 #include "dawn_native/OpenGLBackend.h"
28 #endif
29 
30 #if defined(SK_BUILD_FOR_MAC) && USE_OPENGL_BACKEND
31 #include <dlfcn.h>
getProcAddressMacOS(const char * procName)32 static void* getProcAddressMacOS(const char* procName) {
33     return dlsym(RTLD_DEFAULT, procName);
34 }
35 #endif
36 
37 namespace {
38 
39 #ifdef SK_BUILD_FOR_WIN
40 class ProcGetter {
41 public:
42     typedef void(*Proc)();
43 
ProcGetter()44     ProcGetter()
45       : fModule(LoadLibraryA("opengl32.dll")) {
46         SkASSERT(!fInstance);
47         fInstance = this;
48     }
49 
~ProcGetter()50     ~ProcGetter() {
51         if (fModule) {
52             FreeLibrary(fModule);
53         }
54         fInstance = nullptr;
55     }
56 
getProcAddress(const char * name)57     static void* getProcAddress(const char* name) {
58         return fInstance->getProc(name);
59     }
60 
61 private:
getProc(const char * name)62     Proc getProc(const char* name) {
63         PROC proc;
64         if ((proc = GetProcAddress(fModule, name))) {
65             return (Proc) proc;
66         }
67         if ((proc = wglGetProcAddress(name))) {
68             return (Proc) proc;
69         }
70         return nullptr;
71     }
72 
73     HMODULE fModule;
74     static ProcGetter* fInstance;
75 };
76 
77 ProcGetter* ProcGetter::fInstance;
78 #endif
79 
PrintDeviceError(WGPUErrorType,const char * message,void *)80 static void PrintDeviceError(WGPUErrorType, const char* message, void*) {
81     SkDebugf("Device error: %s\n", message);
82 }
83 
84 class DawnTestContextImpl : public sk_gpu_test::DawnTestContext {
85 public:
createDevice(const dawn_native::Instance & instance,wgpu::BackendType type)86     static wgpu::Device createDevice(const dawn_native::Instance& instance,
87                                      wgpu::BackendType type) {
88         DawnProcTable backendProcs = dawn_native::GetProcs();
89         dawnProcSetProcs(&backendProcs);
90 
91         std::vector<dawn_native::Adapter> adapters = instance.GetAdapters();
92         for (dawn_native::Adapter adapter : adapters) {
93             wgpu::AdapterProperties properties;
94             adapter.GetProperties(&properties);
95             if (properties.backendType == type) {
96                 return wgpu::Device::Acquire(adapter.CreateDevice());
97             }
98         }
99         return nullptr;
100     }
101 
Create(DawnTestContext * sharedContext)102     static DawnTestContext* Create(DawnTestContext* sharedContext) {
103         std::unique_ptr<dawn_native::Instance> instance = std::make_unique<dawn_native::Instance>();
104         wgpu::Device device;
105         if (sharedContext) {
106             device = sharedContext->getDevice();
107         } else {
108             wgpu::BackendType type;
109 #if USE_OPENGL_BACKEND
110             dawn_native::opengl::AdapterDiscoveryOptions adapterOptions;
111             adapterOptions.getProc = reinterpret_cast<void*(*)(const char*)>(
112 #if defined(SK_BUILD_FOR_UNIX)
113                 glXGetProcAddress
114 #elif defined(SK_BUILD_FOR_MAC)
115                 getProcAddressMacOS
116 #elif defined(SK_BUILD_FOR_WIN)
117                 ProcGetter::getProcAddress
118 #endif
119             );
120             instance->DiscoverAdapters(&adapterOptions);
121             type = wgpu::BackendType::OpenGL;
122 #else
123             instance->DiscoverDefaultAdapters();
124 #if defined(SK_BUILD_FOR_MAC)
125             type = wgpu::BackendType::Metal;
126 #elif defined(SK_BUILD_FOR_WIN)
127             type = wgpu::BackendType::D3D12;
128 #elif defined(SK_BUILD_FOR_UNIX)
129             type = wgpu::BackendType::Vulkan;
130 #endif
131 #endif
132             device = createDevice(*instance, type);
133             device.SetUncapturedErrorCallback(PrintDeviceError, 0);
134         }
135         if (!device) {
136             return nullptr;
137         }
138         return new DawnTestContextImpl(std::move(instance), device);
139     }
140 
~DawnTestContextImpl()141     ~DawnTestContextImpl() override { this->teardown(); }
142 
testAbandon()143     void testAbandon() override {}
144 
finish()145     void finish() override {}
146 
makeContext(const GrContextOptions & options)147     sk_sp<GrDirectContext> makeContext(const GrContextOptions& options) override {
148         return GrDirectContext::MakeDawn(fDevice, options);
149     }
150 
151 protected:
teardown()152     void teardown() override {
153         INHERITED::teardown();
154     }
155 
156 private:
DawnTestContextImpl(std::unique_ptr<dawn_native::Instance> instance,const wgpu::Device & device)157     DawnTestContextImpl(std::unique_ptr<dawn_native::Instance> instance,
158                         const wgpu::Device& device)
159             : DawnTestContext(std::move(instance), device) {
160         fFenceSupport = true;
161     }
162 
onPlatformMakeNotCurrent() const163     void onPlatformMakeNotCurrent() const override {}
onPlatformMakeCurrent() const164     void onPlatformMakeCurrent() const override {}
onPlatformGetAutoContextRestore() const165     std::function<void()> onPlatformGetAutoContextRestore() const override  { return nullptr; }
166 
167     using INHERITED = sk_gpu_test::DawnTestContext;
168 };
169 }  // anonymous namespace
170 
171 namespace sk_gpu_test {
CreatePlatformDawnTestContext(DawnTestContext * sharedContext)172 DawnTestContext* CreatePlatformDawnTestContext(DawnTestContext* sharedContext) {
173     return DawnTestContextImpl::Create(sharedContext);
174 }
175 }  // namespace sk_gpu_test
176 
177 #endif
178