• 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,dawn_native::BackendType type)86     static wgpu::Device createDevice(const dawn_native::Instance& instance,
87                                      dawn_native::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             if (adapter.GetBackendType() == type) {
94                 return wgpu::Device::Acquire(adapter.CreateDevice());
95             }
96         }
97         return nullptr;
98     }
99 
Create(DawnTestContext * sharedContext)100     static DawnTestContext* Create(DawnTestContext* sharedContext) {
101         std::unique_ptr<dawn_native::Instance> instance = std::make_unique<dawn_native::Instance>();
102         wgpu::Device device;
103         if (sharedContext) {
104             device = sharedContext->getDevice();
105         } else {
106             dawn_native::BackendType type;
107 #if USE_OPENGL_BACKEND
108             dawn_native::opengl::AdapterDiscoveryOptions adapterOptions;
109             adapterOptions.getProc = reinterpret_cast<void*(*)(const char*)>(
110 #if defined(SK_BUILD_FOR_UNIX)
111                 glXGetProcAddress
112 #elif defined(SK_BUILD_FOR_MAC)
113                 getProcAddressMacOS
114 #elif defined(SK_BUILD_FOR_WIN)
115                 ProcGetter::getProcAddress
116 #endif
117             );
118             instance->DiscoverAdapters(&adapterOptions);
119             type = dawn_native::BackendType::OpenGL;
120 #else
121             instance->DiscoverDefaultAdapters();
122 #if defined(SK_BUILD_FOR_MAC)
123             type = dawn_native::BackendType::Metal;
124 #elif defined(SK_BUILD_FOR_WIN)
125             type = dawn_native::BackendType::D3D12;
126 #elif defined(SK_BUILD_FOR_UNIX)
127             type = dawn_native::BackendType::Vulkan;
128 #endif
129 #endif
130             device = createDevice(*instance, type);
131             device.SetUncapturedErrorCallback(PrintDeviceError, 0);
132         }
133         if (!device) {
134             return nullptr;
135         }
136         return new DawnTestContextImpl(std::move(instance), device);
137     }
138 
~DawnTestContextImpl()139     ~DawnTestContextImpl() override { this->teardown(); }
140 
testAbandon()141     void testAbandon() override {}
142 
finish()143     void finish() override {}
144 
makeContext(const GrContextOptions & options)145     sk_sp<GrDirectContext> makeContext(const GrContextOptions& options) override {
146         return GrDirectContext::MakeDawn(fDevice, options);
147     }
148 
149 protected:
teardown()150     void teardown() override {
151         INHERITED::teardown();
152     }
153 
154 private:
DawnTestContextImpl(std::unique_ptr<dawn_native::Instance> instance,const wgpu::Device & device)155     DawnTestContextImpl(std::unique_ptr<dawn_native::Instance> instance,
156                         const wgpu::Device& device)
157             : DawnTestContext(std::move(instance), device) {
158         fFenceSupport = true;
159     }
160 
onPlatformMakeNotCurrent() const161     void onPlatformMakeNotCurrent() const override {}
onPlatformMakeCurrent() const162     void onPlatformMakeCurrent() const override {}
onPlatformGetAutoContextRestore() const163     std::function<void()> onPlatformGetAutoContextRestore() const override  { return nullptr; }
164 
165     using INHERITED = sk_gpu_test::DawnTestContext;
166 };
167 }  // anonymous namespace
168 
169 namespace sk_gpu_test {
CreatePlatformDawnTestContext(DawnTestContext * sharedContext)170 DawnTestContext* CreatePlatformDawnTestContext(DawnTestContext* sharedContext) {
171     return DawnTestContextImpl::Create(sharedContext);
172 }
173 }  // namespace sk_gpu_test
174 
175 #endif
176