Add Adapter::SupportsExternalImages
This commit adds a getter so that Chromium can check whether an Adapter would support external images. External images are necessary to implement the WebGPU swapchain and interop with the rest of the web platform. We should not expose adapters that cannot interop with the canvas and other web platform primitives until WebGPU gains options to request more "limited" adapters. Bug: dawn:1056 Change-Id: Iff83ac26b0e92dccdd4e29c0d854d9276a4a37bc Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/61580 Reviewed-by: Kai Ninomiya <kainino@chromium.org> Reviewed-by: Brian Ho <hob@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
a6ddb0e116
commit
9978b2f742
|
@ -47,6 +47,8 @@ namespace dawn_native {
|
|||
const std::vector<const char*>& requestedExtensions) const;
|
||||
WGPUDeviceProperties GetAdapterProperties() const;
|
||||
|
||||
virtual bool SupportsExternalImages() const = 0;
|
||||
|
||||
protected:
|
||||
PCIInfo mPCIInfo = {};
|
||||
wgpu::AdapterType mAdapterType = wgpu::AdapterType::Unknown;
|
||||
|
|
|
@ -103,6 +103,10 @@ namespace dawn_native {
|
|||
return mImpl->GetAdapterProperties();
|
||||
}
|
||||
|
||||
bool Adapter::SupportsExternalImages() const {
|
||||
return mImpl->SupportsExternalImages();
|
||||
}
|
||||
|
||||
Adapter::operator bool() const {
|
||||
return mImpl != nullptr;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
CleanUpDebugLayerFilters();
|
||||
}
|
||||
|
||||
bool Adapter::SupportsExternalImages() const {
|
||||
// Via dawn_native::d3d12::ExternalImageDXGI::Create
|
||||
return true;
|
||||
}
|
||||
|
||||
const D3D12DeviceInfo& Adapter::GetDeviceInfo() const {
|
||||
return mDeviceInfo;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
Adapter(Backend* backend, ComPtr<IDXGIAdapter3> hardwareAdapter);
|
||||
~Adapter() override;
|
||||
|
||||
// AdapterBase Implementation
|
||||
bool SupportsExternalImages() const override;
|
||||
|
||||
const D3D12DeviceInfo& GetDeviceInfo() const;
|
||||
IDXGIAdapter3* GetHardwareAdapter() const;
|
||||
Backend* GetBackend() const;
|
||||
|
|
|
@ -205,6 +205,12 @@ namespace dawn_native { namespace metal {
|
|||
InitializeSupportedExtensions();
|
||||
}
|
||||
|
||||
// AdapterBase Implementation
|
||||
bool SupportsExternalImages() const override {
|
||||
// Via dawn_native::metal::WrapIOSurface
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
ResultOrError<DeviceBase*> CreateDeviceImpl(const DeviceDescriptor* descriptor) override {
|
||||
return Device::Create(this, mDevice, descriptor);
|
||||
|
|
|
@ -34,6 +34,10 @@ namespace dawn_native { namespace null {
|
|||
|
||||
Adapter::~Adapter() = default;
|
||||
|
||||
bool Adapter::SupportsExternalImages() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Used for the tests that intend to use an adapter without all extensions enabled.
|
||||
void Adapter::SetSupportedExtensions(const std::vector<const char*>& requiredExtensions) {
|
||||
mSupportedExtensions = GetInstance()->ExtensionNamesToExtensionsSet(requiredExtensions);
|
||||
|
|
|
@ -169,6 +169,9 @@ namespace dawn_native { namespace null {
|
|||
Adapter(InstanceBase* instance);
|
||||
~Adapter() override;
|
||||
|
||||
// AdapterBase Implementation
|
||||
bool SupportsExternalImages() const override;
|
||||
|
||||
// Used for the tests that intend to use an adapter without all extensions enabled.
|
||||
void SetSupportedExtensions(const std::vector<const char*>& requiredExtensions);
|
||||
|
||||
|
|
|
@ -194,6 +194,12 @@ namespace dawn_native { namespace opengl {
|
|||
|
||||
~Adapter() override = default;
|
||||
|
||||
// AdapterBase Implementation
|
||||
bool SupportsExternalImages() const override {
|
||||
// Via dawn_native::opengl::WrapExternalEGLImage
|
||||
return GetBackendType() == wgpu::BackendType::OpenGLES;
|
||||
}
|
||||
|
||||
private:
|
||||
OpenGLFunctions mFunctions;
|
||||
|
||||
|
|
|
@ -251,6 +251,13 @@ namespace dawn_native { namespace vulkan {
|
|||
return {};
|
||||
}
|
||||
|
||||
bool Adapter::SupportsExternalImages() const {
|
||||
// Via dawn_native::vulkan::WrapVulkanImage
|
||||
return external_memory::Service::CheckSupport(mDeviceInfo) &&
|
||||
external_semaphore::Service::CheckSupport(mDeviceInfo, mPhysicalDevice,
|
||||
mBackend->GetFunctions());
|
||||
}
|
||||
|
||||
void Adapter::InitializeSupportedExtensions() {
|
||||
if (mDeviceInfo.features.textureCompressionBC == VK_TRUE) {
|
||||
mSupportedExtensions.EnableExtension(Extension::TextureCompressionBC);
|
||||
|
|
|
@ -29,6 +29,9 @@ namespace dawn_native { namespace vulkan {
|
|||
Adapter(Backend* backend, VkPhysicalDevice physicalDevice);
|
||||
~Adapter() override = default;
|
||||
|
||||
// AdapterBase Implementation
|
||||
bool SupportsExternalImages() const override;
|
||||
|
||||
const VulkanDeviceInfo& GetDeviceInfo() const;
|
||||
VkPhysicalDevice GetPhysicalDevice() const;
|
||||
Backend* GetBackend() const;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
class Device;
|
||||
struct VulkanDeviceInfo;
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
||||
namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
|
@ -36,6 +37,8 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
|||
explicit Service(Device* device);
|
||||
~Service();
|
||||
|
||||
static bool CheckSupport(const VulkanDeviceInfo& deviceInfo);
|
||||
|
||||
// True if the device reports it supports importing external memory.
|
||||
bool SupportsImportMemory(VkFormat format,
|
||||
VkImageType type,
|
||||
|
|
|
@ -60,15 +60,18 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
Service::Service(Device* device) : mDevice(device) {
|
||||
const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
|
||||
|
||||
mSupported = deviceInfo.HasExt(DeviceExt::ExternalMemoryFD) &&
|
||||
deviceInfo.HasExt(DeviceExt::ImageDrmFormatModifier);
|
||||
Service::Service(Device* device)
|
||||
: mDevice(device), mSupported(CheckSupport(device->GetDeviceInfo())) {
|
||||
}
|
||||
|
||||
Service::~Service() = default;
|
||||
|
||||
// static
|
||||
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo) {
|
||||
return deviceInfo.HasExt(DeviceExt::ExternalMemoryFD) &&
|
||||
deviceInfo.HasExt(DeviceExt::ImageDrmFormatModifier);
|
||||
}
|
||||
|
||||
bool Service::SupportsImportMemory(VkFormat format,
|
||||
VkImageType type,
|
||||
VkImageTiling tiling,
|
||||
|
|
|
@ -24,6 +24,11 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
|||
|
||||
Service::~Service() = default;
|
||||
|
||||
// static
|
||||
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Service::SupportsImportMemory(VkFormat format,
|
||||
VkImageType type,
|
||||
VkImageTiling tiling,
|
||||
|
|
|
@ -22,12 +22,17 @@
|
|||
|
||||
namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
|
||||
Service::Service(Device* device) : mDevice(device) {
|
||||
mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalMemoryFD);
|
||||
Service::Service(Device* device)
|
||||
: mDevice(device), mSupported(CheckSupport(device->GetDeviceInfo())) {
|
||||
}
|
||||
|
||||
Service::~Service() = default;
|
||||
|
||||
// static
|
||||
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo) {
|
||||
return deviceInfo.HasExt(DeviceExt::ExternalMemoryFD);
|
||||
}
|
||||
|
||||
bool Service::SupportsImportMemory(VkFormat format,
|
||||
VkImageType type,
|
||||
VkImageTiling tiling,
|
||||
|
|
|
@ -22,12 +22,17 @@
|
|||
|
||||
namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||
|
||||
Service::Service(Device* device) : mDevice(device) {
|
||||
mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalMemoryZirconHandle);
|
||||
Service::Service(Device* device)
|
||||
: mDevice(device), mSupported(CheckSupport(device->GetDeviceInfo())) {
|
||||
}
|
||||
|
||||
Service::~Service() = default;
|
||||
|
||||
// static
|
||||
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo) {
|
||||
return deviceInfo.HasExt(DeviceExt::ExternalMemoryZirconHandle);
|
||||
}
|
||||
|
||||
bool Service::SupportsImportMemory(VkFormat format,
|
||||
VkImageType type,
|
||||
VkImageTiling tiling,
|
||||
|
|
|
@ -30,6 +30,10 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
|||
explicit Service(Device* device);
|
||||
~Service();
|
||||
|
||||
static bool CheckSupport(const VulkanDeviceInfo& deviceInfo,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VulkanFunctions& fn);
|
||||
|
||||
// True if the device reports it supports this feature
|
||||
bool Supported();
|
||||
|
||||
|
|
|
@ -27,12 +27,21 @@ static constexpr VkExternalSemaphoreHandleTypeFlagBits kHandleType =
|
|||
|
||||
namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
||||
|
||||
Service::Service(Device* device) : mDevice(device) {
|
||||
mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalSemaphoreFD);
|
||||
Service::Service(Device* device)
|
||||
: mDevice(device),
|
||||
mSupported(CheckSupport(device->GetDeviceInfo(),
|
||||
ToBackend(device->GetAdapter())->GetPhysicalDevice(),
|
||||
device->fn)) {
|
||||
}
|
||||
|
||||
// Early out before we try using extension functions
|
||||
if (!mSupported) {
|
||||
return;
|
||||
Service::~Service() = default;
|
||||
|
||||
// static
|
||||
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VulkanFunctions& fn) {
|
||||
if (!deviceInfo.HasExt(DeviceExt::ExternalSemaphoreFD)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo;
|
||||
|
@ -44,17 +53,14 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
|||
semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR;
|
||||
semaphoreProperties.pNext = nullptr;
|
||||
|
||||
mDevice->fn.GetPhysicalDeviceExternalSemaphoreProperties(
|
||||
ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &semaphoreInfo,
|
||||
&semaphoreProperties);
|
||||
fn.GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &semaphoreInfo,
|
||||
&semaphoreProperties);
|
||||
|
||||
VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR |
|
||||
VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR;
|
||||
mSupported =
|
||||
mSupported && IsSubset(requiredFlags, semaphoreProperties.externalSemaphoreFeatures);
|
||||
}
|
||||
|
||||
Service::~Service() = default;
|
||||
return IsSubset(requiredFlags, semaphoreProperties.externalSemaphoreFeatures);
|
||||
}
|
||||
|
||||
bool Service::Supported() {
|
||||
return mSupported;
|
||||
|
|
|
@ -24,6 +24,13 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
|||
|
||||
Service::~Service() = default;
|
||||
|
||||
// static
|
||||
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VulkanFunctions& fn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Service::Supported() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -20,12 +20,21 @@
|
|||
|
||||
namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
||||
|
||||
Service::Service(Device* device) : mDevice(device) {
|
||||
mSupported = device->GetDeviceInfo().hasExt(DeviceExt::ExternalSemaphoreZirconHandle);
|
||||
Service::Service(Device* device)
|
||||
: mDevice(device),
|
||||
mSupported(CheckSupport(device->GetDeviceInfo(),
|
||||
ToBackend(device->GetAdapter())->GetPhysicalDevice(),
|
||||
device->fn)) {
|
||||
}
|
||||
|
||||
// Early out before we try using extension functions
|
||||
if (!mSupported) {
|
||||
return;
|
||||
Service::~Service() = default;
|
||||
|
||||
// static
|
||||
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VulkanFunctions& fn) {
|
||||
if (!deviceInfo.HasExt(DeviceExt::ExternalSemaphoreZirconHandle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo;
|
||||
|
@ -37,17 +46,14 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
|||
semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR;
|
||||
semaphoreProperties.pNext = nullptr;
|
||||
|
||||
mDevice->fn.GetPhysicalDeviceExternalSemaphoreProperties(
|
||||
ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &semaphoreInfo,
|
||||
&semaphoreProperties);
|
||||
fn.GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &semaphoreInfo,
|
||||
&semaphoreProperties);
|
||||
|
||||
VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR |
|
||||
VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR;
|
||||
mSupported =
|
||||
mSupported && IsSubset(requiredFlags, semaphoreProperties.externalSemaphoreFeatures);
|
||||
}
|
||||
|
||||
Service::~Service() = default;
|
||||
return IsSubset(requiredFlags, semaphoreProperties.externalSemaphoreFeatures);
|
||||
}
|
||||
|
||||
bool Service::Supported() {
|
||||
return mSupported;
|
||||
|
|
|
@ -109,6 +109,10 @@ namespace dawn_native {
|
|||
std::vector<const char*> GetSupportedExtensions() const;
|
||||
WGPUDeviceProperties GetAdapterProperties() const;
|
||||
|
||||
// Check that the Adapter is able to support importing external images. This is necessary
|
||||
// to implement the swapchain and interop APIs in Chromium.
|
||||
bool SupportsExternalImages() const;
|
||||
|
||||
explicit operator bool() const;
|
||||
|
||||
// Create a device on this adapter, note that the interface will change to include at least
|
||||
|
|
Loading…
Reference in New Issue