Only expose device extension functions that are enabled
If a device extension isn't enabled, then the associated extension
functions shouldn't be exposed through vkGetDeviceProcAddr().
Bug b/117974925
Change-Id: I828cf9ff9d8aaf22c15a5379cfb9d93612d23360
Tests: dEQP-VK.api.version_check.entry_points
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31696
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Vulkan/VkDevice.cpp b/src/Vulkan/VkDevice.cpp
index 6b082e6..9871872 100644
--- a/src/Vulkan/VkDevice.cpp
+++ b/src/Vulkan/VkDevice.cpp
@@ -37,7 +37,9 @@
{
Device::Device(const Device::CreateInfo* info, void* mem)
- : physicalDevice(info->pPhysicalDevice), queues(reinterpret_cast<Queue*>(mem))
+ : physicalDevice(info->pPhysicalDevice),
+ queues(reinterpret_cast<Queue*>(mem)),
+ enabledExtensionCount(info->pCreateInfo->enabledExtensionCount)
{
const auto* pCreateInfo = info->pCreateInfo;
for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
@@ -57,6 +59,12 @@
}
}
+ extensions = reinterpret_cast<ExtensionName*>(static_cast<uint8_t*>(mem) + (sizeof(Queue) * queueCount));
+ for(uint32_t i = 0; i < enabledExtensionCount; i++)
+ {
+ strncpy(extensions[i], pCreateInfo->ppEnabledExtensionNames[i], VK_MAX_EXTENSION_NAME_SIZE);
+ }
+
if(pCreateInfo->enabledLayerCount)
{
// "The ppEnabledLayerNames and enabledLayerCount members of VkDeviceCreateInfo are deprecated and their values must be ignored by implementations."
@@ -87,7 +95,19 @@
queueCount += info->pCreateInfo->pQueueCreateInfos[i].queueCount;
}
- return sizeof(Queue) * queueCount;
+ return (sizeof(Queue) * queueCount) + (info->pCreateInfo->enabledExtensionCount * sizeof(ExtensionName));
+}
+
+bool Device::hasExtension(const char* extensionName) const
+{
+ for(uint32_t i = 0; i < enabledExtensionCount; i++)
+ {
+ if(strncmp(extensions[i], extensionName, VK_MAX_EXTENSION_NAME_SIZE) == 0)
+ {
+ return true;
+ }
+ }
+ return false;
}
VkQueue Device::getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) const
diff --git a/src/Vulkan/VkDevice.hpp b/src/Vulkan/VkDevice.hpp
index 2b129f1..3ce466d 100644
--- a/src/Vulkan/VkDevice.hpp
+++ b/src/Vulkan/VkDevice.hpp
@@ -43,6 +43,7 @@
static size_t ComputeRequiredAllocationSize(const CreateInfo* info);
+ bool hasExtension(const char* extensionName) const;
VkQueue getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) const;
VkResult waitForFences(uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout);
VkResult waitIdle();
@@ -58,6 +59,9 @@
Queue* queues = nullptr;
uint32_t queueCount = 0;
sw::Blitter* blitter = nullptr;
+ uint32_t enabledExtensionCount = 0;
+ typedef char ExtensionName[VK_MAX_EXTENSION_NAME_SIZE];
+ ExtensionName* extensions = nullptr;
};
using DispatchableDevice = DispatchableObject<Device, VkDevice>;
diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp
index 0938ce1..194f146 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -13,9 +13,11 @@
// limitations under the License.
#include "VkGetProcAddress.h"
+#include "VkDevice.hpp"
#include <unordered_map>
#include <string>
+#include <vector>
#ifdef __ANDROID__
#include <cerrno>
@@ -234,44 +236,90 @@
MAKE_VULKAN_DEVICE_ENTRY(vkDestroyDescriptorUpdateTemplate),
MAKE_VULKAN_DEVICE_ENTRY(vkUpdateDescriptorSetWithTemplate),
MAKE_VULKAN_DEVICE_ENTRY(vkGetDescriptorSetLayoutSupport),
- // VK_KHR_descriptor_update_template
- MAKE_VULKAN_DEVICE_ENTRY(vkCreateDescriptorUpdateTemplateKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkDestroyDescriptorUpdateTemplateKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkUpdateDescriptorSetWithTemplateKHR),
- // VK_KHR_device_group
- MAKE_VULKAN_DEVICE_ENTRY(vkGetDeviceGroupPeerMemoryFeaturesKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkCmdSetDeviceMaskKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkCmdDispatchBaseKHR),
- // VK_KHR_maintenance1
- MAKE_VULKAN_DEVICE_ENTRY(vkTrimCommandPoolKHR),
- // VK_KHR_sampler_ycbcr_conversion
- MAKE_VULKAN_DEVICE_ENTRY(vkCreateSamplerYcbcrConversionKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkDestroySamplerYcbcrConversionKHR),
- // VK_KHR_bind_memory2
- MAKE_VULKAN_DEVICE_ENTRY(vkBindBufferMemory2KHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkBindImageMemory2KHR),
- // VK_KHR_get_memory_requirements2
- MAKE_VULKAN_DEVICE_ENTRY(vkGetImageMemoryRequirements2KHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkGetBufferMemoryRequirements2KHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkGetImageSparseMemoryRequirements2KHR),
- // VK_KHR_maintenance3
- MAKE_VULKAN_DEVICE_ENTRY(vkGetDescriptorSetLayoutSupportKHR),
-#ifndef __ANDROID__
- // VK_KHR_swapchain
- MAKE_VULKAN_DEVICE_ENTRY(vkCreateSwapchainKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkDestroySwapchainKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkGetSwapchainImagesKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkAcquireNextImageKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkQueuePresentKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkGetDeviceGroupPresentCapabilitiesKHR),
- MAKE_VULKAN_DEVICE_ENTRY(vkGetDeviceGroupSurfacePresentModesKHR),
-#else
+#ifdef __ANDROID__
MAKE_VULKAN_DEVICE_ENTRY(vkGetSwapchainGrallocUsageANDROID),
MAKE_VULKAN_DEVICE_ENTRY(vkGetSwapchainGrallocUsage2ANDROID),
MAKE_VULKAN_DEVICE_ENTRY(vkAcquireImageANDROID),
MAKE_VULKAN_DEVICE_ENTRY(vkQueueSignalReleaseImageANDROID),
#endif
};
+
+static const std::vector<std::pair<const char*, std::unordered_map<std::string, PFN_vkVoidFunction>>> deviceExtensionFunctionPointers =
+{
+ // VK_KHR_descriptor_update_template
+ {
+ VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME,
+ {
+ MAKE_VULKAN_DEVICE_ENTRY(vkCreateDescriptorUpdateTemplateKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkDestroyDescriptorUpdateTemplateKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkUpdateDescriptorSetWithTemplateKHR),
+ }
+ },
+ // VK_KHR_device_group
+ {
+ VK_KHR_DEVICE_GROUP_EXTENSION_NAME,
+ {
+ MAKE_VULKAN_DEVICE_ENTRY(vkGetDeviceGroupPeerMemoryFeaturesKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkCmdSetDeviceMaskKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkCmdDispatchBaseKHR),
+ }
+ },
+ // VK_KHR_maintenance1
+ {
+ VK_KHR_MAINTENANCE1_EXTENSION_NAME,
+ {
+ MAKE_VULKAN_DEVICE_ENTRY(vkTrimCommandPoolKHR),
+ }
+ },
+ // VK_KHR_sampler_ycbcr_conversion
+ {
+ VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
+ {
+ MAKE_VULKAN_DEVICE_ENTRY(vkCreateSamplerYcbcrConversionKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkDestroySamplerYcbcrConversionKHR),
+ }
+ },
+ // VK_KHR_bind_memory2
+ {
+ VK_KHR_BIND_MEMORY_2_EXTENSION_NAME,
+ {
+ MAKE_VULKAN_DEVICE_ENTRY(vkBindBufferMemory2KHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkBindImageMemory2KHR),
+ }
+ },
+ // VK_KHR_get_memory_requirements2
+ {
+ VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
+ {
+ MAKE_VULKAN_DEVICE_ENTRY(vkGetImageMemoryRequirements2KHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkGetBufferMemoryRequirements2KHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkGetImageSparseMemoryRequirements2KHR),
+ }
+ },
+ // VK_KHR_maintenance3
+ {
+ VK_KHR_MAINTENANCE3_EXTENSION_NAME,
+ {
+ MAKE_VULKAN_DEVICE_ENTRY(vkGetDescriptorSetLayoutSupportKHR),
+ }
+ },
+#ifndef __ANDROID__
+ // VK_KHR_swapchain
+ {
+ VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+ {
+ MAKE_VULKAN_DEVICE_ENTRY(vkCreateSwapchainKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkDestroySwapchainKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkGetSwapchainImagesKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkAcquireNextImageKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkQueuePresentKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkGetDeviceGroupPresentCapabilitiesKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkGetDeviceGroupSurfacePresentModesKHR),
+ }
+ },
+#endif
+};
+
#undef MAKE_VULKAN_DEVICE_ENTRY
PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName)
@@ -308,6 +356,19 @@
return deviceFunction->second;
}
+ vk::Device* myDevice = Cast(device);
+ for(const auto& deviceExtensionFunctions : deviceExtensionFunctionPointers)
+ {
+ if(myDevice->hasExtension(deviceExtensionFunctions.first))
+ {
+ deviceFunction = deviceExtensionFunctions.second.find(std::string(pName));
+ if(deviceFunction != deviceExtensionFunctions.second.end())
+ {
+ return deviceFunction->second;
+ }
+ }
+ }
+
return nullptr;
}
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index d734bb0..3e56519 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -1290,8 +1290,7 @@
switch(extensionCreateInfo->sType)
{
case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT:
- ASSERT(!HasExtensionProperty(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, deviceExtensionProperties,
- sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0])));
+ ASSERT(!vk::Cast(device)->hasExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME));
break;
default:
UNIMPLEMENTED("extensionCreateInfo->sType");