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