mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-12 16:15:55 +00:00
OpenGL: Implement the backend connection and adapter.
The OpenGL backend can't gather discover default adapters because it needs getProc to do anything so we add DiscoverAdapters method to Instance that takes backend-specific options. dawn_native::opengl::CreateDevice is removed in favor of the adapter path so OpenGLBinding is modified to create an instance locally. This is only temporary until all backends support adapters, at which point a lot of *Binding code will be factored. Also contains a small fix for Result<T, E> with movable types. BUG=dawn:29 Change-Id: I4eb3d4a14a871af73e1872132aff72b45e5fe566 Reviewed-on: https://dawn-review.googlesource.com/c/3663 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
ab8eb2d6ed
commit
90e594ee8b
2
BUILD.gn
2
BUILD.gn
@ -535,6 +535,8 @@ source_set("libdawn_native_sources") {
|
||||
if (dawn_enable_opengl) {
|
||||
deps += [ "third_party:glad" ]
|
||||
sources += [
|
||||
"src/dawn_native/opengl/BackendGL.cpp",
|
||||
"src/dawn_native/opengl/BackendGL.h",
|
||||
"src/dawn_native/opengl/BufferGL.cpp",
|
||||
"src/dawn_native/opengl/BufferGL.h",
|
||||
"src/dawn_native/opengl/CommandBufferGL.cpp",
|
||||
|
@ -282,11 +282,11 @@ E* Result<T*, E*>::GetErrorFromPayload(intptr_t payload) {
|
||||
|
||||
// Implementation of Result<T, E>
|
||||
template <typename T, typename E>
|
||||
Result<T, E>::Result(T&& success) : mType(Success), mSuccess(success) {
|
||||
Result<T, E>::Result(T&& success) : mType(Success), mSuccess(std::move(success)) {
|
||||
}
|
||||
|
||||
template <typename T, typename E>
|
||||
Result<T, E>::Result(E&& error) : mType(Error), mError(error) {
|
||||
Result<T, E>::Result(E&& error) : mType(Error), mError(std::move(error)) {
|
||||
}
|
||||
|
||||
template <typename T, typename E>
|
||||
@ -296,7 +296,7 @@ Result<T, E>::~Result() {
|
||||
|
||||
template <typename T, typename E>
|
||||
Result<T, E>::Result(Result<T, E>&& other)
|
||||
: mType(other.mType), mError(std::move(other.mError)), mSuccess(other.mSuccess) {
|
||||
: mType(other.mType), mError(std::move(other.mError)), mSuccess(std::move(other.mSuccess)) {
|
||||
other.mType = Acquired;
|
||||
}
|
||||
template <typename T, typename E>
|
||||
|
@ -28,4 +28,9 @@ namespace dawn_native {
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> BackendConnection::DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* options) {
|
||||
return DAWN_VALIDATION_ERROR("DiscoverAdapters not implemented for this backend.");
|
||||
}
|
||||
|
||||
} // namespace dawn_native
|
||||
|
@ -36,6 +36,10 @@ namespace dawn_native {
|
||||
// options (such as debug adapters, custom driver libraries, etc.)
|
||||
virtual std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() = 0;
|
||||
|
||||
// Returns new adapters created with the backend-specific options.
|
||||
virtual ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* options);
|
||||
|
||||
private:
|
||||
InstanceBase* mInstance = nullptr;
|
||||
BackendType mType;
|
||||
|
@ -54,6 +54,11 @@ namespace dawn_native {
|
||||
return reinterpret_cast<dawnDevice>(mImpl->CreateDevice());
|
||||
}
|
||||
|
||||
// AdapterDiscoverOptionsBase
|
||||
|
||||
AdapterDiscoveryOptionsBase::AdapterDiscoveryOptionsBase(BackendType type) : backendType(type) {
|
||||
}
|
||||
|
||||
// Instance
|
||||
|
||||
Instance::Instance() : mImpl(new InstanceBase()) {
|
||||
@ -68,6 +73,10 @@ namespace dawn_native {
|
||||
mImpl->DiscoverDefaultAdapters();
|
||||
}
|
||||
|
||||
bool Instance::DiscoverAdapters(const AdapterDiscoveryOptionsBase* options) {
|
||||
return mImpl->DiscoverAdapters(options);
|
||||
}
|
||||
|
||||
std::vector<Adapter> Instance::GetAdapters() const {
|
||||
// Adapters are owned by mImpl so it is safe to return non RAII pointers to them
|
||||
std::vector<Adapter> adapters;
|
||||
|
@ -67,6 +67,11 @@ namespace dawn_native {
|
||||
}
|
||||
}
|
||||
|
||||
// This is just a wrapper around the real logic that uses Error.h error handling.
|
||||
bool InstanceBase::DiscoverAdapters(const AdapterDiscoveryOptionsBase* options) {
|
||||
return !ConsumedError(DiscoverAdaptersInternal(options));
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<AdapterBase>>& InstanceBase::GetAdapters() const {
|
||||
return mAdapters;
|
||||
}
|
||||
@ -103,6 +108,34 @@ namespace dawn_native {
|
||||
mBackendsConnected = true;
|
||||
}
|
||||
|
||||
ResultOrError<BackendConnection*> InstanceBase::FindBackend(BackendType type) {
|
||||
for (std::unique_ptr<BackendConnection>& backend : mBackends) {
|
||||
if (backend->GetType() == type) {
|
||||
return backend.get();
|
||||
}
|
||||
}
|
||||
|
||||
return DAWN_VALIDATION_ERROR("Backend isn't present.");
|
||||
}
|
||||
|
||||
MaybeError InstanceBase::DiscoverAdaptersInternal(const AdapterDiscoveryOptionsBase* options) {
|
||||
EnsureBackendConnections();
|
||||
|
||||
BackendConnection* backend;
|
||||
DAWN_TRY_ASSIGN(backend, FindBackend(options->backendType));
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> newAdapters;
|
||||
DAWN_TRY_ASSIGN(newAdapters, backend->DiscoverAdapters(options));
|
||||
|
||||
for (std::unique_ptr<AdapterBase>& adapter : newAdapters) {
|
||||
ASSERT(adapter->GetBackendType() == backend->GetType());
|
||||
ASSERT(adapter->GetInstance() == this);
|
||||
mAdapters.push_back(std::move(adapter));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool InstanceBase::ConsumedError(MaybeError maybeError) {
|
||||
if (maybeError.IsError()) {
|
||||
ErrorData* error = maybeError.AcquireError();
|
||||
|
@ -34,6 +34,7 @@ namespace dawn_native {
|
||||
InstanceBase& operator=(const InstanceBase& other) = delete;
|
||||
|
||||
void DiscoverDefaultAdapters();
|
||||
bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options);
|
||||
|
||||
const std::vector<std::unique_ptr<AdapterBase>>& GetAdapters() const;
|
||||
|
||||
@ -41,7 +42,13 @@ namespace dawn_native {
|
||||
bool ConsumedError(MaybeError maybeError);
|
||||
|
||||
private:
|
||||
// Lazily creates connections to all backends that have been compiled.
|
||||
void EnsureBackendConnections();
|
||||
// Finds the BackendConnection for `type` or returns an error.
|
||||
ResultOrError<BackendConnection*> FindBackend(BackendType type);
|
||||
|
||||
MaybeError DiscoverAdaptersInternal(const AdapterDiscoveryOptionsBase* options);
|
||||
|
||||
bool mBackendsConnected = false;
|
||||
|
||||
std::vector<std::unique_ptr<BackendConnection>> mBackends;
|
||||
|
@ -36,9 +36,9 @@ namespace dawn_native { namespace null {
|
||||
}
|
||||
};
|
||||
|
||||
class NullBackend : public BackendConnection {
|
||||
class Backend : public BackendConnection {
|
||||
public:
|
||||
NullBackend(InstanceBase* instance) : BackendConnection(instance, BackendType::Null) {
|
||||
Backend(InstanceBase* instance) : BackendConnection(instance, BackendType::Null) {
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override {
|
||||
@ -55,7 +55,7 @@ namespace dawn_native { namespace null {
|
||||
}
|
||||
|
||||
BackendConnection* Connect(InstanceBase* instance) {
|
||||
return new NullBackend(instance);
|
||||
return new Backend(instance);
|
||||
}
|
||||
|
||||
// Device
|
||||
|
90
src/dawn_native/opengl/BackendGL.cpp
Normal file
90
src/dawn_native/opengl/BackendGL.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
// Copyright 2019 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "dawn_native/opengl/BackendGL.h"
|
||||
|
||||
#include "dawn_native/OpenGLBackend.h"
|
||||
#include "dawn_native/opengl/DeviceGL.h"
|
||||
|
||||
namespace dawn_native { namespace opengl {
|
||||
|
||||
// Implementation of OpenGLBackend.h
|
||||
|
||||
AdapterDiscoveryOptions::AdapterDiscoveryOptions()
|
||||
: AdapterDiscoveryOptionsBase(BackendType::OpenGL) {
|
||||
}
|
||||
|
||||
// The OpenGL backend's Adapter.
|
||||
|
||||
class Adapter : public AdapterBase {
|
||||
public:
|
||||
Adapter(InstanceBase* instance, const AdapterDiscoveryOptions* options)
|
||||
: AdapterBase(instance, BackendType::OpenGL) {
|
||||
// Use getProc to populate GLAD.
|
||||
gladLoadGLLoader(reinterpret_cast<GLADloadproc>(options->getProc));
|
||||
|
||||
// Set state that never changes between devices.
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
|
||||
}
|
||||
virtual ~Adapter() = default;
|
||||
|
||||
private:
|
||||
ResultOrError<DeviceBase*> CreateDeviceImpl() override {
|
||||
// There is no limit on the number of devices created from this adapter because they can
|
||||
// all share the same backing OpenGL context.
|
||||
return {new Device};
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation of the OpenGL backend's BackendConnection
|
||||
|
||||
Backend::Backend(InstanceBase* instance) : BackendConnection(instance, BackendType::OpenGL) {
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||
// The OpenGL backend needs at least "getProcAddress" to discover an adapter.
|
||||
return {};
|
||||
}
|
||||
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> Backend::DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* optionsBase) {
|
||||
// TODO(cwallez@chromium.org): For now we can only create a single adapter because glad uses
|
||||
// static variables to store the pointers to OpenGL procs. Also, if we could create
|
||||
// multiple adapters, we would need to figure out what to do about MakeCurrent.
|
||||
if (mCreatedAdapter) {
|
||||
return DAWN_VALIDATION_ERROR("The OpenGL backend can only create a single adapter");
|
||||
}
|
||||
|
||||
ASSERT(optionsBase->backendType == BackendType::OpenGL);
|
||||
const AdapterDiscoveryOptions* options =
|
||||
reinterpret_cast<const AdapterDiscoveryOptions*>(optionsBase);
|
||||
|
||||
if (options->getProc == nullptr) {
|
||||
return DAWN_VALIDATION_ERROR("AdapterDiscoveryOptions::getProc must be set");
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> adapters;
|
||||
adapters.push_back(std::make_unique<Adapter>(GetInstance(), options));
|
||||
|
||||
mCreatedAdapter = true;
|
||||
return std::move(adapters);
|
||||
}
|
||||
|
||||
BackendConnection* Connect(InstanceBase* instance) {
|
||||
return new Backend(instance);
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::opengl
|
31
src/dawn_native/opengl/BackendGL.h
Normal file
31
src/dawn_native/opengl/BackendGL.h
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2019 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "dawn_native/BackendConnection.h"
|
||||
|
||||
namespace dawn_native { namespace opengl {
|
||||
|
||||
class Backend : public BackendConnection {
|
||||
public:
|
||||
Backend(InstanceBase* instance);
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* options) override;
|
||||
|
||||
private:
|
||||
bool mCreatedAdapter = false;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::opengl
|
@ -33,22 +33,6 @@
|
||||
|
||||
namespace dawn_native { namespace opengl {
|
||||
|
||||
dawnDevice CreateDevice(void* (*getProc)(const char*)) {
|
||||
gladLoadGLLoader(reinterpret_cast<GLADloadproc>(getProc));
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
|
||||
|
||||
return reinterpret_cast<dawnDevice>(new Device);
|
||||
}
|
||||
|
||||
BackendConnection* Connect(InstanceBase* instance) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Device
|
||||
|
||||
Device::Device() {
|
||||
CollectPCIInfo();
|
||||
}
|
||||
|
@ -64,6 +64,15 @@ namespace dawn_native {
|
||||
AdapterBase* mImpl = nullptr;
|
||||
};
|
||||
|
||||
// Base class for options passed to Instance::DiscoverAdapters.
|
||||
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptionsBase {
|
||||
public:
|
||||
const BackendType backendType;
|
||||
|
||||
protected:
|
||||
AdapterDiscoveryOptionsBase(BackendType type);
|
||||
};
|
||||
|
||||
// Represents a connection to dawn_native and is used for dependency injection, discovering
|
||||
// system adapters and injecting custom adapters (like a Swiftshader Vulkan adapter).
|
||||
//
|
||||
@ -81,6 +90,10 @@ namespace dawn_native {
|
||||
// adapters will later be returned by GetAdapters.
|
||||
void DiscoverDefaultAdapters();
|
||||
|
||||
// Adds adapters that can be discovered with the options provided (like a getProcAddress).
|
||||
// The backend is chosen based on the type of the options used. Returns true on success.
|
||||
bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options);
|
||||
|
||||
// Returns all the adapters that the instance knows about.
|
||||
std::vector<Adapter> GetAdapters() const;
|
||||
|
||||
|
@ -15,11 +15,16 @@
|
||||
#ifndef DAWNNATIVE_OPENGLBACKEND_H_
|
||||
#define DAWNNATIVE_OPENGLBACKEND_H_
|
||||
|
||||
#include <dawn/dawn.h>
|
||||
#include <dawn_native/dawn_native_export.h>
|
||||
#include <dawn_native/DawnNative.h>
|
||||
|
||||
namespace dawn_native { namespace opengl {
|
||||
DAWN_NATIVE_EXPORT dawnDevice CreateDevice(void* (*getProc)(const char*));
|
||||
|
||||
struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptions : public AdapterDiscoveryOptionsBase {
|
||||
AdapterDiscoveryOptions();
|
||||
|
||||
void* (*getProc)(const char*);
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::opengl
|
||||
|
||||
#endif // DAWNNATIVE_OPENGLBACKEND_H_
|
||||
|
@ -108,13 +108,23 @@ namespace utils {
|
||||
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
|
||||
gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress));
|
||||
|
||||
return dawn_native::opengl::CreateDevice(
|
||||
reinterpret_cast<void* (*)(const char*)>(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 {
|
||||
@ -129,6 +139,7 @@ namespace utils {
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<dawn_native::Instance> mInstance;
|
||||
dawnSwapChainImplementation mSwapchainImpl = {};
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user