blob: 162deaf2a2e211fdedf6ef3540860c03776d0dd0 [file] [log] [blame]
Stephen White985741a2019-07-18 11:43:45 -04001/*
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
Stephen Whitea521c962019-12-04 09:57:48 -05008#include "dawn/webgpu_cpp.h"
Mike Klein52337de2019-07-25 09:00:52 -05009#include "tools/gpu/dawn/DawnTestContext.h"
Stephen White985741a2019-07-18 11:43:45 -040010
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
Stephen Whitea521c962019-12-04 09:57:48 -050022#include "dawn/webgpu.h"
Stephen White1e2adcf2019-10-16 09:48:53 -040023#include "dawn/dawn_proc.h"
Robert Phillipsf4f80112020-07-13 16:13:31 -040024#include "include/gpu/GrDirectContext.h"
Stephen White985741a2019-07-18 11:43:45 -040025#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>
32static void* getProcAddressMacOS(const char* procName) {
33 return dlsym(RTLD_DEFAULT, procName);
34}
35#endif
36
37namespace {
38
39#ifdef SK_BUILD_FOR_WIN
40class ProcGetter {
41public:
42 typedef void(*Proc)();
43
44 ProcGetter()
45 : fModule(LoadLibraryA("opengl32.dll")) {
46 SkASSERT(!fInstance);
47 fInstance = this;
48 }
49
50 ~ProcGetter() {
51 if (fModule) {
52 FreeLibrary(fModule);
53 }
54 fInstance = nullptr;
55 }
56
57 static void* getProcAddress(const char* name) {
58 return fInstance->getProc(name);
59 }
60
61private:
62 Proc getProc(const char* name) {
63 PROC proc;
Stephen White883c7e92019-10-17 10:44:37 -040064 if ((proc = GetProcAddress(fModule, name))) {
Stephen White985741a2019-07-18 11:43:45 -040065 return (Proc) proc;
66 }
Stephen White883c7e92019-10-17 10:44:37 -040067 if ((proc = wglGetProcAddress(name))) {
Stephen White985741a2019-07-18 11:43:45 -040068 return (Proc) proc;
69 }
70 return nullptr;
71 }
72
73 HMODULE fModule;
74 static ProcGetter* fInstance;
75};
76
77ProcGetter* ProcGetter::fInstance;
78#endif
79
Stephen White362db582020-06-22 13:48:34 -040080static void PrintDeviceError(WGPUErrorType, const char* message, void*) {
81 SkDebugf("Device error: %s\n", message);
82}
83
Stephen White985741a2019-07-18 11:43:45 -040084class DawnTestContextImpl : public sk_gpu_test::DawnTestContext {
85public:
Stephen White3cc8d4f2019-10-30 09:56:23 -040086 static wgpu::Device createDevice(const dawn_native::Instance& instance,
Stephen White985741a2019-07-18 11:43:45 -040087 dawn_native::BackendType type) {
88 DawnProcTable backendProcs = dawn_native::GetProcs();
Stephen White1e2adcf2019-10-16 09:48:53 -040089 dawnProcSetProcs(&backendProcs);
Stephen White985741a2019-07-18 11:43:45 -040090
91 std::vector<dawn_native::Adapter> adapters = instance.GetAdapters();
92 for (dawn_native::Adapter adapter : adapters) {
93 if (adapter.GetBackendType() == type) {
Stephen Whitef40cef82020-05-29 13:58:39 -040094 return wgpu::Device::Acquire(adapter.CreateDevice());
Stephen White985741a2019-07-18 11:43:45 -040095 }
96 }
97 return nullptr;
98 }
99
100 static DawnTestContext* Create(DawnTestContext* sharedContext) {
101 std::unique_ptr<dawn_native::Instance> instance = std::make_unique<dawn_native::Instance>();
Stephen White3cc8d4f2019-10-30 09:56:23 -0400102 wgpu::Device device;
Stephen White985741a2019-07-18 11:43:45 -0400103 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);
Stephen White362db582020-06-22 13:48:34 -0400131 device.SetUncapturedErrorCallback(PrintDeviceError, 0);
Stephen White985741a2019-07-18 11:43:45 -0400132 }
133 if (!device) {
134 return nullptr;
135 }
136 return new DawnTestContextImpl(std::move(instance), device);
137 }
138
139 ~DawnTestContextImpl() override { this->teardown(); }
140
141 void testAbandon() override {}
142
Stephen White985741a2019-07-18 11:43:45 -0400143 void finish() override {}
144
Robert Phillipsf4f80112020-07-13 16:13:31 -0400145 sk_sp<GrDirectContext> makeContext(const GrContextOptions& options) override {
146 return GrDirectContext::MakeDawn(fDevice, options);
Stephen White985741a2019-07-18 11:43:45 -0400147 }
148
149protected:
150 void teardown() override {
151 INHERITED::teardown();
152 }
153
154private:
155 DawnTestContextImpl(std::unique_ptr<dawn_native::Instance> instance,
Stephen White3cc8d4f2019-10-30 09:56:23 -0400156 const wgpu::Device& device)
Stephen White64c8b812020-06-03 14:05:48 -0400157 : DawnTestContext(std::move(instance), device) {
Greg Daniel02497d42020-02-21 15:46:27 -0500158 fFenceSupport = true;
Stephen White985741a2019-07-18 11:43:45 -0400159 }
160
Robert Phillipsedf3f382020-02-13 12:59:19 -0500161 void onPlatformMakeNotCurrent() const override {}
Stephen White985741a2019-07-18 11:43:45 -0400162 void onPlatformMakeCurrent() const override {}
163 std::function<void()> onPlatformGetAutoContextRestore() const override { return nullptr; }
Stephen White985741a2019-07-18 11:43:45 -0400164
John Stiles7571f9e2020-09-02 22:42:33 -0400165 using INHERITED = sk_gpu_test::DawnTestContext;
Stephen White985741a2019-07-18 11:43:45 -0400166};
167} // anonymous namespace
168
169namespace sk_gpu_test {
170DawnTestContext* CreatePlatformDawnTestContext(DawnTestContext* sharedContext) {
171 return DawnTestContextImpl::Create(sharedContext);
172}
173} // namespace sk_gpu_test
174
175#endif