Simplify BackendBinding following adapters.

It doesn't need to care about device creation anymore, except for the
GLFW window hints and creating a GL context to discover the adapter.

Also remove the non-adapter GetPCIInfo.

BUG=dawn:29

Change-Id: I9bc8232536a55d2f973463ae0f2e0548dfc35456
Reviewed-on: https://dawn-review.googlesource.com/c/4381
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Corentin Wallez 2019-02-12 15:48:15 +00:00 committed by Commit Bot service account
parent 5987c4e839
commit bb5696bcd3
14 changed files with 139 additions and 170 deletions

View File

@ -27,6 +27,7 @@
#include <dawn_wire/WireServer.h> #include <dawn_wire/WireServer.h>
#include "GLFW/glfw3.h" #include "GLFW/glfw3.h"
#include <algorithm>
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
@ -59,6 +60,7 @@ enum class CmdBufType {
#endif #endif
static CmdBufType cmdBufType = CmdBufType::Terrible; static CmdBufType cmdBufType = CmdBufType::Terrible;
static std::unique_ptr<dawn_native::Instance> instance;
static utils::BackendBinding* binding = nullptr; static utils::BackendBinding* binding = nullptr;
static GLFWwindow* window = nullptr; static GLFWwindow* window = nullptr;
@ -69,29 +71,45 @@ static utils::TerribleCommandBuffer* c2sBuf = nullptr;
static utils::TerribleCommandBuffer* s2cBuf = nullptr; static utils::TerribleCommandBuffer* s2cBuf = nullptr;
dawn::Device CreateCppDawnDevice() { dawn::Device CreateCppDawnDevice() {
binding = utils::CreateBinding(backendType);
if (binding == nullptr) {
return dawn::Device();
}
glfwSetErrorCallback(PrintGLFWError); glfwSetErrorCallback(PrintGLFWError);
if (!glfwInit()) { if (!glfwInit()) {
return dawn::Device(); return dawn::Device();
} }
binding->SetupGLFWWindowHints(); // Create the test window and discover adapters using it (esp. for OpenGL)
utils::SetupGLFWWindowHintsForBackend(backendType);
window = glfwCreateWindow(640, 480, "Dawn window", nullptr, nullptr); window = glfwCreateWindow(640, 480, "Dawn window", nullptr, nullptr);
if (!window) { if (!window) {
return dawn::Device(); return dawn::Device();
} }
binding->SetWindow(window); instance = std::make_unique<dawn_native::Instance>();
utils::DiscoverAdapter(instance.get(), window, backendType);
dawnDevice backendDevice = binding->CreateDevice(); // Get an adapter for the backend to use, and create the device.
dawn_native::Adapter backendAdapter;
{
std::vector<dawn_native::Adapter> adapters = instance->GetAdapters();
auto adapterIt = std::find_if(adapters.begin(), adapters.end(),
[](const dawn_native::Adapter adapter) -> bool {
return adapter.GetBackendType() == backendType;
});
ASSERT(adapterIt != adapters.end());
backendAdapter = *adapterIt;
}
dawnDevice backendDevice = backendAdapter.CreateDevice();
dawnProcTable backendProcs = dawn_native::GetProcs(); dawnProcTable backendProcs = dawn_native::GetProcs();
binding = utils::CreateBinding(backendType, window, backendDevice);
if (binding == nullptr) {
return dawn::Device();
}
// Choose whether to use the backend procs and devices directly, or set up the wire.
dawnDevice cDevice = nullptr; dawnDevice cDevice = nullptr;
dawnProcTable procs; dawnProcTable procs;
switch (cmdBufType) { switch (cmdBufType) {
case CmdBufType::None: case CmdBufType::None:
procs = backendProcs; procs = backendProcs;

View File

@ -26,11 +26,6 @@ namespace dawn_native {
return GetProcsAutogen(); return GetProcsAutogen();
} }
const PCIInfo& GetPCIInfo(dawnDevice device) {
DeviceBase* deviceBase = reinterpret_cast<DeviceBase*>(device);
return deviceBase->GetPCIInfo();
}
// Adapter // Adapter
Adapter::Adapter() = default; Adapter::Adapter() = default;
@ -50,6 +45,10 @@ namespace dawn_native {
return mImpl->GetPCIInfo(); return mImpl->GetPCIInfo();
} }
Adapter::operator bool() const {
return mImpl != nullptr;
}
dawnDevice Adapter::CreateDevice() { dawnDevice Adapter::CreateDevice() {
return reinterpret_cast<dawnDevice>(mImpl->CreateDevice()); return reinterpret_cast<dawnDevice>(mImpl->CreateDevice());
} }

View File

@ -102,11 +102,6 @@ namespace dawn_native {
mCaches->bindGroupLayouts.erase(obj); mCaches->bindGroupLayouts.erase(obj);
} }
const PCIInfo& DeviceBase::GetPCIInfo() const {
ASSERT(mAdapter != nullptr);
return mAdapter->GetPCIInfo();
}
// Object creation API methods // Object creation API methods
BindGroupBase* DeviceBase::CreateBindGroup(const BindGroupDescriptor* descriptor) { BindGroupBase* DeviceBase::CreateBindGroup(const BindGroupDescriptor* descriptor) {

View File

@ -114,8 +114,6 @@ namespace dawn_native {
return nullptr; return nullptr;
} }
virtual const PCIInfo& GetPCIInfo() const;
virtual ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer( virtual ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(
size_t size) = 0; size_t size) = 0;
virtual MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, virtual MaybeError CopyFromStagingToBuffer(StagingBufferBase* source,

View File

@ -55,6 +55,8 @@ namespace dawn_native {
BackendType GetBackendType() const; BackendType GetBackendType() const;
const PCIInfo& GetPCIInfo() const; const PCIInfo& GetPCIInfo() const;
explicit operator bool() const;
// Create a device on this adapter, note that the interface will change to include at least // Create a device on this adapter, note that the interface will change to include at least
// a device descriptor and a pointer to backend specific options. // a device descriptor and a pointer to backend specific options.
// On an error, nullptr is returned. // On an error, nullptr is returned.
@ -104,8 +106,6 @@ namespace dawn_native {
// Backend-agnostic API for dawn_native // Backend-agnostic API for dawn_native
DAWN_NATIVE_EXPORT dawnProcTable GetProcs(); DAWN_NATIVE_EXPORT dawnProcTable GetProcs();
DAWN_NATIVE_EXPORT const PCIInfo& GetPCIInfo(dawnDevice device);
} // namespace dawn_native } // namespace dawn_native
#endif // DAWNNATIVE_DAWNNATIVE_H_ #endif // DAWNNATIVE_DAWNNATIVE_H_

View File

@ -26,6 +26,7 @@
#include "utils/SystemUtils.h" #include "utils/SystemUtils.h"
#include "utils/TerribleCommandBuffer.h" #include "utils/TerribleCommandBuffer.h"
#include <algorithm>
#include <iostream> #include <iostream>
#include <unordered_map> #include <unordered_map>
#include "GLFW/glfw3.h" #include "GLFW/glfw3.h"
@ -55,7 +56,7 @@ namespace {
std::unordered_map<dawn_native::BackendType, GLFWwindow*> windows; std::unordered_map<dawn_native::BackendType, GLFWwindow*> windows;
// Creates a GLFW window set up for use with a given backend. // Creates a GLFW window set up for use with a given backend.
GLFWwindow* GetWindowForBackend(utils::BackendBinding* binding, dawn_native::BackendType type) { GLFWwindow* GetWindowForBackend(dawn_native::BackendType type) {
GLFWwindow** window = &windows[type]; GLFWwindow** window = &windows[type];
if (*window != nullptr) { if (*window != nullptr) {
@ -67,7 +68,7 @@ namespace {
} }
glfwDefaultWindowHints(); glfwDefaultWindowHints();
binding->SetupGLFWWindowHints(); utils::SetupGLFWWindowHintsForBackend(type);
std::string windowName = "Dawn " + ParamName(type) + " test window"; std::string windowName = "Dawn " + ParamName(type) + " test window";
*window = glfwCreateWindow(400, 400, windowName.c_str(), nullptr, nullptr); *window = glfwCreateWindow(400, 400, windowName.c_str(), nullptr, nullptr);
@ -174,17 +175,35 @@ bool DawnTest::IsMacOS() const {
bool gTestUsesWire = false; bool gTestUsesWire = false;
void DawnTest::SetUp() { void DawnTest::SetUp() {
mBinding.reset(utils::CreateBinding(GetParam())); // Create the test window and discover adapters using it (esp. for OpenGL)
DAWN_ASSERT(mBinding != nullptr); GLFWwindow* testWindow = GetWindowForBackend(GetParam());
GLFWwindow* testWindow = GetWindowForBackend(mBinding.get(), GetParam());
DAWN_ASSERT(testWindow != nullptr); DAWN_ASSERT(testWindow != nullptr);
mBinding->SetWindow(testWindow); mInstance = std::make_unique<dawn_native::Instance>();
utils::DiscoverAdapter(mInstance.get(), testWindow, GetParam());
dawnDevice backendDevice = mBinding->CreateDevice(); // Get an adapter for the backend to use, and create the device.
dawn_native::Adapter backendAdapter;
{
std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
auto adapterIt = std::find_if(adapters.begin(), adapters.end(),
[this](const dawn_native::Adapter adapter) -> bool {
// Chromium's GTest harness has GetParam() as a regular
// function and not a member function of this.
DAWN_UNUSED(this);
return adapter.GetBackendType() == GetParam();
});
ASSERT(adapterIt != adapters.end());
backendAdapter = *adapterIt;
}
mPCIInfo = backendAdapter.GetPCIInfo();
dawnDevice backendDevice = backendAdapter.CreateDevice();
dawnProcTable backendProcs = dawn_native::GetProcs(); dawnProcTable backendProcs = dawn_native::GetProcs();
mBinding.reset(utils::CreateBinding(GetParam(), testWindow, backendDevice));
DAWN_ASSERT(mBinding != nullptr);
// Choose whether to use the backend procs and devices directly, or set up the wire. // Choose whether to use the backend procs and devices directly, or set up the wire.
dawnDevice cDevice = nullptr; dawnDevice cDevice = nullptr;
dawnProcTable procs; dawnProcTable procs;
@ -225,8 +244,6 @@ void DawnTest::SetUp() {
// The end2end tests should never cause validation errors. These should be tested in unittests. // The end2end tests should never cause validation errors. These should be tested in unittests.
device.SetErrorCallback(DeviceErrorCauseTestFailure, 0); device.SetErrorCallback(DeviceErrorCauseTestFailure, 0);
mPCIInfo = dawn_native::GetPCIInfo(backendDevice);
} }
void DawnTest::TearDown() { void DawnTest::TearDown() {

View File

@ -177,6 +177,7 @@ class DawnTest : public ::testing::TestWithParam<dawn_native::BackendType> {
// Assuming the data is mapped, checks all expectations // Assuming the data is mapped, checks all expectations
void ResolveExpectations(); void ResolveExpectations();
std::unique_ptr<dawn_native::Instance> mInstance;
std::unique_ptr<utils::BackendBinding> mBinding; std::unique_ptr<utils::BackendBinding> mBinding;
dawn_native::PCIInfo mPCIInfo; dawn_native::PCIInfo mPCIInfo;

View File

@ -14,55 +14,92 @@
#include "utils/BackendBinding.h" #include "utils/BackendBinding.h"
#include "common/Assert.h" #include "common/Compiler.h"
#include "GLFW/glfw3.h"
#if defined(DAWN_ENABLE_BACKEND_OPENGL)
# include "dawn_native/OpenGLBackend.h"
#endif // defined(DAWN_ENABLE_BACKEND_OPENGL)
namespace utils { namespace utils {
#if defined(DAWN_ENABLE_BACKEND_D3D12) #if defined(DAWN_ENABLE_BACKEND_D3D12)
BackendBinding* CreateD3D12Binding(); BackendBinding* CreateD3D12Binding(GLFWwindow* window, dawnDevice device);
#endif #endif
#if defined(DAWN_ENABLE_BACKEND_METAL) #if defined(DAWN_ENABLE_BACKEND_METAL)
BackendBinding* CreateMetalBinding(); BackendBinding* CreateMetalBinding(GLFWwindow* window, dawnDevice device);
#endif #endif
#if defined(DAWN_ENABLE_BACKEND_NULL) #if defined(DAWN_ENABLE_BACKEND_NULL)
BackendBinding* CreateNullBinding(); BackendBinding* CreateNullBinding(GLFWwindow* window, dawnDevice device);
#endif #endif
#if defined(DAWN_ENABLE_BACKEND_OPENGL) #if defined(DAWN_ENABLE_BACKEND_OPENGL)
BackendBinding* CreateOpenGLBinding(); BackendBinding* CreateOpenGLBinding(GLFWwindow* window, dawnDevice device);
#endif #endif
#if defined(DAWN_ENABLE_BACKEND_VULKAN) #if defined(DAWN_ENABLE_BACKEND_VULKAN)
BackendBinding* CreateVulkanBinding(); BackendBinding* CreateVulkanBinding(GLFWwindow* window, dawnDevice device);
#endif #endif
void BackendBinding::SetWindow(GLFWwindow* window) { BackendBinding::BackendBinding(GLFWwindow* window, dawnDevice device)
mWindow = window; : mWindow(window), mDevice(device) {
} }
BackendBinding* CreateBinding(dawn_native::BackendType type) { void SetupGLFWWindowHintsForBackend(dawn_native::BackendType type) {
if (type == dawn_native::BackendType::OpenGL) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
} else {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
}
}
void DiscoverAdapter(dawn_native::Instance* instance,
GLFWwindow* window,
dawn_native::BackendType type) {
DAWN_UNUSED(type);
DAWN_UNUSED(window);
if (type == dawn_native::BackendType::OpenGL) {
#if defined(DAWN_ENABLE_BACKEND_OPENGL)
glfwMakeContextCurrent(window);
dawn_native::opengl::AdapterDiscoveryOptions adapterOptions;
adapterOptions.getProc = reinterpret_cast<void* (*)(const char*)>(glfwGetProcAddress);
instance->DiscoverAdapters(&adapterOptions);
#endif // defined(DAWN_ENABLE_BACKEND_OPENGL)
} else {
instance->DiscoverDefaultAdapters();
}
}
BackendBinding* CreateBinding(dawn_native::BackendType type,
GLFWwindow* window,
dawnDevice device) {
switch (type) { switch (type) {
#if defined(DAWN_ENABLE_BACKEND_D3D12) #if defined(DAWN_ENABLE_BACKEND_D3D12)
case dawn_native::BackendType::D3D12: case dawn_native::BackendType::D3D12:
return CreateD3D12Binding(); return CreateD3D12Binding(window, device);
#endif #endif
#if defined(DAWN_ENABLE_BACKEND_METAL) #if defined(DAWN_ENABLE_BACKEND_METAL)
case dawn_native::BackendType::Metal: case dawn_native::BackendType::Metal:
return CreateMetalBinding(); return CreateMetalBinding(window, device);
#endif #endif
#if defined(DAWN_ENABLE_BACKEND_NULL) #if defined(DAWN_ENABLE_BACKEND_NULL)
case dawn_native::BackendType::Null: case dawn_native::BackendType::Null:
return CreateNullBinding(); return CreateNullBinding(window, device);
#endif #endif
#if defined(DAWN_ENABLE_BACKEND_OPENGL) #if defined(DAWN_ENABLE_BACKEND_OPENGL)
case dawn_native::BackendType::OpenGL: case dawn_native::BackendType::OpenGL:
return CreateOpenGLBinding(); return CreateOpenGLBinding(window, device);
#endif #endif
#if defined(DAWN_ENABLE_BACKEND_VULKAN) #if defined(DAWN_ENABLE_BACKEND_VULKAN)
case dawn_native::BackendType::Vulkan: case dawn_native::BackendType::Vulkan:
return CreateVulkanBinding(); return CreateVulkanBinding(window, device);
#endif #endif
default: default:

View File

@ -15,11 +15,10 @@
#ifndef UTILS_BACKENDBINDING_H_ #ifndef UTILS_BACKENDBINDING_H_
#define UTILS_BACKENDBINDING_H_ #define UTILS_BACKENDBINDING_H_
#include <dawn_native/DawnNative.h> #include "dawn/dawncpp.h"
#include "dawn_native/DawnNative.h"
struct GLFWwindow; struct GLFWwindow;
typedef struct dawnProcTable_s dawnProcTable;
typedef struct dawnDeviceImpl* dawnDevice;
namespace utils { namespace utils {
@ -27,18 +26,23 @@ namespace utils {
public: public:
virtual ~BackendBinding() = default; virtual ~BackendBinding() = default;
virtual void SetupGLFWWindowHints() = 0;
virtual dawnDevice CreateDevice() = 0;
virtual uint64_t GetSwapChainImplementation() = 0; virtual uint64_t GetSwapChainImplementation() = 0;
virtual dawnTextureFormat GetPreferredSwapChainTextureFormat() = 0; virtual dawnTextureFormat GetPreferredSwapChainTextureFormat() = 0;
void SetWindow(GLFWwindow* window);
protected: protected:
BackendBinding(GLFWwindow* window, dawnDevice device);
GLFWwindow* mWindow = nullptr; GLFWwindow* mWindow = nullptr;
dawnDevice mDevice = nullptr;
}; };
BackendBinding* CreateBinding(dawn_native::BackendType type); void SetupGLFWWindowHintsForBackend(dawn_native::BackendType type);
void DiscoverAdapter(dawn_native::Instance* instance,
GLFWwindow* window,
dawn_native::BackendType type);
BackendBinding* CreateBinding(dawn_native::BackendType type,
GLFWwindow* window,
dawnDevice device);
} // namespace utils } // namespace utils

View File

@ -27,30 +27,14 @@ namespace utils {
class D3D12Binding : public BackendBinding { class D3D12Binding : public BackendBinding {
public: public:
void SetupGLFWWindowHints() override { D3D12Binding(GLFWwindow* window, dawnDevice device) : BackendBinding(window, device) {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
}
dawnDevice CreateDevice() override {
// Make an instance and find a D3D12 adapter
mInstance = std::make_unique<dawn_native::Instance>();
mInstance->DiscoverDefaultAdapters();
std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
for (dawn_native::Adapter adapter : adapters) {
if (adapter.GetBackendType() == dawn_native::BackendType::D3D12) {
mBackendDevice = adapter.CreateDevice();
return mBackendDevice;
}
}
UNREACHABLE();
} }
uint64_t GetSwapChainImplementation() override { uint64_t GetSwapChainImplementation() override {
if (mSwapchainImpl.userData == nullptr) { if (mSwapchainImpl.userData == nullptr) {
HWND win32Window = glfwGetWin32Window(mWindow); HWND win32Window = glfwGetWin32Window(mWindow);
mSwapchainImpl = mSwapchainImpl =
dawn_native::d3d12::CreateNativeSwapChainImpl(mBackendDevice, win32Window); dawn_native::d3d12::CreateNativeSwapChainImpl(mDevice, win32Window);
} }
return reinterpret_cast<uint64_t>(&mSwapchainImpl); return reinterpret_cast<uint64_t>(&mSwapchainImpl);
} }
@ -61,13 +45,11 @@ namespace utils {
} }
private: private:
std::unique_ptr<dawn_native::Instance> mInstance;
dawnDevice mBackendDevice = nullptr;
dawnSwapChainImplementation mSwapchainImpl = {}; dawnSwapChainImplementation mSwapchainImpl = {};
}; };
BackendBinding* CreateD3D12Binding() { BackendBinding* CreateD3D12Binding(GLFWwindow* window, dawnDevice device) {
return new D3D12Binding; return new D3D12Binding(window, device);
} }
} // namespace utils } // namespace utils

View File

@ -110,26 +110,7 @@ namespace utils {
class MetalBinding : public BackendBinding { class MetalBinding : public BackendBinding {
public: public:
void SetupGLFWWindowHints() override { MetalBinding(GLFWwindow* window, dawnDevice device) : BackendBinding(window, device) {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
}
dawnDevice CreateDevice() override {
// Make an instance and find a Metal adapter
mInstance = std::make_unique<dawn_native::Instance>();
mInstance->DiscoverDefaultAdapters();
std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
for (dawn_native::Adapter adapter : adapters) {
if (adapter.GetBackendType() == dawn_native::BackendType::Metal) {
dawnDevice device = adapter.CreateDevice();
mMetalDevice = dawn_native::metal::GetMetalDevice(device);
return device;
}
}
UNREACHABLE();
return {};
} }
uint64_t GetSwapChainImplementation() override { uint64_t GetSwapChainImplementation() override {
@ -145,12 +126,10 @@ namespace utils {
} }
private: private:
std::unique_ptr<dawn_native::Instance> mInstance;
id<MTLDevice> mMetalDevice = nil;
dawnSwapChainImplementation mSwapchainImpl = {}; dawnSwapChainImplementation mSwapchainImpl = {};
}; };
BackendBinding* CreateMetalBinding() { BackendBinding* CreateMetalBinding(GLFWwindow* window, dawnDevice device) {
return new MetalBinding; return new MetalBinding(window, device);
} }
} }

View File

@ -23,23 +23,9 @@ namespace utils {
class NullBinding : public BackendBinding { class NullBinding : public BackendBinding {
public: public:
void SetupGLFWWindowHints() override { NullBinding(GLFWwindow* window, dawnDevice device) : BackendBinding(window, device) {
} }
dawnDevice CreateDevice() override {
// Make an instance and find the null adapter
mInstance = std::make_unique<dawn_native::Instance>();
mInstance->DiscoverDefaultAdapters();
std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
for (dawn_native::Adapter adapter : adapters) {
if (adapter.GetBackendType() == dawn_native::BackendType::Null) {
return adapter.CreateDevice();
}
}
UNREACHABLE();
return {};
}
uint64_t GetSwapChainImplementation() override { uint64_t GetSwapChainImplementation() override {
if (mSwapchainImpl.userData == nullptr) { if (mSwapchainImpl.userData == nullptr) {
mSwapchainImpl = dawn_native::null::CreateNativeSwapChainImpl(); mSwapchainImpl = dawn_native::null::CreateNativeSwapChainImpl();
@ -51,12 +37,11 @@ namespace utils {
} }
private: private:
std::unique_ptr<dawn_native::Instance> mInstance;
dawnSwapChainImplementation mSwapchainImpl = {}; dawnSwapChainImplementation mSwapchainImpl = {};
}; };
BackendBinding* CreateNullBinding() { BackendBinding* CreateNullBinding(GLFWwindow* window, dawnDevice device) {
return new NullBinding; return new NullBinding(window, device);
} }
} // namespace utils } // namespace utils

View File

@ -95,36 +95,9 @@ namespace utils {
class OpenGLBinding : public BackendBinding { class OpenGLBinding : public BackendBinding {
public: public:
void SetupGLFWWindowHints() override { OpenGLBinding(GLFWwindow* window, dawnDevice device) : BackendBinding(window, device) {
#if defined(DAWN_PLATFORM_APPLE)
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#else
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#endif
}
dawnDevice CreateDevice() override {
glfwMakeContextCurrent(mWindow);
// Load the GL entry points in our copy of the glad static library // Load the GL entry points in our copy of the glad static library
gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress)); gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress));
// Make an instance and "discover" an OpenGL adapter with glfw's getProc
mInstance = std::make_unique<dawn_native::Instance>();
dawn_native::opengl::AdapterDiscoveryOptions adapterOptions;
adapterOptions.getProc = reinterpret_cast<void* (*)(const char*)>(glfwGetProcAddress);
mInstance->DiscoverAdapters(&adapterOptions);
std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
ASSERT(adapters.size() == 1);
return adapters[0].CreateDevice();
} }
uint64_t GetSwapChainImplementation() override { uint64_t GetSwapChainImplementation() override {
@ -139,12 +112,11 @@ namespace utils {
} }
private: private:
std::unique_ptr<dawn_native::Instance> mInstance;
dawnSwapChainImplementation mSwapchainImpl = {}; dawnSwapChainImplementation mSwapchainImpl = {};
}; };
BackendBinding* CreateOpenGLBinding() { BackendBinding* CreateOpenGLBinding(GLFWwindow* window, dawnDevice device) {
return new OpenGLBinding; return new OpenGLBinding(window, device);
} }
} // namespace utils } // namespace utils

View File

@ -26,25 +26,9 @@ namespace utils {
class VulkanBinding : public BackendBinding { class VulkanBinding : public BackendBinding {
public: public:
void SetupGLFWWindowHints() override { VulkanBinding(GLFWwindow* window, dawnDevice device) : BackendBinding(window, device) {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
} }
dawnDevice CreateDevice() override {
// Make an instance and find a Vulkan adapter
mInstance = std::make_unique<dawn_native::Instance>();
mInstance->DiscoverDefaultAdapters();
std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
for (dawn_native::Adapter adapter : adapters) {
if (adapter.GetBackendType() == dawn_native::BackendType::Vulkan) {
mDevice = adapter.CreateDevice();
return mDevice;
}
}
UNREACHABLE();
return {};
}
uint64_t GetSwapChainImplementation() override { uint64_t GetSwapChainImplementation() override {
if (mSwapchainImpl.userData == nullptr) { if (mSwapchainImpl.userData == nullptr) {
VkSurfaceKHR surface = VK_NULL_HANDLE; VkSurfaceKHR surface = VK_NULL_HANDLE;
@ -63,13 +47,11 @@ namespace utils {
} }
private: private:
std::unique_ptr<dawn_native::Instance> mInstance;
dawnDevice mDevice = nullptr;
dawnSwapChainImplementation mSwapchainImpl = {}; dawnSwapChainImplementation mSwapchainImpl = {};
}; };
BackendBinding* CreateVulkanBinding() { BackendBinding* CreateVulkanBinding(GLFWwindow* window, dawnDevice device) {
return new VulkanBinding; return new VulkanBinding(window, device);
} }
} // namespace utils } // namespace utils