Add FeatureLevel to AdapterBase; implement Compat.
This introduces the notion of FeatureLevel, currently consisting of Core or Compatibility. Each AdapterBase is now constructed with the FeatureLevel it supports. When discovering PhysicalDevices, create an AdapterBase for each of the FeaturLevels which that PhysicalDevice supports. For most of the backends, this will mean Core and Compatibility, while OpenGL and D3D11 support only Compatibility. Bug: dawn:1796. Change-Id: I828247ef43e2220805ccf6c08827aa5e2382a026 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/118240 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Stephen White <senorblanco@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
3ee4f6af41
commit
b9e12716c6
|
@ -53,7 +53,8 @@
|
|||
"members": [
|
||||
{"name": "compatible surface", "type": "surface", "optional": true},
|
||||
{"name": "power preference", "type": "power preference", "default": "undefined"},
|
||||
{"name": "force fallback adapter", "type": "bool", "default": "false"}
|
||||
{"name": "force fallback adapter", "type": "bool", "default": "false"},
|
||||
{"name": "compatibility mode", "type": "bool", "default": "false"}
|
||||
]
|
||||
},
|
||||
"request adapter status": {
|
||||
|
@ -140,7 +141,8 @@
|
|||
{"name": "name", "type": "char", "annotation": "const*", "length": "strlen"},
|
||||
{"name": "driver description", "type": "char", "annotation": "const*", "length": "strlen"},
|
||||
{"name": "adapter type", "type": "adapter type"},
|
||||
{"name": "backend type", "type": "backend type"}
|
||||
{"name": "backend type", "type": "backend type"},
|
||||
{"name": "compatibility mode", "type": "bool", "default": "false"}
|
||||
]
|
||||
},
|
||||
"adapter type": {
|
||||
|
|
|
@ -20,8 +20,10 @@
|
|||
|
||||
namespace dawn::native {
|
||||
|
||||
AdapterBase::AdapterBase(const Ref<PhysicalDeviceBase>& physicalDevice)
|
||||
: mPhysicalDevice(std::move(physicalDevice)) {}
|
||||
AdapterBase::AdapterBase(const Ref<PhysicalDeviceBase>& physicalDevice, FeatureLevel featureLevel)
|
||||
: mPhysicalDevice(std::move(physicalDevice)), mFeatureLevel(featureLevel) {
|
||||
ASSERT(physicalDevice->SupportsFeatureLevel(featureLevel));
|
||||
}
|
||||
|
||||
AdapterBase::~AdapterBase() = default;
|
||||
|
||||
|
@ -39,6 +41,7 @@ bool AdapterBase::APIGetLimits(SupportedLimits* limits) const {
|
|||
|
||||
void AdapterBase::APIGetProperties(AdapterProperties* properties) const {
|
||||
mPhysicalDevice->APIGetProperties(properties);
|
||||
properties->compatibilityMode = mFeatureLevel == FeatureLevel::Compatibility;
|
||||
}
|
||||
|
||||
bool AdapterBase::APIHasFeature(wgpu::FeatureName feature) const {
|
||||
|
@ -68,4 +71,8 @@ bool AdapterBase::AllowUnsafeAPIs() const {
|
|||
!GetTogglesState().IsEnabled(Toggle::DisallowUnsafeAPIs);
|
||||
}
|
||||
|
||||
FeatureLevel AdapterBase::GetFeatureLevel() const {
|
||||
return mFeatureLevel;
|
||||
}
|
||||
|
||||
} // namespace dawn::native
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "dawn/native/DawnNative.h"
|
||||
|
||||
#include "dawn/common/RefCounted.h"
|
||||
#include "dawn/native/PhysicalDevice.h"
|
||||
#include "dawn/native/dawn_platform.h"
|
||||
|
||||
namespace dawn::native {
|
||||
|
@ -28,7 +29,7 @@ struct SupportedLimits;
|
|||
|
||||
class AdapterBase : public RefCounted {
|
||||
public:
|
||||
explicit AdapterBase(const Ref<PhysicalDeviceBase>& physicalDevice);
|
||||
AdapterBase(const Ref<PhysicalDeviceBase>& physicalDevice, FeatureLevel featureLevel);
|
||||
~AdapterBase() override;
|
||||
|
||||
// WebGPU API
|
||||
|
@ -53,8 +54,11 @@ class AdapterBase : public RefCounted {
|
|||
// TODO(dawn:1685): Remove wrapper once DisallowUnsafeAPIs is fully removed.
|
||||
bool AllowUnsafeAPIs() const;
|
||||
|
||||
FeatureLevel GetFeatureLevel() const;
|
||||
|
||||
private:
|
||||
Ref<PhysicalDeviceBase> mPhysicalDevice;
|
||||
FeatureLevel mFeatureLevel;
|
||||
};
|
||||
|
||||
} // namespace dawn::native
|
||||
|
|
|
@ -255,6 +255,10 @@ ResultOrError<Ref<AdapterBase>> InstanceBase::RequestAdapterInternal(
|
|||
AdapterProperties properties;
|
||||
mAdapters[i]->APIGetProperties(&properties);
|
||||
|
||||
bool isCompatibility = mAdapters[i]->GetFeatureLevel() == FeatureLevel::Compatibility;
|
||||
if (options->compatibilityMode != isCompatibility) {
|
||||
continue;
|
||||
}
|
||||
if (options->forceFallbackAdapter) {
|
||||
if (!gpu_info::IsGoogleSwiftshader(properties.vendorID, properties.deviceID)) {
|
||||
continue;
|
||||
|
@ -320,7 +324,12 @@ void InstanceBase::DiscoverDefaultAdapters() {
|
|||
for (Ref<PhysicalDeviceBase>& physicalDevice : physicalDevices) {
|
||||
ASSERT(physicalDevice->GetBackendType() == backend->GetType());
|
||||
ASSERT(physicalDevice->GetInstance() == this);
|
||||
mAdapters.push_back(AcquireRef(new AdapterBase(std::move(physicalDevice))));
|
||||
for (auto featureLevel : {FeatureLevel::Compatibility, FeatureLevel::Core}) {
|
||||
if (physicalDevice->SupportsFeatureLevel(featureLevel)) {
|
||||
mAdapters.push_back(
|
||||
AcquireRef(new AdapterBase(std::move(physicalDevice), featureLevel)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -454,7 +463,12 @@ MaybeError InstanceBase::DiscoverAdaptersInternal(const AdapterDiscoveryOptionsB
|
|||
for (Ref<PhysicalDeviceBase>& physicalDevice : newPhysicalDevices) {
|
||||
ASSERT(physicalDevice->GetBackendType() == backend->GetType());
|
||||
ASSERT(physicalDevice->GetInstance() == this);
|
||||
mAdapters.push_back(AcquireRef(new AdapterBase(std::move(physicalDevice))));
|
||||
for (auto featureLevel : {FeatureLevel::Compatibility, FeatureLevel::Core}) {
|
||||
if (physicalDevice->SupportsFeatureLevel(featureLevel)) {
|
||||
mAdapters.push_back(
|
||||
AcquireRef(new AdapterBase(std::move(physicalDevice), featureLevel)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ namespace dawn::native {
|
|||
|
||||
class DeviceBase;
|
||||
|
||||
enum class FeatureLevel { Compatibility, Core };
|
||||
|
||||
class PhysicalDeviceBase : public RefCounted {
|
||||
public:
|
||||
PhysicalDeviceBase(InstanceBase* instance,
|
||||
|
@ -78,6 +80,8 @@ class PhysicalDeviceBase : public RefCounted {
|
|||
|
||||
virtual bool SupportsExternalImages() const = 0;
|
||||
|
||||
virtual bool SupportsFeatureLevel(FeatureLevel featureLevel) const = 0;
|
||||
|
||||
protected:
|
||||
uint32_t mVendorId = 0xFFFFFFFF;
|
||||
std::string mVendorName;
|
||||
|
|
|
@ -73,6 +73,10 @@ bool PhysicalDevice::SupportsExternalImages() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool PhysicalDevice::SupportsFeatureLevel(FeatureLevel featureLevel) const {
|
||||
return featureLevel == FeatureLevel::Compatibility;
|
||||
}
|
||||
|
||||
const DeviceInfo& PhysicalDevice::GetDeviceInfo() const {
|
||||
return mDeviceInfo;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ class PhysicalDevice : public d3d::PhysicalDevice {
|
|||
// PhysicalDeviceBase Implementation
|
||||
bool SupportsExternalImages() const override;
|
||||
|
||||
bool SupportsFeatureLevel(FeatureLevel featureLevel) const override;
|
||||
|
||||
const DeviceInfo& GetDeviceInfo() const;
|
||||
ResultOrError<ComPtr<ID3D11Device>> CreateD3D11Device();
|
||||
|
||||
|
|
|
@ -43,6 +43,10 @@ bool PhysicalDevice::SupportsExternalImages() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PhysicalDevice::SupportsFeatureLevel(FeatureLevel) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
const D3D12DeviceInfo& PhysicalDevice::GetDeviceInfo() const {
|
||||
return mDeviceInfo;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ class PhysicalDevice : public d3d::PhysicalDevice {
|
|||
|
||||
// PhysicalDeviceBase Implementation
|
||||
bool SupportsExternalImages() const override;
|
||||
bool SupportsFeatureLevel(FeatureLevel featureLevel) const override;
|
||||
|
||||
const D3D12DeviceInfo& GetDeviceInfo() const;
|
||||
Backend* GetBackend() const;
|
||||
|
|
|
@ -292,6 +292,8 @@ class PhysicalDevice : public PhysicalDeviceBase {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SupportsFeatureLevel(FeatureLevel) const override { return true; }
|
||||
|
||||
private:
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(AdapterBase* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
|
|
|
@ -51,6 +51,10 @@ bool PhysicalDevice::SupportsExternalImages() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool PhysicalDevice::SupportsFeatureLevel(FeatureLevel) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
MaybeError PhysicalDevice::InitializeImpl() {
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -181,6 +181,8 @@ class PhysicalDevice : public PhysicalDeviceBase {
|
|||
// PhysicalDeviceBase Implementation
|
||||
bool SupportsExternalImages() const override;
|
||||
|
||||
bool SupportsFeatureLevel(FeatureLevel featureLevel) const override;
|
||||
|
||||
// Used for the tests that intend to use an adapter without all features enabled.
|
||||
using PhysicalDeviceBase::SetSupportedFeaturesForTesting;
|
||||
|
||||
|
|
|
@ -227,6 +227,10 @@ ResultOrError<Ref<DeviceBase>> PhysicalDevice::CreateDeviceImpl(AdapterBase* ada
|
|||
return Device::Create(adapter, descriptor, mFunctions, std::move(context), deviceToggles);
|
||||
}
|
||||
|
||||
bool PhysicalDevice::SupportsFeatureLevel(FeatureLevel featureLevel) const {
|
||||
return featureLevel == FeatureLevel::Compatibility;
|
||||
}
|
||||
|
||||
MaybeError PhysicalDevice::ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TogglesState& toggles) const {
|
||||
|
|
|
@ -33,6 +33,7 @@ class PhysicalDevice : public PhysicalDeviceBase {
|
|||
|
||||
// PhysicalDeviceBase Implementation
|
||||
bool SupportsExternalImages() const override;
|
||||
bool SupportsFeatureLevel(FeatureLevel featureLevel) const override;
|
||||
|
||||
private:
|
||||
MaybeError InitializeImpl() override;
|
||||
|
|
|
@ -429,6 +429,10 @@ bool PhysicalDevice::SupportsExternalImages() const {
|
|||
mVulkanInstance->GetFunctions());
|
||||
}
|
||||
|
||||
bool PhysicalDevice::SupportsFeatureLevel(FeatureLevel) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void PhysicalDevice::SetupBackendDeviceToggles(TogglesState* deviceToggles) const {
|
||||
// TODO(crbug.com/dawn/857): tighten this workaround when this issue is fixed in both
|
||||
// Vulkan SPEC and drivers.
|
||||
|
|
|
@ -35,6 +35,7 @@ class PhysicalDevice : public PhysicalDeviceBase {
|
|||
|
||||
// PhysicalDeviceBase Implementation
|
||||
bool SupportsExternalImages() const override;
|
||||
bool SupportsFeatureLevel(FeatureLevel featureLevel) const override;
|
||||
|
||||
const VulkanDeviceInfo& GetDeviceInfo() const;
|
||||
VkPhysicalDevice GetVkPhysicalDevice() const;
|
||||
|
|
|
@ -65,7 +65,7 @@ TEST(AdapterDiscoveryTests, OnlySwiftShader) {
|
|||
instance.DiscoverAdapters(&options);
|
||||
|
||||
const auto& adapters = instance.GetAdapters();
|
||||
EXPECT_LE(adapters.size(), 1u); // 0 or 1 SwiftShader adapters.
|
||||
EXPECT_LE(adapters.size(), 2u); // 0 or 2 SwiftShader adapters.
|
||||
for (const auto& adapter : adapters) {
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
|
@ -260,6 +260,9 @@ class AdapterCreationTest : public ::testing::Test {
|
|||
|
||||
wgpu::AdapterProperties properties;
|
||||
nativeAdapter.GetProperties(&properties);
|
||||
if (properties.compatibilityMode) {
|
||||
continue;
|
||||
}
|
||||
swiftShaderAvailable =
|
||||
swiftShaderAvailable ||
|
||||
gpu_info::IsGoogleSwiftshader(properties.vendorID, properties.deviceID);
|
||||
|
@ -387,6 +390,45 @@ TEST_F(AdapterCreationTest, PreferLowPower) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test that requesting a Compatibility adapter is supported.
|
||||
TEST_F(AdapterCreationTest, Compatibility) {
|
||||
wgpu::RequestAdapterOptions options = {};
|
||||
options.compatibilityMode = 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, anyAdapterAvailable);
|
||||
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
EXPECT_TRUE(properties.compatibilityMode);
|
||||
}
|
||||
|
||||
// Test that requesting a Non-Compatibility adapter is supported and is default.
|
||||
TEST_F(AdapterCreationTest, NonCompatibility) {
|
||||
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);
|
||||
|
||||
wgpu::AdapterProperties properties;
|
||||
adapter.GetProperties(&properties);
|
||||
EXPECT_FALSE(properties.compatibilityMode);
|
||||
}
|
||||
|
||||
// Test that GetInstance() returns the correct Instance.
|
||||
TEST_F(AdapterCreationTest, GetInstance) {
|
||||
wgpu::RequestAdapterOptions options = {};
|
||||
|
|
|
@ -34,9 +34,10 @@ class FeatureTests : public testing::Test {
|
|||
mInstanceBase.Get(),
|
||||
dawn::native::TogglesState(dawn::native::ToggleStage::Adapter)
|
||||
.SetForTesting(dawn::native::Toggle::AllowUnsafeAPIs, true, true)),
|
||||
mAdapterBase(&mPhysicalDevice),
|
||||
mUnsafeAdapterBaseDisallow(&mUnsafePhysicalDeviceDisallow),
|
||||
mUnsafeAdapterBase(&mUnsafePhysicalDevice) {}
|
||||
mAdapterBase(&mPhysicalDevice, dawn::native::FeatureLevel::Core),
|
||||
mUnsafeAdapterBaseDisallow(&mUnsafePhysicalDeviceDisallow,
|
||||
dawn::native::FeatureLevel::Core),
|
||||
mUnsafeAdapterBase(&mUnsafePhysicalDevice, dawn::native::FeatureLevel::Core) {}
|
||||
|
||||
std::vector<wgpu::FeatureName> GetAllFeatureNames() {
|
||||
std::vector<wgpu::FeatureName> allFeatureNames(kTotalFeaturesCount);
|
||||
|
|
|
@ -56,7 +56,8 @@ class GetProcAddressTests : public testing::TestWithParam<DawnFlavor> {
|
|||
GetProcAddressTests()
|
||||
: testing::TestWithParam<DawnFlavor>(),
|
||||
mNativeInstance(dawn::native::InstanceBase::Create()),
|
||||
mAdapterBase(AcquireRef(new dawn::native::null::PhysicalDevice(mNativeInstance.Get()))) {}
|
||||
mAdapterBase(AcquireRef(new dawn::native::null::PhysicalDevice(mNativeInstance.Get())),
|
||||
dawn::native::FeatureLevel::Core) {}
|
||||
|
||||
void SetUp() override {
|
||||
switch (GetParam()) {
|
||||
|
|
|
@ -27,7 +27,8 @@ class PerThreadProcTests : public testing::Test {
|
|||
public:
|
||||
PerThreadProcTests()
|
||||
: mNativeInstance(dawn::native::InstanceBase::Create()),
|
||||
mAdapterBase(AcquireRef(new dawn::native::null::PhysicalDevice(mNativeInstance.Get()))) {}
|
||||
mAdapterBase(AcquireRef(new dawn::native::null::PhysicalDevice(mNativeInstance.Get())),
|
||||
dawn::native::FeatureLevel::Core) {}
|
||||
~PerThreadProcTests() override = default;
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Reference in New Issue