Implement upstream RequestAdapter
Bug: dawn:160 Change-Id: Ifbce6f71fdf43a749c332bd691b63119929e0128 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/75640 Reviewed-by: Loko Kung <lokokung@google.com> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
11797b4b07
commit
a78192741e
|
@ -179,6 +179,8 @@ class [[nodiscard]] Result<Ref<T>, E> {
|
|||
|
||||
template <typename U>
|
||||
Result(Ref<U>&& success);
|
||||
template <typename U>
|
||||
Result(const Ref<U>& success);
|
||||
Result(std::unique_ptr<E> error);
|
||||
|
||||
template <typename U>
|
||||
|
@ -411,6 +413,11 @@ Result<Ref<T>, E>::Result(Ref<U>&& success)
|
|||
static_assert(std::is_convertible<U*, T*>::value, "");
|
||||
}
|
||||
|
||||
template <typename T, typename E>
|
||||
template <typename U>
|
||||
Result<Ref<T>, E>::Result(const Ref<U>& success) : Result(Ref<U>(success)) {
|
||||
}
|
||||
|
||||
template <typename T, typename E>
|
||||
Result<Ref<T>, E>::Result(std::unique_ptr<E> error)
|
||||
: mPayload(detail::MakePayload(error.release(), detail::Error)) {
|
||||
|
|
|
@ -107,10 +107,15 @@ namespace dawn::native {
|
|||
void AdapterBase::APIRequestDevice(const DeviceDescriptor* descriptor,
|
||||
WGPURequestDeviceCallback callback,
|
||||
void* userdata) {
|
||||
static constexpr DeviceDescriptor kDefaultDescriptor = {};
|
||||
if (descriptor == nullptr) {
|
||||
descriptor = &kDefaultDescriptor;
|
||||
}
|
||||
auto result = CreateDeviceInternal(descriptor);
|
||||
|
||||
if (result.IsError()) {
|
||||
std::unique_ptr<ErrorData> errorData = result.AcquireError();
|
||||
// TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
|
||||
callback(WGPURequestDeviceStatus_Error, nullptr,
|
||||
errorData->GetFormattedMessage().c_str(), userdata);
|
||||
return;
|
||||
|
@ -120,6 +125,7 @@ namespace dawn::native {
|
|||
|
||||
WGPURequestDeviceStatus status =
|
||||
device == nullptr ? WGPURequestDeviceStatus_Unknown : WGPURequestDeviceStatus_Success;
|
||||
// TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
|
||||
callback(status, ToAPI(device.Detach()), nullptr, userdata);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace dawn::native {
|
|||
return mInstance;
|
||||
}
|
||||
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> BackendConnection::DiscoverAdapters(
|
||||
ResultOrError<std::vector<Ref<AdapterBase>>> BackendConnection::DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* options) {
|
||||
return DAWN_FORMAT_VALIDATION_ERROR("DiscoverAdapters not implemented for this backend.");
|
||||
}
|
||||
|
|
|
@ -34,10 +34,10 @@ namespace dawn::native {
|
|||
|
||||
// Returns all the adapters for the system that can be created by the backend, without extra
|
||||
// options (such as debug adapters, custom driver libraries, etc.)
|
||||
virtual std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() = 0;
|
||||
virtual std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() = 0;
|
||||
|
||||
// Returns new adapters created with the backend-specific options.
|
||||
virtual ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> DiscoverAdapters(
|
||||
virtual ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* options);
|
||||
|
||||
private:
|
||||
|
|
|
@ -76,14 +76,33 @@ namespace dawn::native {
|
|||
Adapter::Adapter() = default;
|
||||
|
||||
Adapter::Adapter(AdapterBase* impl) : mImpl(impl) {
|
||||
if (mImpl != nullptr) {
|
||||
mImpl->Reference();
|
||||
}
|
||||
}
|
||||
|
||||
Adapter::~Adapter() {
|
||||
if (mImpl != nullptr) {
|
||||
mImpl->Release();
|
||||
}
|
||||
mImpl = nullptr;
|
||||
}
|
||||
|
||||
Adapter::Adapter(const Adapter& other) = default;
|
||||
Adapter& Adapter::operator=(const Adapter& other) = default;
|
||||
Adapter::Adapter(const Adapter& other) : Adapter(other.mImpl) {
|
||||
}
|
||||
|
||||
Adapter& Adapter::operator=(const Adapter& other) {
|
||||
if (this != &other) {
|
||||
if (mImpl) {
|
||||
mImpl->Release();
|
||||
}
|
||||
mImpl = other.mImpl;
|
||||
if (mImpl) {
|
||||
mImpl->Reference();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Adapter::GetProperties(wgpu::AdapterProperties* properties) const {
|
||||
GetProperties(reinterpret_cast<WGPUAdapterProperties*>(properties));
|
||||
|
@ -189,8 +208,8 @@ namespace dawn::native {
|
|||
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;
|
||||
for (const std::unique_ptr<AdapterBase>& adapter : mImpl->GetAdapters()) {
|
||||
adapters.push_back({adapter.get()});
|
||||
for (const Ref<AdapterBase>& adapter : mImpl->GetAdapters()) {
|
||||
adapters.push_back({adapter.Get()});
|
||||
}
|
||||
return adapters;
|
||||
}
|
||||
|
|
|
@ -535,6 +535,7 @@ namespace dawn::native {
|
|||
}
|
||||
ErrorScope scope = mErrorScopeStack->Pop();
|
||||
if (callback != nullptr) {
|
||||
// TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
|
||||
callback(static_cast<WGPUErrorType>(scope.GetErrorType()), scope.GetErrorMessage(),
|
||||
userdata);
|
||||
}
|
||||
|
@ -973,6 +974,7 @@ namespace dawn::native {
|
|||
// callback.
|
||||
if (maybeResult.IsError()) {
|
||||
std::unique_ptr<ErrorData> error = maybeResult.AcquireError();
|
||||
// TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
|
||||
callback(WGPUCreatePipelineAsyncStatus_Error, nullptr, error->GetMessage().c_str(),
|
||||
userdata);
|
||||
}
|
||||
|
@ -1015,6 +1017,7 @@ namespace dawn::native {
|
|||
// callback.
|
||||
if (maybeResult.IsError()) {
|
||||
std::unique_ptr<ErrorData> error = maybeResult.AcquireError();
|
||||
// TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
|
||||
callback(WGPUCreatePipelineAsyncStatus_Error, nullptr, error->GetMessage().c_str(),
|
||||
userdata);
|
||||
}
|
||||
|
@ -1325,6 +1328,7 @@ namespace dawn::native {
|
|||
Ref<ComputePipelineBase> cachedComputePipeline =
|
||||
GetCachedComputePipeline(uninitializedComputePipeline.Get());
|
||||
if (cachedComputePipeline.Get() != nullptr) {
|
||||
// TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
|
||||
callback(WGPUCreatePipelineAsyncStatus_Success, ToAPI(cachedComputePipeline.Detach()),
|
||||
"", userdata);
|
||||
} else {
|
||||
|
@ -1471,6 +1475,7 @@ namespace dawn::native {
|
|||
Ref<RenderPipelineBase> cachedRenderPipeline =
|
||||
GetCachedRenderPipeline(uninitializedRenderPipeline.Get());
|
||||
if (cachedRenderPipeline != nullptr) {
|
||||
// TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
|
||||
callback(WGPUCreatePipelineAsyncStatus_Success, ToAPI(cachedRenderPipeline.Detach()),
|
||||
"", userdata);
|
||||
} else {
|
||||
|
|
|
@ -15,16 +15,24 @@
|
|||
#include "dawn_native/Instance.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "common/GPUInfo.h"
|
||||
#include "common/Log.h"
|
||||
#include "dawn_native/ErrorData.h"
|
||||
#include "dawn_native/Surface.h"
|
||||
#include "dawn_native/ValidationUtils_autogen.h"
|
||||
#include "dawn_platform/DawnPlatform.h"
|
||||
|
||||
// For SwiftShader fallback
|
||||
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||
# include "dawn_native/VulkanBackend.h"
|
||||
#endif // defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||
|
||||
#if defined(DAWN_USE_X11)
|
||||
# include "dawn_native/XlibXcbFunctions.h"
|
||||
#endif // defined(DAWN_USE_X11)
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace dawn::native {
|
||||
|
||||
// Forward definitions of each backend's "Connect" function that creates new BackendConnection.
|
||||
|
@ -102,7 +110,100 @@ namespace dawn::native {
|
|||
void InstanceBase::APIRequestAdapter(const RequestAdapterOptions* options,
|
||||
WGPURequestAdapterCallback callback,
|
||||
void* userdata) {
|
||||
callback(WGPURequestAdapterStatus_Error, nullptr, "Not implemented", userdata);
|
||||
static constexpr RequestAdapterOptions kDefaultOptions = {};
|
||||
if (options == nullptr) {
|
||||
options = &kDefaultOptions;
|
||||
}
|
||||
auto result = RequestAdapterInternal(options);
|
||||
if (result.IsError()) {
|
||||
auto err = result.AcquireError();
|
||||
std::string msg = err->GetFormattedMessage();
|
||||
// TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
|
||||
callback(WGPURequestAdapterStatus_Error, nullptr, msg.c_str(), userdata);
|
||||
} else {
|
||||
Ref<AdapterBase> adapter = result.AcquireSuccess();
|
||||
// TODO(crbug.com/dawn/1122): Call callbacks only on wgpuInstanceProcessEvents
|
||||
callback(WGPURequestAdapterStatus_Success, ToAPI(adapter.Detach()), nullptr, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
ResultOrError<Ref<AdapterBase>> InstanceBase::RequestAdapterInternal(
|
||||
const RequestAdapterOptions* options) {
|
||||
ASSERT(options != nullptr);
|
||||
if (options->forceFallbackAdapter) {
|
||||
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||
if (GetEnabledBackends()[wgpu::BackendType::Vulkan]) {
|
||||
dawn_native::vulkan::AdapterDiscoveryOptions vulkanOptions;
|
||||
vulkanOptions.forceSwiftShader = true;
|
||||
DAWN_TRY(DiscoverAdaptersInternal(&vulkanOptions));
|
||||
}
|
||||
#else
|
||||
return Ref<AdapterBase>(nullptr);
|
||||
#endif // defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||
} else {
|
||||
DiscoverDefaultAdapters();
|
||||
}
|
||||
|
||||
wgpu::AdapterType preferredType;
|
||||
switch (options->powerPreference) {
|
||||
case wgpu::PowerPreference::LowPower:
|
||||
preferredType = wgpu::AdapterType::IntegratedGPU;
|
||||
break;
|
||||
case wgpu::PowerPreference::Undefined:
|
||||
case wgpu::PowerPreference::HighPerformance:
|
||||
preferredType = wgpu::AdapterType::DiscreteGPU;
|
||||
break;
|
||||
}
|
||||
|
||||
std::optional<size_t> discreteGPUAdapterIndex;
|
||||
std::optional<size_t> integratedGPUAdapterIndex;
|
||||
std::optional<size_t> cpuAdapterIndex;
|
||||
std::optional<size_t> unknownAdapterIndex;
|
||||
|
||||
for (size_t i = 0; i < mAdapters.size(); ++i) {
|
||||
AdapterProperties properties;
|
||||
mAdapters[i]->APIGetProperties(&properties);
|
||||
|
||||
if (options->forceFallbackAdapter) {
|
||||
if (!gpu_info::IsSwiftshader(properties.vendorID, properties.deviceID)) {
|
||||
continue;
|
||||
}
|
||||
return mAdapters[i];
|
||||
}
|
||||
if (properties.adapterType == preferredType) {
|
||||
return mAdapters[i];
|
||||
}
|
||||
switch (properties.adapterType) {
|
||||
case wgpu::AdapterType::DiscreteGPU:
|
||||
discreteGPUAdapterIndex = i;
|
||||
break;
|
||||
case wgpu::AdapterType::IntegratedGPU:
|
||||
integratedGPUAdapterIndex = i;
|
||||
break;
|
||||
case wgpu::AdapterType::CPU:
|
||||
cpuAdapterIndex = i;
|
||||
break;
|
||||
case wgpu::AdapterType::Unknown:
|
||||
unknownAdapterIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// For now, we always prefer the discrete GPU
|
||||
if (discreteGPUAdapterIndex) {
|
||||
return mAdapters[*discreteGPUAdapterIndex];
|
||||
}
|
||||
if (integratedGPUAdapterIndex) {
|
||||
return mAdapters[*integratedGPUAdapterIndex];
|
||||
}
|
||||
if (cpuAdapterIndex) {
|
||||
return mAdapters[*cpuAdapterIndex];
|
||||
}
|
||||
if (unknownAdapterIndex) {
|
||||
return mAdapters[*unknownAdapterIndex];
|
||||
}
|
||||
|
||||
return Ref<AdapterBase>(nullptr);
|
||||
}
|
||||
|
||||
void InstanceBase::DiscoverDefaultAdapters() {
|
||||
|
@ -116,10 +217,9 @@ namespace dawn::native {
|
|||
|
||||
// Query and merge all default adapters for all backends
|
||||
for (std::unique_ptr<BackendConnection>& backend : mBackends) {
|
||||
std::vector<std::unique_ptr<AdapterBase>> backendAdapters =
|
||||
backend->DiscoverDefaultAdapters();
|
||||
std::vector<Ref<AdapterBase>> backendAdapters = backend->DiscoverDefaultAdapters();
|
||||
|
||||
for (std::unique_ptr<AdapterBase>& adapter : backendAdapters) {
|
||||
for (Ref<AdapterBase>& adapter : backendAdapters) {
|
||||
ASSERT(adapter->GetBackendType() == backend->GetType());
|
||||
ASSERT(adapter->GetInstance() == this);
|
||||
mAdapters.push_back(std::move(adapter));
|
||||
|
@ -146,7 +246,7 @@ namespace dawn::native {
|
|||
return mFeaturesInfo.GetFeatureInfo(feature);
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<AdapterBase>>& InstanceBase::GetAdapters() const {
|
||||
const std::vector<Ref<AdapterBase>>& InstanceBase::GetAdapters() const {
|
||||
return mAdapters;
|
||||
}
|
||||
|
||||
|
@ -226,10 +326,10 @@ namespace dawn::native {
|
|||
}
|
||||
foundBackend = true;
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> newAdapters;
|
||||
std::vector<Ref<AdapterBase>> newAdapters;
|
||||
DAWN_TRY_ASSIGN(newAdapters, backend->DiscoverAdapters(options));
|
||||
|
||||
for (std::unique_ptr<AdapterBase>& adapter : newAdapters) {
|
||||
for (Ref<AdapterBase>& adapter : newAdapters) {
|
||||
ASSERT(adapter->GetBackendType() == backend->GetType());
|
||||
ASSERT(adapter->GetInstance() == this);
|
||||
mAdapters.push_back(std::move(adapter));
|
||||
|
@ -246,7 +346,6 @@ namespace dawn::native {
|
|||
|
||||
ASSERT(error != nullptr);
|
||||
dawn::InfoLog() << error->GetFormattedMessage();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace dawn::native {
|
|||
void DiscoverDefaultAdapters();
|
||||
bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options);
|
||||
|
||||
const std::vector<std::unique_ptr<AdapterBase>>& GetAdapters() const;
|
||||
const std::vector<Ref<AdapterBase>>& GetAdapters() const;
|
||||
|
||||
// Used to handle error that happen up to device creation.
|
||||
bool ConsumedError(MaybeError maybeError);
|
||||
|
@ -96,6 +96,9 @@ namespace dawn::native {
|
|||
|
||||
MaybeError DiscoverAdaptersInternal(const AdapterDiscoveryOptionsBase* options);
|
||||
|
||||
ResultOrError<Ref<AdapterBase>> RequestAdapterInternal(
|
||||
const RequestAdapterOptions* options);
|
||||
|
||||
BackendsBitset mBackendsConnected;
|
||||
|
||||
bool mDiscoveredDefaultAdapters = false;
|
||||
|
@ -107,7 +110,7 @@ namespace dawn::native {
|
|||
std::unique_ptr<dawn::platform::Platform> mDefaultPlatform;
|
||||
|
||||
std::vector<std::unique_ptr<BackendConnection>> mBackends;
|
||||
std::vector<std::unique_ptr<AdapterBase>> mAdapters;
|
||||
std::vector<Ref<AdapterBase>> mAdapters;
|
||||
|
||||
FeaturesInfo mFeaturesInfo;
|
||||
TogglesInfo mTogglesInfo;
|
||||
|
|
|
@ -66,13 +66,12 @@ namespace dawn::native::d3d12 {
|
|||
return std::move(factory);
|
||||
}
|
||||
|
||||
ResultOrError<std::unique_ptr<AdapterBase>> CreateAdapterFromIDXGIAdapter(
|
||||
ResultOrError<Ref<AdapterBase>> CreateAdapterFromIDXGIAdapter(
|
||||
Backend* backend,
|
||||
ComPtr<IDXGIAdapter> dxgiAdapter) {
|
||||
ComPtr<IDXGIAdapter3> dxgiAdapter3;
|
||||
DAWN_TRY(CheckHRESULT(dxgiAdapter.As(&dxgiAdapter3), "DXGIAdapter retrieval"));
|
||||
std::unique_ptr<Adapter> adapter =
|
||||
std::make_unique<Adapter>(backend, std::move(dxgiAdapter3));
|
||||
Ref<Adapter> adapter = AcquireRef(new Adapter(backend, std::move(dxgiAdapter3)));
|
||||
DAWN_TRY(adapter->Initialize());
|
||||
|
||||
return {std::move(adapter)};
|
||||
|
@ -150,7 +149,7 @@ namespace dawn::native::d3d12 {
|
|||
return mFunctions.get();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||
AdapterDiscoveryOptions options;
|
||||
auto result = DiscoverAdapters(&options);
|
||||
if (result.IsError()) {
|
||||
|
@ -160,16 +159,16 @@ namespace dawn::native::d3d12 {
|
|||
return result.AcquireSuccess();
|
||||
}
|
||||
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> Backend::DiscoverAdapters(
|
||||
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* optionsBase) {
|
||||
ASSERT(optionsBase->backendType == WGPUBackendType_D3D12);
|
||||
const AdapterDiscoveryOptions* options =
|
||||
static_cast<const AdapterDiscoveryOptions*>(optionsBase);
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> adapters;
|
||||
std::vector<Ref<AdapterBase>> adapters;
|
||||
if (options->dxgiAdapter != nullptr) {
|
||||
// |dxgiAdapter| was provided. Discover just that adapter.
|
||||
std::unique_ptr<AdapterBase> adapter;
|
||||
Ref<AdapterBase> adapter;
|
||||
DAWN_TRY_ASSIGN(adapter, CreateAdapterFromIDXGIAdapter(this, options->dxgiAdapter));
|
||||
adapters.push_back(std::move(adapter));
|
||||
return std::move(adapters);
|
||||
|
@ -183,14 +182,14 @@ namespace dawn::native::d3d12 {
|
|||
}
|
||||
|
||||
ASSERT(dxgiAdapter != nullptr);
|
||||
ResultOrError<std::unique_ptr<AdapterBase>> adapter =
|
||||
ResultOrError<Ref<AdapterBase>> adapter =
|
||||
CreateAdapterFromIDXGIAdapter(this, dxgiAdapter);
|
||||
if (adapter.IsError()) {
|
||||
GetInstance()->ConsumedError(adapter.AcquireError());
|
||||
continue;
|
||||
}
|
||||
|
||||
adapters.push_back(std::move(adapter.AcquireSuccess()));
|
||||
adapters.push_back(adapter.AcquireSuccess());
|
||||
}
|
||||
|
||||
return adapters;
|
||||
|
|
|
@ -40,8 +40,8 @@ namespace dawn::native::d3d12 {
|
|||
|
||||
const PlatformFunctions* GetFunctions() const;
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> DiscoverAdapters(
|
||||
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* optionsBase) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -23,8 +23,8 @@ namespace dawn::native::metal {
|
|||
public:
|
||||
Backend(InstanceBase* instance);
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> DiscoverAdapters(
|
||||
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* optionsBase) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -558,7 +558,7 @@ namespace dawn::native::metal {
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||
AdapterDiscoveryOptions options;
|
||||
auto result = DiscoverAdapters(&options);
|
||||
if (result.IsError()) {
|
||||
|
@ -568,11 +568,11 @@ namespace dawn::native::metal {
|
|||
return result.AcquireSuccess();
|
||||
}
|
||||
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> Backend::DiscoverAdapters(
|
||||
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* optionsBase) {
|
||||
ASSERT(optionsBase->backendType == WGPUBackendType_Metal);
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> adapters;
|
||||
std::vector<Ref<AdapterBase>> adapters;
|
||||
BOOL supportedVersion = NO;
|
||||
#if defined(DAWN_PLATFORM_MACOS)
|
||||
if (@available(macOS 10.11, *)) {
|
||||
|
@ -581,7 +581,7 @@ namespace dawn::native::metal {
|
|||
NSRef<NSArray<id<MTLDevice>>> devices = AcquireNSRef(MTLCopyAllDevices());
|
||||
|
||||
for (id<MTLDevice> device in devices.Get()) {
|
||||
std::unique_ptr<Adapter> adapter = std::make_unique<Adapter>(GetInstance(), device);
|
||||
Ref<Adapter> adapter = AcquireRef(new Adapter(GetInstance(), device));
|
||||
if (!GetInstance()->ConsumedError(adapter->Initialize())) {
|
||||
adapters.push_back(std::move(adapter));
|
||||
}
|
||||
|
@ -593,8 +593,8 @@ namespace dawn::native::metal {
|
|||
if (@available(iOS 8.0, *)) {
|
||||
supportedVersion = YES;
|
||||
// iOS only has a single device so MTLCopyAllDevices doesn't exist there.
|
||||
std::unique_ptr<Adapter> adapter =
|
||||
std::make_unique<Adapter>(GetInstance(), MTLCreateSystemDefaultDevice());
|
||||
Ref<Adapter> adapter =
|
||||
AcquireRef(new Adapter(GetInstance(), MTLCreateSystemDefaultDevice()));
|
||||
if (!GetInstance()->ConsumedError(adapter->Initialize())) {
|
||||
adapters.push_back(std::move(adapter));
|
||||
}
|
||||
|
|
|
@ -71,11 +71,11 @@ namespace dawn::native::null {
|
|||
Backend(InstanceBase* instance) : BackendConnection(instance, wgpu::BackendType::Null) {
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override {
|
||||
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() override {
|
||||
// There is always a single Null adapter because it is purely CPU based and doesn't
|
||||
// depend on the system.
|
||||
std::vector<std::unique_ptr<AdapterBase>> adapters;
|
||||
std::unique_ptr<Adapter> adapter = std::make_unique<Adapter>(GetInstance());
|
||||
std::vector<Ref<AdapterBase>> adapters;
|
||||
Ref<Adapter> adapter = AcquireRef(new Adapter(GetInstance()));
|
||||
adapters.push_back(std::move(adapter));
|
||||
return adapters;
|
||||
}
|
||||
|
|
|
@ -270,12 +270,12 @@ namespace dawn::native::opengl {
|
|||
: BackendConnection(instance, backendType) {
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||
// The OpenGL backend needs at least "getProcAddress" to discover an adapter.
|
||||
return {};
|
||||
}
|
||||
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> Backend::DiscoverAdapters(
|
||||
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* optionsBase) {
|
||||
// TODO(cwallez@chromium.org): For now only create a single OpenGL adapter because don't
|
||||
// know how to handle MakeCurrent.
|
||||
|
@ -288,14 +288,13 @@ namespace dawn::native::opengl {
|
|||
DAWN_INVALID_IF(options->getProc == nullptr,
|
||||
"AdapterDiscoveryOptions::getProc must be set");
|
||||
|
||||
std::unique_ptr<Adapter> adapter = std::make_unique<Adapter>(
|
||||
GetInstance(), static_cast<wgpu::BackendType>(optionsBase->backendType));
|
||||
Ref<Adapter> adapter = AcquireRef(
|
||||
new Adapter(GetInstance(), static_cast<wgpu::BackendType>(optionsBase->backendType)));
|
||||
DAWN_TRY(adapter->InitializeGLFunctions(options->getProc));
|
||||
DAWN_TRY(adapter->Initialize());
|
||||
|
||||
mCreatedAdapter = true;
|
||||
std::vector<std::unique_ptr<AdapterBase>> adapters;
|
||||
adapters.push_back(std::unique_ptr<AdapterBase>(adapter.release()));
|
||||
std::vector<Ref<AdapterBase>> adapters{std::move(adapter)};
|
||||
return std::move(adapters);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ namespace dawn::native::opengl {
|
|||
public:
|
||||
Backend(InstanceBase* instance, wgpu::BackendType backendType);
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> DiscoverAdapters(
|
||||
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* options) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -395,7 +395,7 @@ namespace dawn::native::vulkan {
|
|||
|
||||
Backend::~Backend() = default;
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||
AdapterDiscoveryOptions options;
|
||||
auto result = DiscoverAdapters(&options);
|
||||
if (result.IsError()) {
|
||||
|
@ -405,14 +405,14 @@ namespace dawn::native::vulkan {
|
|||
return result.AcquireSuccess();
|
||||
}
|
||||
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> Backend::DiscoverAdapters(
|
||||
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* optionsBase) {
|
||||
ASSERT(optionsBase->backendType == WGPUBackendType_Vulkan);
|
||||
|
||||
const AdapterDiscoveryOptions* options =
|
||||
static_cast<const AdapterDiscoveryOptions*>(optionsBase);
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> adapters;
|
||||
std::vector<Ref<AdapterBase>> adapters;
|
||||
|
||||
InstanceBase* instance = GetInstance();
|
||||
for (ICD icd : kICDs) {
|
||||
|
@ -429,8 +429,8 @@ namespace dawn::native::vulkan {
|
|||
const std::vector<VkPhysicalDevice>& physicalDevices =
|
||||
mVulkanInstances[icd]->GetPhysicalDevices();
|
||||
for (uint32_t i = 0; i < physicalDevices.size(); ++i) {
|
||||
std::unique_ptr<Adapter> adapter = std::make_unique<Adapter>(
|
||||
instance, mVulkanInstances[icd].Get(), physicalDevices[i]);
|
||||
Ref<Adapter> adapter = AcquireRef(
|
||||
new Adapter(instance, mVulkanInstances[icd].Get(), physicalDevices[i]));
|
||||
if (instance->ConsumedError(adapter->Initialize())) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -73,8 +73,8 @@ namespace dawn::native::vulkan {
|
|||
|
||||
MaybeError Initialize();
|
||||
|
||||
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> DiscoverAdapters(
|
||||
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
||||
const AdapterDiscoveryOptionsBase* optionsBase) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,10 +13,13 @@
|
|||
// limitations under the License.
|
||||
|
||||
#include "common/GPUInfo.h"
|
||||
#include "common/Log.h"
|
||||
#include "common/Platform.h"
|
||||
#include "common/SystemUtils.h"
|
||||
#include "dawn/dawn_proc.h"
|
||||
#include "dawn/webgpu_cpp.h"
|
||||
#include "dawn_native/DawnNative.h"
|
||||
#include "tests/MockCallback.h"
|
||||
|
||||
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||
# include "dawn_native/VulkanBackend.h"
|
||||
|
@ -43,6 +46,8 @@
|
|||
|
||||
namespace {
|
||||
|
||||
using namespace testing;
|
||||
|
||||
class AdapterDiscoveryTests : public ::testing::Test {};
|
||||
|
||||
#if defined(DAWN_ENABLE_BACKEND_VULKAN)
|
||||
|
@ -266,4 +271,145 @@ namespace {
|
|||
}
|
||||
#endif // defined(DAWN_ENABLE_BACKEND_VULKAN) && defined(DAWN_ENABLE_BACKEND_METAL)
|
||||
|
||||
class AdapterCreationTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
dawnProcSetProcs(&dawn_native::GetProcs());
|
||||
|
||||
{
|
||||
auto nativeInstance = std::make_unique<dawn_native::Instance>();
|
||||
nativeInstance->DiscoverDefaultAdapters();
|
||||
for (dawn_native::Adapter& nativeAdapter : nativeInstance->GetAdapters()) {
|
||||
anyAdapterAvailable = true;
|
||||
|
||||
wgpu::AdapterProperties properties;
|
||||
nativeAdapter.GetProperties(&properties);
|
||||
swiftShaderAvailable =
|
||||
swiftShaderAvailable ||
|
||||
gpu_info::IsSwiftshader(properties.vendorID, properties.deviceID);
|
||||
discreteGPUAvailable = discreteGPUAvailable ||
|
||||
properties.adapterType == wgpu::AdapterType::DiscreteGPU;
|
||||
integratedGPUAvailable =
|
||||
integratedGPUAvailable ||
|
||||
properties.adapterType == wgpu::AdapterType::IntegratedGPU;
|
||||
}
|
||||
}
|
||||
|
||||
instance = wgpu::CreateInstance();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
instance = nullptr;
|
||||
dawnProcSetProcs(nullptr);
|
||||
}
|
||||
|
||||
wgpu::Instance instance;
|
||||
bool anyAdapterAvailable = false;
|
||||
bool swiftShaderAvailable = false;
|
||||
bool discreteGPUAvailable = false;
|
||||
bool integratedGPUAvailable = false;
|
||||
};
|
||||
|
||||
// Test that requesting the default adapter works
|
||||
TEST_F(AdapterCreationTest, DefaultAdapter) {
|
||||
wgpu::RequestAdapterOptions options = {};
|
||||
|
||||
MockCallback<WGPURequestAdapterCallback> cb;
|
||||
|
||||
WGPUAdapter cAdapter = nullptr;
|
||||
EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Success, _, nullptr, this))
|
||||
.WillOnce(SaveArg<1>(&cAdapter));
|
||||
instance.RequestAdapter(&options, cb.Callback(), cb.MakeUserdata(this));
|
||||
|
||||
wgpu::Adapter adapter = wgpu::Adapter::Acquire(cAdapter);
|
||||
EXPECT_EQ(adapter != nullptr, anyAdapterAvailable);
|
||||
}
|
||||
|
||||
// Test that passing nullptr for the options gets the default adapter
|
||||
TEST_F(AdapterCreationTest, NullGivesDefaultAdapter) {
|
||||
wgpu::RequestAdapterOptions options = {};
|
||||
|
||||
MockCallback<WGPURequestAdapterCallback> cb;
|
||||
|
||||
WGPUAdapter cAdapter = nullptr;
|
||||
EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Success, _, nullptr, this))
|
||||
.WillOnce(SaveArg<1>(&cAdapter));
|
||||
instance.RequestAdapter(&options, cb.Callback(), cb.MakeUserdata(this));
|
||||
|
||||
wgpu::Adapter adapter = wgpu::Adapter::Acquire(cAdapter);
|
||||
EXPECT_EQ(adapter != nullptr, anyAdapterAvailable);
|
||||
|
||||
EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Success, _, nullptr, this + 1))
|
||||
.WillOnce(SaveArg<1>(&cAdapter));
|
||||
instance.RequestAdapter(nullptr, cb.Callback(), cb.MakeUserdata(this + 1));
|
||||
|
||||
wgpu::Adapter adapter2 = wgpu::Adapter::Acquire(cAdapter);
|
||||
EXPECT_EQ(adapter.Get(), adapter2.Get());
|
||||
}
|
||||
|
||||
// Test that requesting the fallback adapter returns SwiftShader.
|
||||
TEST_F(AdapterCreationTest, FallbackAdapter) {
|
||||
wgpu::RequestAdapterOptions options = {};
|
||||
options.forceFallbackAdapter = true;
|
||||
|
||||
MockCallback<WGPURequestAdapterCallback> cb;
|
||||
|
||||
WGPUAdapter cAdapter = nullptr;
|
||||
EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Success, _, nullptr, this))
|
||||
.WillOnce(SaveArg<1>(&cAdapter));
|
||||
instance.RequestAdapter(&options, cb.Callback(), cb.MakeUserdata(this));
|
||||
|
||||
wgpu::Adapter adapter = wgpu::Adapter::Acquire(cAdapter);
|
||||
EXPECT_EQ(adapter != nullptr, swiftShaderAvailable);
|
||||
if (adapter != nullptr) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
|
||||
EXPECT_EQ(properties.adapterType, wgpu::AdapterType::CPU);
|
||||
EXPECT_TRUE(gpu_info::IsSwiftshader(properties.vendorID, properties.deviceID));
|
||||
}
|
||||
}
|
||||
|
||||
// Test that requesting a high performance GPU works
|
||||
TEST_F(AdapterCreationTest, PreferHighPerformance) {
|
||||
wgpu::RequestAdapterOptions options = {};
|
||||
options.powerPreference = wgpu::PowerPreference::HighPerformance;
|
||||
|
||||
MockCallback<WGPURequestAdapterCallback> cb;
|
||||
|
||||
WGPUAdapter cAdapter = nullptr;
|
||||
EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Success, _, nullptr, this))
|
||||
.WillOnce(SaveArg<1>(&cAdapter));
|
||||
instance.RequestAdapter(&options, cb.Callback(), cb.MakeUserdata(this));
|
||||
|
||||
wgpu::Adapter adapter = wgpu::Adapter::Acquire(cAdapter);
|
||||
EXPECT_EQ(adapter != nullptr, anyAdapterAvailable);
|
||||
if (discreteGPUAvailable) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
EXPECT_EQ(properties.adapterType, wgpu::AdapterType::DiscreteGPU);
|
||||
}
|
||||
}
|
||||
|
||||
// Test that requesting a low power GPU works
|
||||
TEST_F(AdapterCreationTest, PreferLowPower) {
|
||||
wgpu::RequestAdapterOptions options = {};
|
||||
options.powerPreference = wgpu::PowerPreference::LowPower;
|
||||
|
||||
MockCallback<WGPURequestAdapterCallback> cb;
|
||||
|
||||
WGPUAdapter cAdapter = nullptr;
|
||||
EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Success, _, nullptr, this))
|
||||
.WillOnce(SaveArg<1>(&cAdapter));
|
||||
instance.RequestAdapter(&options, cb.Callback(), cb.MakeUserdata(this));
|
||||
|
||||
wgpu::Adapter adapter = wgpu::Adapter::Acquire(cAdapter);
|
||||
EXPECT_EQ(adapter != nullptr, anyAdapterAvailable);
|
||||
if (integratedGPUAvailable) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
EXPECT_EQ(properties.adapterType, wgpu::AdapterType::IntegratedGPU);
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
|
|
@ -99,6 +99,21 @@ namespace {
|
|||
EXPECT_NE(device, nullptr);
|
||||
}
|
||||
|
||||
// Test successful call to RequestDevice with a null descriptor
|
||||
TEST_F(DeviceCreationTest, RequestDeviceNullDescriptorSuccess) {
|
||||
WGPUDevice cDevice;
|
||||
{
|
||||
MockCallback<WGPURequestDeviceCallback> cb;
|
||||
EXPECT_CALL(cb, Call(WGPURequestDeviceStatus_Success, NotNull(), nullptr, this))
|
||||
.WillOnce(SaveArg<1>(&cDevice));
|
||||
|
||||
adapter.RequestDevice(nullptr, cb.Callback(), cb.MakeUserdata(this));
|
||||
}
|
||||
|
||||
wgpu::Device device = wgpu::Device::Acquire(cDevice);
|
||||
EXPECT_NE(device, nullptr);
|
||||
}
|
||||
|
||||
// Test failing call to RequestDevice with invalid feature
|
||||
TEST_F(DeviceCreationTest, RequestDeviceFailure) {
|
||||
MockCallback<WGPURequestDeviceCallback> cb;
|
||||
|
|
Loading…
Reference in New Issue