blob: 34bc5b3ac3b6b33f1a4b3de750ba415826d8da04 [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"
Stephen White985741a2019-07-18 11:43:45 -04009#include "dawn_native/DawnNative.h"
Mike Klein52337de2019-07-25 09:00:52 -050010#include "tools/gpu/dawn/DawnTestContext.h"
Stephen White985741a2019-07-18 11:43:45 -040011
12#ifdef SK_BUILD_FOR_UNIX
13#include "GL/glx.h"
14#endif
15
16#ifdef SK_BUILD_FOR_WIN
17#include <windows.h>
18#endif
19
20#define USE_OPENGL_BACKEND 0
21
22#ifdef SK_DAWN
Stephen Whitea521c962019-12-04 09:57:48 -050023#include "dawn/webgpu.h"
Stephen White1e2adcf2019-10-16 09:48:53 -040024#include "dawn/dawn_proc.h"
Stephen White985741a2019-07-18 11:43:45 -040025#include "include/gpu/GrContext.h"
26#include "tools/AutoreleasePool.h"
27#if USE_OPENGL_BACKEND
28#include "dawn_native/OpenGLBackend.h"
29#endif
30
31#if defined(SK_BUILD_FOR_MAC) && USE_OPENGL_BACKEND
32#include <dlfcn.h>
33static void* getProcAddressMacOS(const char* procName) {
34 return dlsym(RTLD_DEFAULT, procName);
35}
36#endif
37
38namespace {
39
40#ifdef SK_BUILD_FOR_WIN
41class ProcGetter {
42public:
43 typedef void(*Proc)();
44
45 ProcGetter()
46 : fModule(LoadLibraryA("opengl32.dll")) {
47 SkASSERT(!fInstance);
48 fInstance = this;
49 }
50
51 ~ProcGetter() {
52 if (fModule) {
53 FreeLibrary(fModule);
54 }
55 fInstance = nullptr;
56 }
57
58 static void* getProcAddress(const char* name) {
59 return fInstance->getProc(name);
60 }
61
62private:
63 Proc getProc(const char* name) {
64 PROC proc;
Stephen White883c7e92019-10-17 10:44:37 -040065 if ((proc = GetProcAddress(fModule, name))) {
Stephen White985741a2019-07-18 11:43:45 -040066 return (Proc) proc;
67 }
Stephen White883c7e92019-10-17 10:44:37 -040068 if ((proc = wglGetProcAddress(name))) {
Stephen White985741a2019-07-18 11:43:45 -040069 return (Proc) proc;
70 }
71 return nullptr;
72 }
73
74 HMODULE fModule;
75 static ProcGetter* fInstance;
76};
77
78ProcGetter* ProcGetter::fInstance;
79#endif
80
Stephen White985741a2019-07-18 11:43:45 -040081class DawnTestContextImpl : public sk_gpu_test::DawnTestContext {
82public:
Stephen White3cc8d4f2019-10-30 09:56:23 -040083 static wgpu::Device createDevice(const dawn_native::Instance& instance,
Stephen White985741a2019-07-18 11:43:45 -040084 dawn_native::BackendType type) {
85 DawnProcTable backendProcs = dawn_native::GetProcs();
Stephen White1e2adcf2019-10-16 09:48:53 -040086 dawnProcSetProcs(&backendProcs);
Stephen White985741a2019-07-18 11:43:45 -040087
88 std::vector<dawn_native::Adapter> adapters = instance.GetAdapters();
89 for (dawn_native::Adapter adapter : adapters) {
90 if (adapter.GetBackendType() == type) {
Stephen Whitef40cef82020-05-29 13:58:39 -040091 return wgpu::Device::Acquire(adapter.CreateDevice());
Stephen White985741a2019-07-18 11:43:45 -040092 }
93 }
94 return nullptr;
95 }
96
97 static DawnTestContext* Create(DawnTestContext* sharedContext) {
98 std::unique_ptr<dawn_native::Instance> instance = std::make_unique<dawn_native::Instance>();
Stephen White3cc8d4f2019-10-30 09:56:23 -040099 wgpu::Device device;
Stephen White985741a2019-07-18 11:43:45 -0400100 if (sharedContext) {
101 device = sharedContext->getDevice();
102 } else {
103 dawn_native::BackendType type;
104#if USE_OPENGL_BACKEND
105 dawn_native::opengl::AdapterDiscoveryOptions adapterOptions;
106 adapterOptions.getProc = reinterpret_cast<void*(*)(const char*)>(
107#if defined(SK_BUILD_FOR_UNIX)
108 glXGetProcAddress
109#elif defined(SK_BUILD_FOR_MAC)
110 getProcAddressMacOS
111#elif defined(SK_BUILD_FOR_WIN)
112 ProcGetter::getProcAddress
113#endif
114 );
115 instance->DiscoverAdapters(&adapterOptions);
116 type = dawn_native::BackendType::OpenGL;
117#else
118 instance->DiscoverDefaultAdapters();
119#if defined(SK_BUILD_FOR_MAC)
120 type = dawn_native::BackendType::Metal;
121#elif defined(SK_BUILD_FOR_WIN)
122 type = dawn_native::BackendType::D3D12;
123#elif defined(SK_BUILD_FOR_UNIX)
124 type = dawn_native::BackendType::Vulkan;
125#endif
126#endif
127 device = createDevice(*instance, type);
128 }
129 if (!device) {
130 return nullptr;
131 }
132 return new DawnTestContextImpl(std::move(instance), device);
133 }
134
135 ~DawnTestContextImpl() override { this->teardown(); }
136
137 void testAbandon() override {}
138
Stephen White985741a2019-07-18 11:43:45 -0400139 void finish() override {}
140
141 sk_sp<GrContext> makeGrContext(const GrContextOptions& options) override {
142 return GrContext::MakeDawn(fDevice, options);
143 }
144
145protected:
146 void teardown() override {
147 INHERITED::teardown();
148 }
149
150private:
151 DawnTestContextImpl(std::unique_ptr<dawn_native::Instance> instance,
Stephen White3cc8d4f2019-10-30 09:56:23 -0400152 const wgpu::Device& device)
Stephen White985741a2019-07-18 11:43:45 -0400153 : DawnTestContext(device)
154 , fInstance(std::move(instance)) {
Greg Daniel02497d42020-02-21 15:46:27 -0500155 fFenceSupport = true;
Stephen White985741a2019-07-18 11:43:45 -0400156 }
157
Robert Phillipsedf3f382020-02-13 12:59:19 -0500158 void onPlatformMakeNotCurrent() const override {}
Stephen White985741a2019-07-18 11:43:45 -0400159 void onPlatformMakeCurrent() const override {}
160 std::function<void()> onPlatformGetAutoContextRestore() const override { return nullptr; }
Stephen White985741a2019-07-18 11:43:45 -0400161 std::unique_ptr<dawn_native::Instance> fInstance;
162
163 typedef sk_gpu_test::DawnTestContext INHERITED;
164};
165} // anonymous namespace
166
167namespace sk_gpu_test {
168DawnTestContext* CreatePlatformDawnTestContext(DawnTestContext* sharedContext) {
169 return DawnTestContextImpl::Create(sharedContext);
170}
171} // namespace sk_gpu_test
172
173#endif