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;
|
const std::vector<const char*>& requestedExtensions) const;
|
||||||
WGPUDeviceProperties GetAdapterProperties() const;
|
WGPUDeviceProperties GetAdapterProperties() const;
|
||||||
|
|
||||||
|
virtual bool SupportsExternalImages() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PCIInfo mPCIInfo = {};
|
PCIInfo mPCIInfo = {};
|
||||||
wgpu::AdapterType mAdapterType = wgpu::AdapterType::Unknown;
|
wgpu::AdapterType mAdapterType = wgpu::AdapterType::Unknown;
|
||||||
|
|
|
@ -103,6 +103,10 @@ namespace dawn_native {
|
||||||
return mImpl->GetAdapterProperties();
|
return mImpl->GetAdapterProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Adapter::SupportsExternalImages() const {
|
||||||
|
return mImpl->SupportsExternalImages();
|
||||||
|
}
|
||||||
|
|
||||||
Adapter::operator bool() const {
|
Adapter::operator bool() const {
|
||||||
return mImpl != nullptr;
|
return mImpl != nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,11 @@ namespace dawn_native { namespace d3d12 {
|
||||||
CleanUpDebugLayerFilters();
|
CleanUpDebugLayerFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Adapter::SupportsExternalImages() const {
|
||||||
|
// Via dawn_native::d3d12::ExternalImageDXGI::Create
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const D3D12DeviceInfo& Adapter::GetDeviceInfo() const {
|
const D3D12DeviceInfo& Adapter::GetDeviceInfo() const {
|
||||||
return mDeviceInfo;
|
return mDeviceInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,9 @@ namespace dawn_native { namespace d3d12 {
|
||||||
Adapter(Backend* backend, ComPtr<IDXGIAdapter3> hardwareAdapter);
|
Adapter(Backend* backend, ComPtr<IDXGIAdapter3> hardwareAdapter);
|
||||||
~Adapter() override;
|
~Adapter() override;
|
||||||
|
|
||||||
|
// AdapterBase Implementation
|
||||||
|
bool SupportsExternalImages() const override;
|
||||||
|
|
||||||
const D3D12DeviceInfo& GetDeviceInfo() const;
|
const D3D12DeviceInfo& GetDeviceInfo() const;
|
||||||
IDXGIAdapter3* GetHardwareAdapter() const;
|
IDXGIAdapter3* GetHardwareAdapter() const;
|
||||||
Backend* GetBackend() const;
|
Backend* GetBackend() const;
|
||||||
|
|
|
@ -205,6 +205,12 @@ namespace dawn_native { namespace metal {
|
||||||
InitializeSupportedExtensions();
|
InitializeSupportedExtensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AdapterBase Implementation
|
||||||
|
bool SupportsExternalImages() const override {
|
||||||
|
// Via dawn_native::metal::WrapIOSurface
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResultOrError<DeviceBase*> CreateDeviceImpl(const DeviceDescriptor* descriptor) override {
|
ResultOrError<DeviceBase*> CreateDeviceImpl(const DeviceDescriptor* descriptor) override {
|
||||||
return Device::Create(this, mDevice, descriptor);
|
return Device::Create(this, mDevice, descriptor);
|
||||||
|
|
|
@ -34,6 +34,10 @@ namespace dawn_native { namespace null {
|
||||||
|
|
||||||
Adapter::~Adapter() = default;
|
Adapter::~Adapter() = default;
|
||||||
|
|
||||||
|
bool Adapter::SupportsExternalImages() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Used for the tests that intend to use an adapter without all extensions enabled.
|
// Used for the tests that intend to use an adapter without all extensions enabled.
|
||||||
void Adapter::SetSupportedExtensions(const std::vector<const char*>& requiredExtensions) {
|
void Adapter::SetSupportedExtensions(const std::vector<const char*>& requiredExtensions) {
|
||||||
mSupportedExtensions = GetInstance()->ExtensionNamesToExtensionsSet(requiredExtensions);
|
mSupportedExtensions = GetInstance()->ExtensionNamesToExtensionsSet(requiredExtensions);
|
||||||
|
|
|
@ -169,6 +169,9 @@ namespace dawn_native { namespace null {
|
||||||
Adapter(InstanceBase* instance);
|
Adapter(InstanceBase* instance);
|
||||||
~Adapter() override;
|
~Adapter() override;
|
||||||
|
|
||||||
|
// AdapterBase Implementation
|
||||||
|
bool SupportsExternalImages() const override;
|
||||||
|
|
||||||
// Used for the tests that intend to use an adapter without all extensions enabled.
|
// Used for the tests that intend to use an adapter without all extensions enabled.
|
||||||
void SetSupportedExtensions(const std::vector<const char*>& requiredExtensions);
|
void SetSupportedExtensions(const std::vector<const char*>& requiredExtensions);
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,12 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
~Adapter() override = default;
|
~Adapter() override = default;
|
||||||
|
|
||||||
|
// AdapterBase Implementation
|
||||||
|
bool SupportsExternalImages() const override {
|
||||||
|
// Via dawn_native::opengl::WrapExternalEGLImage
|
||||||
|
return GetBackendType() == wgpu::BackendType::OpenGLES;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OpenGLFunctions mFunctions;
|
OpenGLFunctions mFunctions;
|
||||||
|
|
||||||
|
|
|
@ -251,6 +251,13 @@ namespace dawn_native { namespace vulkan {
|
||||||
return {};
|
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() {
|
void Adapter::InitializeSupportedExtensions() {
|
||||||
if (mDeviceInfo.features.textureCompressionBC == VK_TRUE) {
|
if (mDeviceInfo.features.textureCompressionBC == VK_TRUE) {
|
||||||
mSupportedExtensions.EnableExtension(Extension::TextureCompressionBC);
|
mSupportedExtensions.EnableExtension(Extension::TextureCompressionBC);
|
||||||
|
|
|
@ -29,6 +29,9 @@ namespace dawn_native { namespace vulkan {
|
||||||
Adapter(Backend* backend, VkPhysicalDevice physicalDevice);
|
Adapter(Backend* backend, VkPhysicalDevice physicalDevice);
|
||||||
~Adapter() override = default;
|
~Adapter() override = default;
|
||||||
|
|
||||||
|
// AdapterBase Implementation
|
||||||
|
bool SupportsExternalImages() const override;
|
||||||
|
|
||||||
const VulkanDeviceInfo& GetDeviceInfo() const;
|
const VulkanDeviceInfo& GetDeviceInfo() const;
|
||||||
VkPhysicalDevice GetPhysicalDevice() const;
|
VkPhysicalDevice GetPhysicalDevice() const;
|
||||||
Backend* GetBackend() const;
|
Backend* GetBackend() const;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
namespace dawn_native { namespace vulkan {
|
namespace dawn_native { namespace vulkan {
|
||||||
class Device;
|
class Device;
|
||||||
|
struct VulkanDeviceInfo;
|
||||||
}} // namespace dawn_native::vulkan
|
}} // namespace dawn_native::vulkan
|
||||||
|
|
||||||
namespace dawn_native { namespace vulkan { namespace external_memory {
|
namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||||
|
@ -36,6 +37,8 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||||
explicit Service(Device* device);
|
explicit Service(Device* device);
|
||||||
~Service();
|
~Service();
|
||||||
|
|
||||||
|
static bool CheckSupport(const VulkanDeviceInfo& deviceInfo);
|
||||||
|
|
||||||
// True if the device reports it supports importing external memory.
|
// True if the device reports it supports importing external memory.
|
||||||
bool SupportsImportMemory(VkFormat format,
|
bool SupportsImportMemory(VkFormat format,
|
||||||
VkImageType type,
|
VkImageType type,
|
||||||
|
|
|
@ -60,15 +60,18 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
Service::Service(Device* device) : mDevice(device) {
|
Service::Service(Device* device)
|
||||||
const VulkanDeviceInfo& deviceInfo = mDevice->GetDeviceInfo();
|
: mDevice(device), mSupported(CheckSupport(device->GetDeviceInfo())) {
|
||||||
|
|
||||||
mSupported = deviceInfo.HasExt(DeviceExt::ExternalMemoryFD) &&
|
|
||||||
deviceInfo.HasExt(DeviceExt::ImageDrmFormatModifier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Service::~Service() = default;
|
Service::~Service() = default;
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo) {
|
||||||
|
return deviceInfo.HasExt(DeviceExt::ExternalMemoryFD) &&
|
||||||
|
deviceInfo.HasExt(DeviceExt::ImageDrmFormatModifier);
|
||||||
|
}
|
||||||
|
|
||||||
bool Service::SupportsImportMemory(VkFormat format,
|
bool Service::SupportsImportMemory(VkFormat format,
|
||||||
VkImageType type,
|
VkImageType type,
|
||||||
VkImageTiling tiling,
|
VkImageTiling tiling,
|
||||||
|
|
|
@ -24,6 +24,11 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||||
|
|
||||||
Service::~Service() = default;
|
Service::~Service() = default;
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Service::SupportsImportMemory(VkFormat format,
|
bool Service::SupportsImportMemory(VkFormat format,
|
||||||
VkImageType type,
|
VkImageType type,
|
||||||
VkImageTiling tiling,
|
VkImageTiling tiling,
|
||||||
|
|
|
@ -22,12 +22,17 @@
|
||||||
|
|
||||||
namespace dawn_native { namespace vulkan { namespace external_memory {
|
namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||||
|
|
||||||
Service::Service(Device* device) : mDevice(device) {
|
Service::Service(Device* device)
|
||||||
mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalMemoryFD);
|
: mDevice(device), mSupported(CheckSupport(device->GetDeviceInfo())) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Service::~Service() = default;
|
Service::~Service() = default;
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo) {
|
||||||
|
return deviceInfo.HasExt(DeviceExt::ExternalMemoryFD);
|
||||||
|
}
|
||||||
|
|
||||||
bool Service::SupportsImportMemory(VkFormat format,
|
bool Service::SupportsImportMemory(VkFormat format,
|
||||||
VkImageType type,
|
VkImageType type,
|
||||||
VkImageTiling tiling,
|
VkImageTiling tiling,
|
||||||
|
|
|
@ -22,12 +22,17 @@
|
||||||
|
|
||||||
namespace dawn_native { namespace vulkan { namespace external_memory {
|
namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||||
|
|
||||||
Service::Service(Device* device) : mDevice(device) {
|
Service::Service(Device* device)
|
||||||
mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalMemoryZirconHandle);
|
: mDevice(device), mSupported(CheckSupport(device->GetDeviceInfo())) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Service::~Service() = default;
|
Service::~Service() = default;
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo) {
|
||||||
|
return deviceInfo.HasExt(DeviceExt::ExternalMemoryZirconHandle);
|
||||||
|
}
|
||||||
|
|
||||||
bool Service::SupportsImportMemory(VkFormat format,
|
bool Service::SupportsImportMemory(VkFormat format,
|
||||||
VkImageType type,
|
VkImageType type,
|
||||||
VkImageTiling tiling,
|
VkImageTiling tiling,
|
||||||
|
|
|
@ -30,6 +30,10 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
||||||
explicit Service(Device* device);
|
explicit Service(Device* device);
|
||||||
~Service();
|
~Service();
|
||||||
|
|
||||||
|
static bool CheckSupport(const VulkanDeviceInfo& deviceInfo,
|
||||||
|
VkPhysicalDevice physicalDevice,
|
||||||
|
const VulkanFunctions& fn);
|
||||||
|
|
||||||
// True if the device reports it supports this feature
|
// True if the device reports it supports this feature
|
||||||
bool Supported();
|
bool Supported();
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,21 @@ static constexpr VkExternalSemaphoreHandleTypeFlagBits kHandleType =
|
||||||
|
|
||||||
namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
||||||
|
|
||||||
Service::Service(Device* device) : mDevice(device) {
|
Service::Service(Device* device)
|
||||||
mSupported = device->GetDeviceInfo().HasExt(DeviceExt::ExternalSemaphoreFD);
|
: mDevice(device),
|
||||||
|
mSupported(CheckSupport(device->GetDeviceInfo(),
|
||||||
|
ToBackend(device->GetAdapter())->GetPhysicalDevice(),
|
||||||
|
device->fn)) {
|
||||||
|
}
|
||||||
|
|
||||||
// Early out before we try using extension functions
|
Service::~Service() = default;
|
||||||
if (!mSupported) {
|
|
||||||
return;
|
// static
|
||||||
|
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo,
|
||||||
|
VkPhysicalDevice physicalDevice,
|
||||||
|
const VulkanFunctions& fn) {
|
||||||
|
if (!deviceInfo.HasExt(DeviceExt::ExternalSemaphoreFD)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo;
|
VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo;
|
||||||
|
@ -44,17 +53,14 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
||||||
semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR;
|
semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR;
|
||||||
semaphoreProperties.pNext = nullptr;
|
semaphoreProperties.pNext = nullptr;
|
||||||
|
|
||||||
mDevice->fn.GetPhysicalDeviceExternalSemaphoreProperties(
|
fn.GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &semaphoreInfo,
|
||||||
ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &semaphoreInfo,
|
|
||||||
&semaphoreProperties);
|
&semaphoreProperties);
|
||||||
|
|
||||||
VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR |
|
VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR |
|
||||||
VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_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() {
|
bool Service::Supported() {
|
||||||
return mSupported;
|
return mSupported;
|
||||||
|
|
|
@ -24,6 +24,13 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
||||||
|
|
||||||
Service::~Service() = default;
|
Service::~Service() = default;
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo,
|
||||||
|
VkPhysicalDevice physicalDevice,
|
||||||
|
const VulkanFunctions& fn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Service::Supported() {
|
bool Service::Supported() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,21 @@
|
||||||
|
|
||||||
namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
||||||
|
|
||||||
Service::Service(Device* device) : mDevice(device) {
|
Service::Service(Device* device)
|
||||||
mSupported = device->GetDeviceInfo().hasExt(DeviceExt::ExternalSemaphoreZirconHandle);
|
: mDevice(device),
|
||||||
|
mSupported(CheckSupport(device->GetDeviceInfo(),
|
||||||
|
ToBackend(device->GetAdapter())->GetPhysicalDevice(),
|
||||||
|
device->fn)) {
|
||||||
|
}
|
||||||
|
|
||||||
// Early out before we try using extension functions
|
Service::~Service() = default;
|
||||||
if (!mSupported) {
|
|
||||||
return;
|
// static
|
||||||
|
bool Service::CheckSupport(const VulkanDeviceInfo& deviceInfo,
|
||||||
|
VkPhysicalDevice physicalDevice,
|
||||||
|
const VulkanFunctions& fn) {
|
||||||
|
if (!deviceInfo.HasExt(DeviceExt::ExternalSemaphoreZirconHandle)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo;
|
VkPhysicalDeviceExternalSemaphoreInfoKHR semaphoreInfo;
|
||||||
|
@ -37,17 +46,14 @@ namespace dawn_native { namespace vulkan { namespace external_semaphore {
|
||||||
semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR;
|
semaphoreProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR;
|
||||||
semaphoreProperties.pNext = nullptr;
|
semaphoreProperties.pNext = nullptr;
|
||||||
|
|
||||||
mDevice->fn.GetPhysicalDeviceExternalSemaphoreProperties(
|
fn.GetPhysicalDeviceExternalSemaphoreProperties(physicalDevice, &semaphoreInfo,
|
||||||
ToBackend(mDevice->GetAdapter())->GetPhysicalDevice(), &semaphoreInfo,
|
|
||||||
&semaphoreProperties);
|
&semaphoreProperties);
|
||||||
|
|
||||||
VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR |
|
VkFlags requiredFlags = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR |
|
||||||
VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_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() {
|
bool Service::Supported() {
|
||||||
return mSupported;
|
return mSupported;
|
||||||
|
|
|
@ -109,6 +109,10 @@ namespace dawn_native {
|
||||||
std::vector<const char*> GetSupportedExtensions() const;
|
std::vector<const char*> GetSupportedExtensions() const;
|
||||||
WGPUDeviceProperties GetAdapterProperties() 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;
|
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
|
||||||
|
|
Loading…
Reference in New Issue