mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-10-18 07:55:15 +00:00
Reland after a refactor of how the extension handling work in the Vulkan backend. The original author is David Turner <david.turner.dev@gmail.com>. Certain Vulkan ICDs (Intel ones notably) will compile SPIR-V shaders with an liberal, compiler-selected, subgroup size (i.e. either 8, 16 or 32). For more context, see [1]. This can be a problem for compute, when one shader stores data in device memory using a subgroup-size dependent layout, to be consumed by a another shader. Problems arise when the compiler decides to compile both shaders with different subgroup sizes. To work-around this, the VK_EXT_subgroup_size_control device extension was introduced recently: it allows the device to report the min/max subgroup sizes it provides, and allows the Vulkan program to control the subgroup size precisely if it wants to. This patch adds support to the Vulkan backend to report and enable the extension if it is available. Note that: - This changes the definition of VulkanDeviceKnobs to make room for the required pNext-linked chains of extensions. - A helper class, PNextChainBuilder is also provided in UtilsVulkan.h to make it easy to build pNext-linked extension struct chains at runtime, as required when probing device propertires/features, or when creating a new VkDevice handle. - This modifies VulkanDeviceInfo::GatherDeviceInfo() to use PNextChainBuilder to query extension features and properties in a single call to vkGetPhysicalDevice{Properties,Features}2. Apart from that, there is no change in behaviour in this CL. I.e. a later CL might force a specific subgroup size for consistency, or introduce a new API to let Dawn clients select a fixed subgroup size. [1] https://bugs.freedesktop.org/show_bug.cgi?id=108875 Bug: dawn:464 Change-Id: I01e5c28e7dac66f0a57bf35532eb192912b254fa Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23201 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
142 lines
5.0 KiB
C++
142 lines
5.0 KiB
C++
// Copyright 2020 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.
|
|
|
|
#ifndef DAWNNATIVE_VULKAN_VULKANEXTENSIONS_H_
|
|
#define DAWNNATIVE_VULKAN_VULKANEXTENSIONS_H_
|
|
|
|
#include <bitset>
|
|
#include <unordered_map>
|
|
|
|
namespace dawn_native { namespace vulkan {
|
|
|
|
// The list of known instance extensions. They must be in dependency order (this is checked
|
|
// inside EnsureDependencies)
|
|
enum class InstanceExt {
|
|
// Promoted to 1.1
|
|
GetPhysicalDeviceProperties2,
|
|
ExternalMemoryCapabilities,
|
|
ExternalSemaphoreCapabilities,
|
|
|
|
// Surface extensions
|
|
Surface,
|
|
FuchsiaImagePipeSurface,
|
|
MetalSurface,
|
|
WaylandSurface,
|
|
Win32Surface,
|
|
XcbSurface,
|
|
XlibSurface,
|
|
|
|
// Others
|
|
DebugReport,
|
|
|
|
EnumCount,
|
|
};
|
|
|
|
// A bitset wrapper that is indexed with InstanceExt.
|
|
struct InstanceExtSet {
|
|
std::bitset<static_cast<size_t>(InstanceExt::EnumCount)> extensionBitSet;
|
|
void Set(InstanceExt extension, bool enabled);
|
|
bool Has(InstanceExt extension) const;
|
|
};
|
|
|
|
// Information about a known instance extension.
|
|
struct InstanceExtInfo {
|
|
InstanceExt index;
|
|
const char* name;
|
|
// The version in which this extension was promoted as built with VK_MAKE_VERSION,
|
|
// or NeverPromoted if it was never promoted.
|
|
uint32_t versionPromoted;
|
|
};
|
|
|
|
// Returns the information about a known InstanceExt
|
|
const InstanceExtInfo& GetInstanceExtInfo(InstanceExt ext);
|
|
// Returns a map that maps a Vulkan extension name to its InstanceExt.
|
|
std::unordered_map<std::string, InstanceExt> CreateInstanceExtNameMap();
|
|
|
|
// Sets entries in `extensions` to true if that entry was promoted in Vulkan version `version`
|
|
void MarkPromotedExtensions(InstanceExtSet* extensions, uint32_t version);
|
|
// From a set of extensions advertised as supported by the instance (or promoted), remove all
|
|
// extensions that don't have all their transitive dependencies in advertisedExts.
|
|
InstanceExtSet EnsureDependencies(const InstanceExtSet& advertisedExts);
|
|
|
|
// The list of known device extensions. They must be in dependency order (this is checked
|
|
// inside EnsureDependencies)
|
|
enum class DeviceExt {
|
|
// Promoted to 1.1
|
|
BindMemory2,
|
|
Maintenance1,
|
|
StorageBufferStorageClass,
|
|
GetPhysicalDeviceProperties2,
|
|
GetMemoryRequirements2,
|
|
ExternalMemoryCapabilities,
|
|
ExternalSemaphoreCapabilities,
|
|
ExternalMemory,
|
|
ExternalSemaphore,
|
|
_16BitStorage,
|
|
SamplerYCbCrConversion,
|
|
|
|
// Promoted to 1.2
|
|
ImageFormatList,
|
|
ShaderFloat16Int8,
|
|
|
|
// External* extensions
|
|
ExternalMemoryFD,
|
|
ExternalMemoryDmaBuf,
|
|
ExternalMemoryZirconHandle,
|
|
ExternalSemaphoreFD,
|
|
ExternalSemaphoreZirconHandle,
|
|
|
|
// Others
|
|
DebugMarker,
|
|
ImageDrmFormatModifier,
|
|
Swapchain,
|
|
SubgroupSizeControl,
|
|
|
|
EnumCount,
|
|
};
|
|
|
|
// A bitset wrapper that is indexed with DeviceExt.
|
|
struct DeviceExtSet {
|
|
std::bitset<static_cast<size_t>(DeviceExt::EnumCount)> extensionBitSet;
|
|
void Set(DeviceExt extension, bool enabled);
|
|
bool Has(DeviceExt extension) const;
|
|
};
|
|
|
|
// A bitset wrapper that is indexed with DeviceExt.
|
|
struct DeviceExtInfo {
|
|
DeviceExt index;
|
|
const char* name;
|
|
// The version in which this extension was promoted as built with VK_MAKE_VERSION,
|
|
// or NeverPromoted if it was never promoted.
|
|
uint32_t versionPromoted;
|
|
};
|
|
|
|
// Returns the information about a known DeviceExt
|
|
const DeviceExtInfo& GetDeviceExtInfo(DeviceExt ext);
|
|
// Returns a map that maps a Vulkan extension name to its DeviceExt.
|
|
std::unordered_map<std::string, DeviceExt> CreateDeviceExtNameMap();
|
|
|
|
// Sets entries in `extensions` to true if that entry was promoted in Vulkan version `version`
|
|
void MarkPromotedExtensions(DeviceExtSet* extensions, uint32_t version);
|
|
// From a set of extensions advertised as supported by the device (or promoted), remove all
|
|
// extensions that don't have all their transitive dependencies in advertisedExts or in
|
|
// instanceExts.
|
|
DeviceExtSet EnsureDependencies(const DeviceExtSet& advertisedExts,
|
|
const InstanceExtSet& instanceExts,
|
|
uint32_t icdVersion);
|
|
|
|
}} // namespace dawn_native::vulkan
|
|
|
|
#endif // DAWNNATIVE_VULKAN_VULKANEXTENSIONS_H_
|