Check FP16 support on vulkan backend
This patch check FP16 support on vulkan backend, and introduces
the shader_float16 extension.
BUG=dawn:426
TEST=dawn_end2end_tests
Change-Id: Ie09568a416ce9eb2c11afeede3e7da520550d5fb
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/21901
Commit-Queue: Xinghua Cao <xinghua.cao@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/Extensions.cpp b/src/dawn_native/Extensions.cpp
index a2b5a9d..de6214f 100644
--- a/src/dawn_native/Extensions.cpp
+++ b/src/dawn_native/Extensions.cpp
@@ -34,7 +34,12 @@
{{Extension::TextureCompressionBC,
{"texture_compression_bc", "Support Block Compressed (BC) texture formats",
"https://bugs.chromium.org/p/dawn/issues/detail?id=42"},
- &WGPUDeviceProperties::textureCompressionBC}}};
+ &WGPUDeviceProperties::textureCompressionBC},
+ {Extension::ShaderFloat16,
+ {"shader_float16",
+ "Support 16bit float arithmetic and declarations in uniform and storage buffers",
+ "https://bugs.chromium.org/p/dawn/issues/detail?id=426"},
+ &WGPUDeviceProperties::shaderFloat16}}};
} // anonymous namespace
diff --git a/src/dawn_native/Extensions.h b/src/dawn_native/Extensions.h
index 6e6d82d..9dbdf77 100644
--- a/src/dawn_native/Extensions.h
+++ b/src/dawn_native/Extensions.h
@@ -25,6 +25,7 @@
enum class Extension {
TextureCompressionBC,
+ ShaderFloat16,
EnumCount,
InvalidEnum = EnumCount,
diff --git a/src/dawn_native/vulkan/AdapterVk.cpp b/src/dawn_native/vulkan/AdapterVk.cpp
index 9cbe82d..86041df 100644
--- a/src/dawn_native/vulkan/AdapterVk.cpp
+++ b/src/dawn_native/vulkan/AdapterVk.cpp
@@ -73,6 +73,13 @@
if (mDeviceInfo.features.textureCompressionBC == VK_TRUE) {
mSupportedExtensions.EnableExtension(Extension::TextureCompressionBC);
}
+
+ if (mDeviceInfo.shaderFloat16Int8 &&
+ mDeviceInfo.shaderFloat16Int8Features.shaderFloat16 == VK_TRUE &&
+ mDeviceInfo._16BitStorage &&
+ mDeviceInfo._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE) {
+ mSupportedExtensions.EnableExtension(Extension::ShaderFloat16);
+ }
}
ResultOrError<DeviceBase*> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp
index 9edefcb..a4a81a4 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -333,6 +333,25 @@
usedKnobs.features.textureCompressionBC = VK_TRUE;
}
+ if (IsExtensionEnabled(Extension::ShaderFloat16)) {
+ const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
+ ASSERT(deviceInfo.shaderFloat16Int8 &&
+ deviceInfo.shaderFloat16Int8Features.shaderFloat16 == VK_TRUE &&
+ deviceInfo._16BitStorage &&
+ deviceInfo._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE);
+
+ usedKnobs.shaderFloat16Int8 = true;
+ usedKnobs.shaderFloat16Int8Features.shaderFloat16 = VK_TRUE;
+ extensionsToRequest.push_back(kExtensionNameKhrShaderFloat16Int8);
+
+ usedKnobs._16BitStorage = true;
+ usedKnobs._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE;
+ // VK_KHR_16bit_storage is promoted to Vulkan 1.1.
+ if (deviceInfo.properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
+ extensionsToRequest.push_back(kExtensionNameKhr16BitStorage);
+ }
+ }
+
// Find a universal queue family
{
// Note that GRAPHICS and COMPUTE imply TRANSFER so we don't need to check for it.
diff --git a/src/dawn_native/vulkan/VulkanInfo.cpp b/src/dawn_native/vulkan/VulkanInfo.cpp
index 2a32262..b2d9928 100644
--- a/src/dawn_native/vulkan/VulkanInfo.cpp
+++ b/src/dawn_native/vulkan/VulkanInfo.cpp
@@ -79,6 +79,8 @@
const char kExtensionNameKhrXlibSurface[] = "VK_KHR_xlib_surface";
const char kExtensionNameFuchsiaImagePipeSurface[] = "VK_FUCHSIA_imagepipe_surface";
const char kExtensionNameKhrMaintenance1[] = "VK_KHR_maintenance1";
+ const char kExtensionNameKhrShaderFloat16Int8[] = "VK_KHR_shader_float16_int8";
+ const char kExtensionNameKhr16BitStorage[] = "VK_KHR_16bit_storage";
ResultOrError<VulkanGlobalInfo> GatherGlobalInfo(const Backend& backend) {
VulkanGlobalInfo info = {};
@@ -221,6 +223,7 @@
ResultOrError<VulkanDeviceInfo> GatherDeviceInfo(const Adapter& adapter) {
VulkanDeviceInfo info = {};
VkPhysicalDevice physicalDevice = adapter.GetPhysicalDevice();
+ const VulkanGlobalInfo& globalInfo = adapter.GetBackend()->GetGlobalInfo();
const VulkanFunctions& vkFunctions = adapter.GetBackend()->GetFunctions();
// Gather general info about the device
@@ -311,6 +314,23 @@
if (IsExtensionName(extension, kExtensionNameKhrMaintenance1)) {
info.maintenance1 = true;
}
+ if (IsExtensionName(extension, kExtensionNameKhrShaderFloat16Int8) &&
+ globalInfo.getPhysicalDeviceProperties2) {
+ info.shaderFloat16Int8 = true;
+ info.shaderFloat16Int8Features.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
+
+ VkPhysicalDeviceFeatures2KHR physicalDeviceFeatures2 = {};
+ physicalDeviceFeatures2.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
+ physicalDeviceFeatures2.pNext = &info.shaderFloat16Int8Features;
+ vkFunctions.GetPhysicalDeviceFeatures2(physicalDevice,
+ &physicalDeviceFeatures2);
+ }
+ if (IsExtensionName(extension, kExtensionNameKhr16BitStorage) &&
+ globalInfo.getPhysicalDeviceProperties2) {
+ info._16BitStorage = true;
+ }
}
}
@@ -319,6 +339,20 @@
info.maintenance1 = true;
}
+ // VK_KHR_16bit_storage is promoted to Vulkan 1.1, so gather information if either is
+ // present, and mark the extension as available.
+ if (info._16BitStorage || info.properties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
+ ASSERT(globalInfo.getPhysicalDeviceProperties2);
+ info._16BitStorage = true;
+ info._16BitStorageFeatures.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
+
+ VkPhysicalDeviceFeatures2 physicalDeviceFeatures2 = {};
+ physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+ physicalDeviceFeatures2.pNext = &info._16BitStorageFeatures;
+ vkFunctions.GetPhysicalDeviceFeatures2(physicalDevice, &physicalDeviceFeatures2);
+ }
+
// TODO(cwallez@chromium.org): gather info about formats
return std::move(info);
diff --git a/src/dawn_native/vulkan/VulkanInfo.h b/src/dawn_native/vulkan/VulkanInfo.h
index 354d9b3..81ef054 100644
--- a/src/dawn_native/vulkan/VulkanInfo.h
+++ b/src/dawn_native/vulkan/VulkanInfo.h
@@ -52,6 +52,8 @@
extern const char kExtensionNameKhrXlibSurface[];
extern const char kExtensionNameFuchsiaImagePipeSurface[];
extern const char kExtensionNameKhrMaintenance1[];
+ extern const char kExtensionNameKhrShaderFloat16Int8[];
+ extern const char kExtensionNameKhr16BitStorage[];
// Global information - gathered before the instance is created
struct VulkanGlobalKnobs {
@@ -85,6 +87,8 @@
// Device information - gathered before the device is created.
struct VulkanDeviceKnobs {
VkPhysicalDeviceFeatures features;
+ VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shaderFloat16Int8Features;
+ VkPhysicalDevice16BitStorageFeaturesKHR _16BitStorageFeatures;
// Extensions, promoted extensions are set to true if their core version is supported.
bool debugMarker = false;
@@ -98,6 +102,8 @@
bool externalSemaphoreZirconHandle = false;
bool swapchain = false;
bool maintenance1 = false;
+ bool shaderFloat16Int8 = false;
+ bool _16BitStorage = false;
};
struct VulkanDeviceInfo : VulkanDeviceKnobs {