diff options
author | android-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com> | 2024-01-10 00:41:16 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2024-01-10 00:41:16 +0000 |
commit | c6172ea9da3191bb327bb7e1c547c5fafae7f6e4 (patch) | |
tree | 4c348635386120a7dec04bbc45a9cdd45f94e874 | |
parent | 75c8f477812f28382be62d98a1c08379d2ac1ea2 (diff) | |
parent | c5457fb58de06e2b5fe84818c0729b55a2b18cad (diff) | |
download | swiftshader-c6172ea9da3191bb327bb7e1c547c5fafae7f6e4.tar.gz |
Roll SwiftShader from 91b84ac6d8ea to 2fa7e9b99ae4 (10 revisions) am: d05e995900 am: d8aef706f5 am: c5457fb58d
Original change: https://android-review.googlesource.com/c/platform/external/swiftshader/+/2889256
Change-Id: I6b5a63e75189566bf941e1acda050e131bb9950f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | OWNERS | 4 | ||||
-rw-r--r-- | include/vulkan/vk_google_filtering_precision.h | 41 | ||||
-rw-r--r-- | src/Pipeline/SpirvShaderSampling.cpp | 2 | ||||
-rw-r--r-- | src/Reactor/ExecutableMemory.hpp | 28 | ||||
-rw-r--r-- | src/Reactor/SubzeroReactor.cpp | 6 | ||||
-rw-r--r-- | src/Vulkan/BUILD.gn | 112 | ||||
-rw-r--r-- | src/Vulkan/VkGetProcAddress.cpp | 73 | ||||
-rw-r--r-- | src/Vulkan/VkGetProcAddress.hpp | 1 | ||||
-rw-r--r-- | src/Vulkan/VkPipelineLayout.cpp | 5 | ||||
-rw-r--r-- | src/Vulkan/VkSampler.cpp | 6 | ||||
-rw-r--r-- | src/Vulkan/VkSampler.hpp | 6 | ||||
-rw-r--r-- | src/Vulkan/VkStringify.cpp | 5 | ||||
-rw-r--r-- | src/Vulkan/VkStructConversion.hpp | 78 | ||||
-rw-r--r-- | src/Vulkan/VulkanPlatform.hpp | 1 | ||||
-rw-r--r-- | src/Vulkan/android_host_vk_swiftshader.lds | 1 | ||||
-rw-r--r-- | src/Vulkan/android_vk_swiftshader.lds | 1 | ||||
-rw-r--r-- | src/Vulkan/fuchsia_vk_swiftshader.lds | 1 | ||||
-rw-r--r-- | src/Vulkan/libVulkan.cpp | 86 | ||||
-rw-r--r-- | src/Vulkan/vk_swiftshader.def | 2 | ||||
-rw-r--r-- | src/Vulkan/vk_swiftshader.exports | 1 | ||||
-rw-r--r-- | src/Vulkan/vk_swiftshader.lds | 1 |
21 files changed, 275 insertions, 186 deletions
@@ -7,15 +7,13 @@ # swiftshader.googlesource.com/SwiftShader has ownership and access control # seperate from those controlled by this OWNERS file. -jonahr@google.com syoussefi@google.com geofflang@google.com sugoi@google.com #{LAST_RESORT_SUGGESTION} -shannonwoods@google.com #{LAST_RESORT_SUGGESTION} chrisforbes@google.com #{LAST_RESORT_SUGGESTION} cwallez@google.com #{LAST_RESORT_SUGGESTION} amaiorano@google.com #{LAST_RESORT_SUGGESTION} natsu@google.com #{LAST_RESORT_SUGGESTION} schuffelen@google.com #{LAST_RESORT_SUGGESTION} -bclayton@google.com #{LAST_RESORT_SUGGESTION}
\ No newline at end of file +bclayton@google.com #{LAST_RESORT_SUGGESTION} diff --git a/include/vulkan/vk_google_filtering_precision.h b/include/vulkan/vk_google_filtering_precision.h deleted file mode 100644 index 65e3bcf11..000000000 --- a/include/vulkan/vk_google_filtering_precision.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2020 The SwiftShader Authors. All Rights Reserved. -// -// 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. - -#include "vulkan_core.h" - -// THIS FILE SHOULD BE DELETED IF VK_GOOGLE_sampler_filtering_precision IS EVER ADDED TO THE VULKAN HEADERS -#ifdef VK_GOOGLE_sampler_filtering_precision -#error "VK_GOOGLE_sampler_filtering_precision is already defined in the Vulkan headers, you can delete this file" -#endif - -static constexpr VkStructureType VK_STRUCTURE_TYPE_SAMPLER_FILTERING_PRECISION_GOOGLE = static_cast<VkStructureType>(1000264000); - -#define VK_GOOGLE_sampler_filtering_precisions 1 -#define VK_GOOGLE_SAMPLER_FILTERING_PRECISION_SPEC_VERSION 1 -#define VK_GOOGLE_SAMPLER_FILTERING_PRECISION_EXTENSION_NAME "VK_GOOGLE_sampler_filtering_precision" - -typedef enum VkSamplerFilteringPrecisionModeGOOGLE { - VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE = 0, - VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE = 1, - VK_SAMPLER_FILTERING_PRECISION_MODE_BEGIN_RANGE_GOOGLE = VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE, - VK_SAMPLER_FILTERING_PRECISION_MODE_END_RANGE_GOOGLE = VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE, - VK_SAMPLER_FILTERING_PRECISION_MODE_RANGE_SIZE_GOOGLE = (VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE - VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE + 1), - VK_SAMPLER_FILTERING_PRECISION_MODE_MAX_ENUM_GOOGLE = 0x7FFFFFFF -} VkSamplerFilteringPrecisionModeGOOGLE; - -typedef struct VkSamplerFilteringPrecisionGOOGLE { - VkStructureType sType; - const void* pNext; - VkSamplerFilteringPrecisionModeGOOGLE samplerFilteringPrecisionMode; -} VkSamplerFilteringPrecisionGOOGLE; diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp index 5225a79f3..47ce57b64 100644 --- a/src/Pipeline/SpirvShaderSampling.cpp +++ b/src/Pipeline/SpirvShaderSampling.cpp @@ -66,7 +66,7 @@ SpirvEmitter::ImageSampler *SpirvEmitter::getImageSampler(const vk::Device *devi samplerState.customBorder = vkSamplerState->customBorderColor; samplerState.mipmapFilter = convertMipmapMode(vkSamplerState); - samplerState.highPrecisionFiltering = (vkSamplerState->filteringPrecision == VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE); + samplerState.highPrecisionFiltering = vkSamplerState->highPrecisionFiltering; samplerState.compareEnable = (vkSamplerState->compareEnable != VK_FALSE); samplerState.compareOp = vkSamplerState->compareOp; diff --git a/src/Reactor/ExecutableMemory.hpp b/src/Reactor/ExecutableMemory.hpp index dbbe32aa5..2cd5becdc 100644 --- a/src/Reactor/ExecutableMemory.hpp +++ b/src/Reactor/ExecutableMemory.hpp @@ -41,17 +41,16 @@ void protectMemoryPages(void *memory, size_t bytes, int permissions); void deallocateMemoryPages(void *memory, size_t bytes); template<typename P> -P unaligned_read(P *address) +P unaligned_read(void *address) { P value; memcpy(&value, address, sizeof(P)); return value; } -template<typename P, typename V> -void unaligned_write(P *address, V value) +template<typename P> +void unaligned_write(void *address, P value) { - static_assert(sizeof(V) == sizeof(P), "value size must match pointee size"); memcpy(address, &value, sizeof(P)); } @@ -60,33 +59,29 @@ class unaligned_ref { public: explicit unaligned_ref(void *ptr) - : ptr((P *)ptr) + : ptr(ptr) {} - template<typename V> - P operator=(V value) + unaligned_ref &operator=(P value) { unaligned_write(ptr, value); - return value; + return *this; } operator P() { - return unaligned_read((P *)ptr); + return unaligned_read<P>(ptr); } private: - P *ptr; + void *ptr; }; template<typename P> class unaligned_ptr { - template<typename S> - friend class unaligned_ptr; - public: - unaligned_ptr(P *ptr) + unaligned_ptr(void *ptr) : ptr(ptr) {} @@ -95,10 +90,9 @@ public: return unaligned_ref<P>(ptr); } - template<typename S> - operator S() + explicit operator intptr_t() { - return S(ptr); + return (intptr_t)ptr; } private: diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp index 0a4e9d2ce..c0c6b1d6e 100644 --- a/src/Reactor/SubzeroReactor.cpp +++ b/src/Reactor/SubzeroReactor.cpp @@ -518,7 +518,7 @@ static void *relocateSymbol(const ElfHeader *elfHeader, const Elf32_Rel &relocat } intptr_t address = (intptr_t)elfHeader + target->sh_offset; - unaligned_ptr<int32_t> patchSite = (int32_t *)(address + relocation.r_offset); + unaligned_ptr<int32_t> patchSite = (void *)(address + relocation.r_offset); if(CPUID::ARM) { @@ -603,8 +603,8 @@ static void *relocateSymbol(const ElfHeader *elfHeader, const Elf64_Rela &reloca } intptr_t address = (intptr_t)elfHeader + target->sh_offset; - unaligned_ptr<int32_t> patchSite32 = (int32_t *)(address + relocation.r_offset); - unaligned_ptr<int64_t> patchSite64 = (int64_t *)(address + relocation.r_offset); + unaligned_ptr<int32_t> patchSite32 = (void *)(address + relocation.r_offset); + unaligned_ptr<int64_t> patchSite64 = (void *)(address + relocation.r_offset); switch(relocation.getType()) { diff --git a/src/Vulkan/BUILD.gn b/src/Vulkan/BUILD.gn index 5556abdf0..852068cad 100644 --- a/src/Vulkan/BUILD.gn +++ b/src/Vulkan/BUILD.gn @@ -12,18 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//build/config/ozone.gni") import("//build_overrides/build.gni") import("//build_overrides/wayland.gni") -import("//build/config/ozone.gni") import("../swiftshader.gni") import("vulkan.gni") # Need a separate config to ensure the warnings are added to the end. config("swiftshader_libvulkan_private_config") { if (is_linux) { - defines = [ - "VK_EXPORT=__attribute__((visibility(\"default\")))", - ] + defines = [ "VK_EXPORT=__attribute__((visibility(\"default\")))" ] if (ozone_platform_x11) { defines += [ "VK_USE_PLATFORM_XCB_KHR" ] } @@ -31,9 +29,7 @@ config("swiftshader_libvulkan_private_config") { defines += [ "VK_USE_PLATFORM_WAYLAND_KHR" ] } } else if (is_chromeos) { - defines = [ - "VK_EXPORT=__attribute__((visibility(\"default\")))", - ] + defines = [ "VK_EXPORT=__attribute__((visibility(\"default\")))" ] } else if (is_fuchsia) { defines = [ "VK_USE_PLATFORM_FUCHSIA=1", @@ -62,10 +58,16 @@ config("swiftshader_libvulkan_private_config") { } defines += [ - "SWIFTSHADER_ENABLE_ASTC", # TODO(b/150130101) - "SWIFTSHADER_LEGACY_PRECISION=true", # TODO(chromium:1299047) - "SWIFTSHADER_ZERO_INITIALIZE_DEVICE_MEMORY", + "SWIFTSHADER_ENABLE_ASTC", # TODO(b/150130101) + "SWIFTSHADER_LEGACY_PRECISION=true", # TODO(chromium:1299047) + "SWIFTSHADER_ZERO_INITIALIZE_DEVICE_MEMORY", ] + + if (build_with_chromium) { + # Chromium requires higher precision filtering to pass the layout tests with SwiftShader. + # http://crbug.com/726075 + defines += [ "SWIFTSHADER_HIGH_PRECISION_FILTERING" ] + } } swiftshader_source_set("swiftshader_libvulkan_headers") { @@ -118,15 +120,13 @@ swiftshader_source_set("swiftshader_libvulkan_headers") { "VkSemaphoreExternalLinux.hpp", ] } else if (is_mac) { - sources += [ - "VkDeviceMemoryExternalMac.hpp", - ] + sources += [ "VkDeviceMemoryExternalMac.hpp" ] } else if (is_fuchsia) { sources += [ "VkSemaphoreExternalFuchsia.hpp" ] } } -swiftshader_shared_library("swiftshader_libvulkan") { +swiftshader_source_set("_swiftshader_libvulkan") { sources = [ "VkBuffer.cpp", "VkBufferView.cpp", @@ -170,6 +170,35 @@ swiftshader_shared_library("swiftshader_libvulkan") { libs = [] + if (is_win) { + libs += [ + "gdi32.lib", + "user32.lib", + ] + } + + public_deps = [ + ":swiftshader_libvulkan_headers", + "../../third_party/SPIRV-Tools:spvtools_headers", + "../../third_party/SPIRV-Tools:spvtools_opt", + "../../third_party/SPIRV-Tools:spvtools_val", + "../../third_party/marl:Marl", + "../Device", + "../Pipeline", + "../Reactor:swiftshader_reactor", + "../System", + "../WSI", + ] + + include_dirs = [ + "..", + "../../include", + "../../third_party/SPIRV-Tools/include", + "../../third_party/SPIRV-Headers/include", + ] +} + +swiftshader_shared_library("swiftshader_libvulkan") { # TODO(capn): Use the same ICD name on both Windows and non-Windows. if (is_win) { output_name = "vk_swiftshader" @@ -178,56 +207,33 @@ swiftshader_shared_library("swiftshader_libvulkan") { } if (is_win) { - sources += [ + sources = [ "Vulkan.rc", "vk_swiftshader.def", ] - libs += [ - "gdi32.lib", - "user32.lib", - ] - } - - if (is_mac) { + } else if (is_mac) { ldflags = [ "-Wl,-install_name,@rpath/libvk_swiftshader.dylib", "-Wl,-exported_symbols_list," + rebase_path("vk_swiftshader.exports", root_build_dir), ] } else if (is_linux || is_chromeos || is_fuchsia) { - inputs = [ - "vk_swiftshader.lds", - ] + inputs = [ "vk_swiftshader.lds" ] ldflags = [ # -Bsymbolic binds symbol references to their global definitions within # a shared object, thereby preventing symbol preemption. "-Wl,-Bsymbolic", "-Wl,--version-script=" + - rebase_path("vk_swiftshader.lds", root_build_dir) ] + rebase_path("vk_swiftshader.lds", root_build_dir), + ] } - deps = [ - "../../third_party/SPIRV-Tools:spvtools_opt", - "../../third_party/SPIRV-Tools:spvtools_val", - "../../third_party/SPIRV-Tools:spvtools_headers", - "../../third_party/marl:Marl", - "../Device", - "../Pipeline", - "../Reactor:swiftshader_reactor", - "../System", - "../WSI", - ] - - include_dirs = [ - "..", - "../../include", - "../../third_party/SPIRV-Tools/include", - "../../third_party/SPIRV-Headers/include", - ] + deps = [ ":_swiftshader_libvulkan" ] +} - public_deps = [ - ":swiftshader_libvulkan_headers", - ] +swiftshader_static_library("swiftshader_libvulkan_static") { + complete_static_lib = true + deps = [ ":_swiftshader_libvulkan" ] } # Generates an ICD JSON file that can be used by all targets in this GN build @@ -256,14 +262,8 @@ action("icd_file") { library_path, ] - inputs = [ - input_file, - ] - outputs = [ - output_icd_file, - ] + inputs = [ input_file ] + outputs = [ output_icd_file ] - deps = [ - ":swiftshader_libvulkan", - ] + deps = [ ":swiftshader_libvulkan" ] } diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp index d61f60037..8a8b75914 100644 --- a/src/Vulkan/VkGetProcAddress.cpp +++ b/src/Vulkan/VkGetProcAddress.cpp @@ -16,6 +16,8 @@ #include "VkDevice.hpp" #include <string> +#include <tuple> +#include <type_traits> #include <unordered_map> #include <vector> @@ -40,17 +42,51 @@ static const std::unordered_map<std::string, PFN_vkVoidFunction> globalFunctionP MAKE_VULKAN_GLOBAL_ENTRY(vkEnumerateInstanceExtensionProperties), MAKE_VULKAN_GLOBAL_ENTRY(vkEnumerateInstanceLayerProperties), MAKE_VULKAN_GLOBAL_ENTRY(vkEnumerateInstanceVersion), + + MAKE_VULKAN_GLOBAL_ENTRY(vk_icdGetInstanceProcAddr), + MAKE_VULKAN_GLOBAL_ENTRY(vk_icdNegotiateLoaderICDInterfaceVersion), +#if VK_USE_PLATFORM_WIN32_KHR + MAKE_VULKAN_GLOBAL_ENTRY(vk_icdEnumerateAdapterPhysicalDevices), +#endif // VK_USE_PLATFORM_WIN32_KHR }; #undef MAKE_VULKAN_GLOBAL_ENTRY // Functions that can be obtained through GetInstanceProcAddr with an instance object -#define MAKE_VULKAN_INSTANCE_ENTRY(aFunction) \ - { \ -# aFunction, reinterpret_cast < PFN_vkVoidFunction>(aFunction) \ +struct InstanceFunctionEntry +{ + PFN_vkVoidFunction pfn; + // True if the first argument is a VkPhysicalDevice. See + // https://github.com/KhronosGroup/Vulkan-Loader/blob/main/docs/LoaderDriverInterface.md#reason-for-adding-vk_icdgetphysicaldeviceprocaddr + bool isPhysicalDeviceFn; +}; + +// Template magic to detect if the first argument of a C function is a VkPhysicalDevice. +template<typename T> +struct FunctionArgs +{}; + +template<typename R, typename... Args> +struct FunctionArgs<VKAPI_ATTR R VKAPI_CALL(Args...)> +{ + using Tuple = std::tuple<Args...>; + using FirstType = typename std::tuple_element<0, Tuple>::type; +}; + +template<typename T> +constexpr bool HasPhysicalDeviceFirstArgument = + std::is_same<typename FunctionArgs<T>::FirstType, VkPhysicalDevice>::value; + +#define MAKE_VULKAN_INSTANCE_ENTRY(aFunction) \ + { \ + #aFunction, \ + { \ + reinterpret_cast<PFN_vkVoidFunction>(aFunction), \ + HasPhysicalDeviceFirstArgument<decltype(aFunction)> \ + } \ } // TODO(b/208256248): Avoid exit-time destructor. -static const std::unordered_map<std::string, PFN_vkVoidFunction> instanceFunctionPointers = { +static const std::unordered_map<std::string, InstanceFunctionEntry> instanceFunctionPointers = { MAKE_VULKAN_INSTANCE_ENTRY(vkDestroyInstance), MAKE_VULKAN_INSTANCE_ENTRY(vkEnumeratePhysicalDevices), @@ -652,7 +688,7 @@ PFN_vkVoidFunction GetInstanceProcAddr(Instance *instance, const char *pName) auto instanceFunction = instanceFunctionPointers.find(std::string(pName)); if(instanceFunction != instanceFunctionPointers.end()) { - return instanceFunction->second; + return instanceFunction->second.pfn; } auto deviceFunction = deviceFunctionPointers.find(std::string(pName)); @@ -674,6 +710,33 @@ PFN_vkVoidFunction GetInstanceProcAddr(Instance *instance, const char *pName) return nullptr; } +PFN_vkVoidFunction GetPhysicalDeviceProcAddr(Instance *instance, const char *pName) +{ + // This function must return nullptr if the name is not known, or the function doesn't take a + // VkPhysicalDevice as the first argument. All functions that have a VkPhysicalDevice as first + // argument are instance function, except for vkGetPhysicalDeviceToolPropertiesEXT which seems + // to have been miscategorized as a device extension when it was made. So we special case that + // funcion. + std::string name = pName; + if(name == "vkGetPhysicalDeviceToolPropertiesEXT") + { + return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceToolPropertiesEXT); + } + + auto instanceFunction = instanceFunctionPointers.find(name); + if(instanceFunction == instanceFunctionPointers.end()) + { + return nullptr; + } + + if(!instanceFunction->second.isPhysicalDeviceFn) + { + return nullptr; + } + + return instanceFunction->second.pfn; +} + PFN_vkVoidFunction GetDeviceProcAddr(Device *device, const char *pName) { auto deviceFunction = deviceFunctionPointers.find(std::string(pName)); diff --git a/src/Vulkan/VkGetProcAddress.hpp b/src/Vulkan/VkGetProcAddress.hpp index 03c467f9b..49101baea 100644 --- a/src/Vulkan/VkGetProcAddress.hpp +++ b/src/Vulkan/VkGetProcAddress.hpp @@ -23,6 +23,7 @@ class Device; class Instance; PFN_vkVoidFunction GetInstanceProcAddr(Instance *instance, const char *pName); +PFN_vkVoidFunction GetPhysicalDeviceProcAddr(Instance *instance, const char *pName); PFN_vkVoidFunction GetDeviceProcAddr(Device *device, const char *pName); } // namespace vk diff --git a/src/Vulkan/VkPipelineLayout.cpp b/src/Vulkan/VkPipelineLayout.cpp index f6d19170c..f9724962f 100644 --- a/src/Vulkan/VkPipelineLayout.cpp +++ b/src/Vulkan/VkPipelineLayout.cpp @@ -14,8 +14,8 @@ #include "VkPipelineLayout.hpp" +#include <algorithm> #include <atomic> -#include <cstring> namespace vk { @@ -57,9 +57,8 @@ PipelineLayout::PipelineLayout(const VkPipelineLayoutCreateInfo *pCreateInfo, vo } } - size_t pushConstantRangesSize = pCreateInfo->pushConstantRangeCount * sizeof(VkPushConstantRange); pushConstantRanges = reinterpret_cast<VkPushConstantRange *>(bindingStorage); - memcpy(pushConstantRanges, pCreateInfo->pPushConstantRanges, pushConstantRangesSize); + std::copy(pCreateInfo->pPushConstantRanges, pCreateInfo->pPushConstantRanges + pCreateInfo->pushConstantRangeCount, pushConstantRanges); incRefCount(); } diff --git a/src/Vulkan/VkSampler.cpp b/src/Vulkan/VkSampler.cpp index 1458fa31f..0458f0adf 100644 --- a/src/Vulkan/VkSampler.cpp +++ b/src/Vulkan/VkSampler.cpp @@ -17,7 +17,7 @@ namespace vk { SamplerState::SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::SamplerYcbcrConversion *ycbcrConversion, - VkSamplerFilteringPrecisionModeGOOGLE filteringPrecision, const VkClearColorValue &customBorderColor) + const VkClearColorValue &customBorderColor) : Memset(this, 0) , magFilter(pCreateInfo->magFilter) , minFilter(pCreateInfo->minFilter) @@ -35,7 +35,9 @@ SamplerState::SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::Sam , borderColor(pCreateInfo->borderColor) , customBorderColor(customBorderColor) , unnormalizedCoordinates(pCreateInfo->unnormalizedCoordinates) - , filteringPrecision(filteringPrecision) +#ifdef SWIFTSHADER_HIGH_PRECISION_FILTERING + , highPrecisionFiltering(true) +#endif { if(ycbcrConversion) { diff --git a/src/Vulkan/VkSampler.hpp b/src/Vulkan/VkSampler.hpp index 868418879..4a627c18b 100644 --- a/src/Vulkan/VkSampler.hpp +++ b/src/Vulkan/VkSampler.hpp @@ -27,7 +27,7 @@ namespace vk { struct SamplerState : sw::Memset<SamplerState> { SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::SamplerYcbcrConversion *ycbcrConversion, - VkSamplerFilteringPrecisionModeGOOGLE filteringPrecision, const VkClearColorValue &customBorderColor); + const VkClearColorValue &customBorderColor); // Prevents accessing mipmap levels out of range. static float ClampLod(float lod) @@ -53,7 +53,7 @@ struct SamplerState : sw::Memset<SamplerState> const VkBool32 unnormalizedCoordinates = VK_FALSE; VkSamplerYcbcrModelConversion ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY; - const VkSamplerFilteringPrecisionModeGOOGLE filteringPrecision = VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE; + const bool highPrecisionFiltering = false; bool studioSwing = false; // Narrow range bool swappedChroma = false; // Cb/Cr components in reverse order }; @@ -115,4 +115,4 @@ static inline SamplerYcbcrConversion *Cast(VkSamplerYcbcrConversion object) } // namespace vk -#endif // VK_SAMPLER_HPP_
\ No newline at end of file +#endif // VK_SAMPLER_HPP_ diff --git a/src/Vulkan/VkStringify.cpp b/src/Vulkan/VkStringify.cpp index 87dbe1554..f78125a44 100644 --- a/src/Vulkan/VkStringify.cpp +++ b/src/Vulkan/VkStringify.cpp @@ -16,7 +16,6 @@ #include "System/Debug.hpp" -#include <vulkan/vk_google_filtering_precision.h> #define VULKAN_HPP_NO_EXCEPTIONS #define VULKAN_HPP_NAMESPACE vkhpp #include <vulkan/vulkan.hpp> @@ -30,10 +29,6 @@ std::string Stringify(VkStructureType value) { default: return vkhpp::to_string(static_cast<vkhpp::StructureType>(value)); - - // TODO(b/174746309): This structure's extension has not been upstreamed yet. - case VK_STRUCTURE_TYPE_SAMPLER_FILTERING_PRECISION_GOOGLE: - return "SamplerFilteringPrecisionGOOGLE"; } #else // In Release builds we avoid a dependency on vkhpp::to_string() to reduce binary size. diff --git a/src/Vulkan/VkStructConversion.hpp b/src/Vulkan/VkStructConversion.hpp index 94563cbc6..7c970e31a 100644 --- a/src/Vulkan/VkStructConversion.hpp +++ b/src/Vulkan/VkStructConversion.hpp @@ -17,6 +17,9 @@ #include "VkMemory.hpp" #include "VkStringify.hpp" + +#include "System/Debug.hpp" + #include <cstring> #include <vector> @@ -362,13 +365,13 @@ struct SubmitInfo static SubmitInfo *Allocate(uint32_t submitCount, const VkSubmitInfo *pSubmits) { size_t submitSize = sizeof(SubmitInfo) * submitCount; - size_t totalSize = submitSize; + size_t totalSize = Align8(submitSize); for(uint32_t i = 0; i < submitCount; i++) { - totalSize += pSubmits[i].waitSemaphoreCount * sizeof(VkSemaphore); - totalSize += pSubmits[i].waitSemaphoreCount * sizeof(VkPipelineStageFlags); - totalSize += pSubmits[i].signalSemaphoreCount * sizeof(VkSemaphore); - totalSize += pSubmits[i].commandBufferCount * sizeof(VkCommandBuffer); + totalSize += Align8(pSubmits[i].waitSemaphoreCount * sizeof(VkSemaphore)); + totalSize += Align8(pSubmits[i].waitSemaphoreCount * sizeof(VkPipelineStageFlags)); + totalSize += Align8(pSubmits[i].signalSemaphoreCount * sizeof(VkSemaphore)); + totalSize += Align8(pSubmits[i].commandBufferCount * sizeof(VkCommandBuffer)); for(const auto *extension = reinterpret_cast<const VkBaseInStructure *>(pSubmits[i].pNext); extension != nullptr; extension = reinterpret_cast<const VkBaseInStructure *>(extension->pNext)) @@ -378,8 +381,8 @@ struct SubmitInfo case VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO: { const auto *tlsSubmitInfo = reinterpret_cast<const VkTimelineSemaphoreSubmitInfo *>(extension); - totalSize += tlsSubmitInfo->waitSemaphoreValueCount * sizeof(uint64_t); - totalSize += tlsSubmitInfo->signalSemaphoreValueCount * sizeof(uint64_t); + totalSize += Align8(tlsSubmitInfo->waitSemaphoreValueCount * sizeof(uint64_t)); + totalSize += Align8(tlsSubmitInfo->signalSemaphoreValueCount * sizeof(uint64_t)); } break; case VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO: @@ -396,11 +399,12 @@ struct SubmitInfo } } - uint8_t *mem = static_cast<uint8_t *>( + uint8_t *buffer = static_cast<uint8_t *>( vk::allocateHostMemory(totalSize, vk::HOST_MEMORY_ALLOCATION_ALIGNMENT, vk::NULL_ALLOCATION_CALLBACKS, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)); + uint8_t *mem = buffer; auto submits = new(mem) SubmitInfo[submitCount]; - mem += submitSize; + mem += Align8(submitSize); for(uint32_t i = 0; i < submitCount; i++) { @@ -418,12 +422,12 @@ struct SubmitInfo size_t size = pSubmits[i].waitSemaphoreCount * sizeof(VkSemaphore); submits[i].pWaitSemaphores = reinterpret_cast<VkSemaphore *>(mem); memcpy(mem, pSubmits[i].pWaitSemaphores, size); - mem += size; + mem += Align8(size); size = pSubmits[i].waitSemaphoreCount * sizeof(VkPipelineStageFlags); submits[i].pWaitDstStageMask = reinterpret_cast<VkPipelineStageFlags *>(mem); memcpy(mem, pSubmits[i].pWaitDstStageMask, size); - mem += size; + mem += Align8(size); } if(pSubmits[i].signalSemaphoreCount > 0) @@ -431,7 +435,7 @@ struct SubmitInfo size_t size = pSubmits[i].signalSemaphoreCount * sizeof(VkSemaphore); submits[i].pSignalSemaphores = reinterpret_cast<VkSemaphore *>(mem); memcpy(mem, pSubmits[i].pSignalSemaphores, size); - mem += size; + mem += Align8(size); } if(pSubmits[i].commandBufferCount > 0) @@ -439,7 +443,7 @@ struct SubmitInfo size_t size = pSubmits[i].commandBufferCount * sizeof(VkCommandBuffer); submits[i].pCommandBuffers = reinterpret_cast<VkCommandBuffer *>(mem); memcpy(mem, pSubmits[i].pCommandBuffers, size); - mem += size; + mem += Align8(size); } submits[i].waitSemaphoreValueCount = 0; @@ -462,7 +466,7 @@ struct SubmitInfo size_t size = tlsSubmitInfo->waitSemaphoreValueCount * sizeof(uint64_t); submits[i].pWaitSemaphoreValues = reinterpret_cast<uint64_t *>(mem); memcpy(mem, tlsSubmitInfo->pWaitSemaphoreValues, size); - mem += size; + mem += Align8(size); } if(tlsSubmitInfo->signalSemaphoreValueCount > 0) @@ -471,7 +475,7 @@ struct SubmitInfo size_t size = tlsSubmitInfo->signalSemaphoreValueCount * sizeof(uint64_t); submits[i].pSignalSemaphoreValues = reinterpret_cast<uint64_t *>(mem); memcpy(mem, tlsSubmitInfo->pSignalSemaphoreValues, size); - mem += size; + mem += Align8(size); } } break; @@ -489,21 +493,22 @@ struct SubmitInfo } } + ASSERT(static_cast<size_t>(mem - buffer) == totalSize); return submits; } static SubmitInfo *Allocate(uint32_t submitCount, const VkSubmitInfo2 *pSubmits) { size_t submitSize = sizeof(SubmitInfo) * submitCount; - size_t totalSize = submitSize; + size_t totalSize = Align8(submitSize); for(uint32_t i = 0; i < submitCount; i++) { - totalSize += pSubmits[i].waitSemaphoreInfoCount * sizeof(VkSemaphore); - totalSize += pSubmits[i].waitSemaphoreInfoCount * sizeof(VkPipelineStageFlags); - totalSize += pSubmits[i].waitSemaphoreInfoCount * sizeof(uint64_t); - totalSize += pSubmits[i].signalSemaphoreInfoCount * sizeof(VkSemaphore); - totalSize += pSubmits[i].signalSemaphoreInfoCount * sizeof(uint64_t); - totalSize += pSubmits[i].commandBufferInfoCount * sizeof(VkCommandBuffer); + totalSize += Align8(pSubmits[i].waitSemaphoreInfoCount * sizeof(VkSemaphore)); + totalSize += Align8(pSubmits[i].waitSemaphoreInfoCount * sizeof(VkPipelineStageFlags)); + totalSize += Align8(pSubmits[i].waitSemaphoreInfoCount * sizeof(uint64_t)); + totalSize += Align8(pSubmits[i].signalSemaphoreInfoCount * sizeof(VkSemaphore)); + totalSize += Align8(pSubmits[i].signalSemaphoreInfoCount * sizeof(uint64_t)); + totalSize += Align8(pSubmits[i].commandBufferInfoCount * sizeof(VkCommandBuffer)); for(const auto *extension = reinterpret_cast<const VkBaseInStructure *>(pSubmits[i].pNext); extension != nullptr; extension = reinterpret_cast<const VkBaseInStructure *>(extension->pNext)) @@ -523,11 +528,12 @@ struct SubmitInfo } } - uint8_t *mem = static_cast<uint8_t *>( + uint8_t *buffer = static_cast<uint8_t *>( vk::allocateHostMemory(totalSize, vk::HOST_MEMORY_ALLOCATION_ALIGNMENT, vk::NULL_ALLOCATION_CALLBACKS, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)); + uint8_t *mem = buffer; auto submits = new(mem) SubmitInfo[submitCount]; - mem += submitSize; + mem += Align8(submitSize); for(uint32_t i = 0; i < submitCount; i++) { @@ -549,15 +555,15 @@ struct SubmitInfo { size_t size = submits[i].waitSemaphoreCount * sizeof(VkSemaphore); submits[i].pWaitSemaphores = reinterpret_cast<VkSemaphore *>(mem); - mem += size; + mem += Align8(size); size = submits[i].waitSemaphoreCount * sizeof(VkPipelineStageFlags); submits[i].pWaitDstStageMask = reinterpret_cast<VkPipelineStageFlags *>(mem); - mem += size; + mem += Align8(size); size = submits[i].waitSemaphoreCount * sizeof(uint64_t); submits[i].pWaitSemaphoreValues = reinterpret_cast<uint64_t *>(mem); - mem += size; + mem += Align8(size); for(uint32_t j = 0; j < submits[i].waitSemaphoreCount; j++) { @@ -571,11 +577,11 @@ struct SubmitInfo { size_t size = submits[i].signalSemaphoreCount * sizeof(VkSemaphore); submits[i].pSignalSemaphores = reinterpret_cast<VkSemaphore *>(mem); - mem += size; + mem += Align8(size); size = submits[i].signalSemaphoreCount * sizeof(uint64_t); submits[i].pSignalSemaphoreValues = reinterpret_cast<uint64_t *>(mem); - mem += size; + mem += Align8(size); for(uint32_t j = 0; j < submits[i].signalSemaphoreCount; j++) { @@ -588,7 +594,7 @@ struct SubmitInfo { size_t size = submits[i].commandBufferCount * sizeof(VkCommandBuffer); submits[i].pCommandBuffers = reinterpret_cast<VkCommandBuffer *>(mem); - mem += size; + mem += Align8(size); for(uint32_t j = 0; j < submits[i].commandBufferCount; j++) { @@ -597,6 +603,7 @@ struct SubmitInfo } } + ASSERT(static_cast<size_t>(mem - buffer) == totalSize); return submits; } @@ -616,8 +623,17 @@ struct SubmitInfo uint64_t *pWaitSemaphoreValues; uint32_t signalSemaphoreValueCount; uint64_t *pSignalSemaphoreValues; + +private: + static size_t Align8(size_t size) + { + // Keep all arrays 8-byte aligned, so that an odd number of `VkPipelineStageFlags` does not break the + // alignment of the other fields. + constexpr size_t align = 8; + return (size + align - 1) & ~(align - 1); + } }; } // namespace vk -#endif // VK_STRUCT_CONVERSION_HPP_
\ No newline at end of file +#endif // VK_STRUCT_CONVERSION_HPP_ diff --git a/src/Vulkan/VulkanPlatform.hpp b/src/Vulkan/VulkanPlatform.hpp index 8e736d41c..90e53131e 100644 --- a/src/Vulkan/VulkanPlatform.hpp +++ b/src/Vulkan/VulkanPlatform.hpp @@ -49,7 +49,6 @@ public: typedef VkNonDispatchableHandle<object##Ptr> object; \ template class VkNonDispatchableHandle<object##Ptr>; -#include <vulkan/vk_google_filtering_precision.h> #include <vulkan/vulkan_core.h> #endif // VULKAN_PLATFORM diff --git a/src/Vulkan/android_host_vk_swiftshader.lds b/src/Vulkan/android_host_vk_swiftshader.lds index d9663ed9b..7318bbbf7 100644 --- a/src/Vulkan/android_host_vk_swiftshader.lds +++ b/src/Vulkan/android_host_vk_swiftshader.lds @@ -3,6 +3,7 @@ global: # Loader-ICD interface functions vk_icdGetInstanceProcAddr; vk_icdNegotiateLoaderICDInterfaceVersion; + vk_icdGetPhysicalDeviceProcAddr; # Vulkan 1.0 API entry functions vkCreateInstance; diff --git a/src/Vulkan/android_vk_swiftshader.lds b/src/Vulkan/android_vk_swiftshader.lds index be404d94f..b88bad3a0 100644 --- a/src/Vulkan/android_vk_swiftshader.lds +++ b/src/Vulkan/android_vk_swiftshader.lds @@ -4,6 +4,7 @@ global: # Loader-ICD interface functions vk_icdGetInstanceProcAddr; vk_icdNegotiateLoaderICDInterfaceVersion; + vk_icdGetPhysicalDeviceProcAddr; # Android HAL module info object HMI; diff --git a/src/Vulkan/fuchsia_vk_swiftshader.lds b/src/Vulkan/fuchsia_vk_swiftshader.lds index 2237ffb08..c4f4464b3 100644 --- a/src/Vulkan/fuchsia_vk_swiftshader.lds +++ b/src/Vulkan/fuchsia_vk_swiftshader.lds @@ -6,6 +6,7 @@ global: # Loader-ICD interface functions vk_icdGetInstanceProcAddr; vk_icdNegotiateLoaderICDInterfaceVersion; + vk_icdGetPhysicalDeviceProcAddr; vk_icdInitializeConnectToServiceCallback; local: diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp index 5360f95fd..30b34b6bb 100644 --- a/src/Vulkan/libVulkan.cpp +++ b/src/Vulkan/libVulkan.cpp @@ -96,6 +96,7 @@ #include <algorithm> #include <cinttypes> +#include <cmath> #include <cstring> #include <functional> #include <map> @@ -236,22 +237,56 @@ void ValidateRenderPassPNextChain(VkDevice device, const T *pCreateInfo) } } +// This variable will be set to the negotiated ICD interface version negotiated with the loader. +// It defaults to 1 because if vk_icdNegotiateLoaderICDInterfaceVersion is never called it means +// that the loader doens't support version 2 of that interface. +uint32_t sICDInterfaceVersion = 1; +// Whether any vk_icd* entrypoints were used. This is used to distinguish between applications that +// use the Vulkan loader to load Swiftshader (in which case vk_icd functions are called), and +// applications that load Swiftshader and grab vkGetInstanceProcAddr directly. +bool sICDEntryPointsUsed = false; + } // namespace extern "C" { VK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName) { TRACE("(VkInstance instance = %p, const char* pName = %p)", instance, pName); + sICDEntryPointsUsed = true; return vk::GetInstanceProcAddr(vk::Cast(instance), pName); } VK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion) { - *pSupportedVersion = 3; + sICDEntryPointsUsed = true; + + sICDInterfaceVersion = std::min(*pSupportedVersion, 7u); + *pSupportedVersion = sICDInterfaceVersion; + return VK_SUCCESS; +} + +VK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char *pName) +{ + sICDEntryPointsUsed = true; + return vk::GetPhysicalDeviceProcAddr(vk::Cast(instance), pName); +} + +#if VK_USE_PLATFORM_WIN32_KHR + +VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) +{ + sICDEntryPointsUsed = true; + if(!pPhysicalDevices) + { + *pPhysicalDeviceCount = 0; + } + return VK_SUCCESS; } +#endif // VK_USE_PLATFORM_WIN32_KHR + #if VK_USE_PLATFORM_FUCHSIA // This symbol must be exported by a Fuchsia Vulkan ICD. The Vulkan loader will @@ -266,6 +301,7 @@ VK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdInitializeConnectToServiceCallbac PFN_vkConnectToService callback) { TRACE("(callback = %p)", callback); + sICDEntryPointsUsed = true; vk::icdFuchsiaServiceConnectCallback = callback; return VK_SUCCESS; } @@ -368,9 +404,6 @@ static const ExtensionProperties deviceExtensionProperties[] = { { { VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION } }, #endif { { VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, VK_EXT_PROVOKING_VERTEX_SPEC_VERSION } }, -#if !defined(__ANDROID__) - { { VK_GOOGLE_SAMPLER_FILTERING_PRECISION_EXTENSION_NAME, VK_GOOGLE_SAMPLER_FILTERING_PRECISION_SPEC_VERSION } }, -#endif { { VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, VK_EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION } }, #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT { { VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME, VK_EXT_DEVICE_MEMORY_REPORT_SPEC_VERSION } }, @@ -520,6 +553,39 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCre initializeLibrary(); + // ICD interface rule for version 5 of the interface: + // - If the loader supports version 4 or lower, the driver must fail with + // VK_ERROR_INCOMPATIBLE_DRIVER for all vkCreateInstance calls with apiVersion + // set to > Vulkan 1.0 + // - If the loader supports version 5 or above, the loader must fail with + // VK_ERROR_INCOMPATIBLE_DRIVER if it can't handle the apiVersion, and drivers + // should fail with VK_ERROR_INCOMPATIBLE_DRIVER only if they can not support the + // specified apiVersion. + if(pCreateInfo->pApplicationInfo) + { + uint32_t appApiVersion = pCreateInfo->pApplicationInfo->apiVersion; + if(sICDEntryPointsUsed && sICDInterfaceVersion <= 4) + { + // Any version above 1.0 is an error. + if(VK_API_VERSION_MAJOR(appApiVersion) != 1 || VK_API_VERSION_MINOR(appApiVersion) != 0) + { + return VK_ERROR_INCOMPATIBLE_DRIVER; + } + } + else + { + if(VK_API_VERSION_MAJOR(appApiVersion) > VK_API_VERSION_MINOR(vk::API_VERSION)) + { + return VK_ERROR_INCOMPATIBLE_DRIVER; + } + if((VK_API_VERSION_MAJOR(appApiVersion) == VK_API_VERSION_MINOR(vk::API_VERSION)) && + VK_API_VERSION_MINOR(appApiVersion) > VK_API_VERSION_MINOR(vk::API_VERSION)) + { + return VK_ERROR_INCOMPATIBLE_DRIVER; + } + } + } + if(pCreateInfo->flags != 0) { // Vulkan 1.3: "flags is reserved for future use." "flags must be 0" @@ -2416,7 +2482,6 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerC const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext); const vk::SamplerYcbcrConversion *ycbcrConversion = nullptr; - VkSamplerFilteringPrecisionModeGOOGLE filteringPrecision = VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE; VkClearColorValue borderColor = {}; while(extensionCreateInfo) @@ -2430,15 +2495,6 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerC ycbcrConversion = vk::Cast(samplerYcbcrConversionInfo->conversion); } break; -#if !defined(__ANDROID__) - case VK_STRUCTURE_TYPE_SAMPLER_FILTERING_PRECISION_GOOGLE: - { - const VkSamplerFilteringPrecisionGOOGLE *filteringInfo = - reinterpret_cast<const VkSamplerFilteringPrecisionGOOGLE *>(extensionCreateInfo); - filteringPrecision = filteringInfo->samplerFilteringPrecisionMode; - } - break; -#endif case VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT: { const VkSamplerCustomBorderColorCreateInfoEXT *borderColorInfo = @@ -2455,7 +2511,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerC extensionCreateInfo = extensionCreateInfo->pNext; } - vk::SamplerState samplerState(pCreateInfo, ycbcrConversion, filteringPrecision, borderColor); + vk::SamplerState samplerState(pCreateInfo, ycbcrConversion, borderColor); uint32_t samplerID = vk::Cast(device)->indexSampler(samplerState); VkResult result = vk::Sampler::Create(pAllocator, pCreateInfo, pSampler, samplerState, samplerID); diff --git a/src/Vulkan/vk_swiftshader.def b/src/Vulkan/vk_swiftshader.def index 27354efd0..3e3aca4f2 100644 --- a/src/Vulkan/vk_swiftshader.def +++ b/src/Vulkan/vk_swiftshader.def @@ -3,6 +3,8 @@ EXPORTS ; Loader-ICD interface functions
vk_icdGetInstanceProcAddr
vk_icdNegotiateLoaderICDInterfaceVersion
+ vk_icdGetPhysicalDeviceProcAddr
+ vk_icdEnumerateAdapterPhysicalDevices
; Vulkan 1.0 API entry functions
vkCreateInstance
diff --git a/src/Vulkan/vk_swiftshader.exports b/src/Vulkan/vk_swiftshader.exports index 1153f0027..68819a366 100644 --- a/src/Vulkan/vk_swiftshader.exports +++ b/src/Vulkan/vk_swiftshader.exports @@ -3,6 +3,7 @@ _vkGetInstanceProcAddr # Loader-ICD interface functions _vk_icdGetInstanceProcAddr _vk_icdNegotiateLoaderICDInterfaceVersion +_vk_icdGetPhysicalDeviceProcAddr # Type-strings and type-infos required by sanitizers _ZTS* diff --git a/src/Vulkan/vk_swiftshader.lds b/src/Vulkan/vk_swiftshader.lds index 873e9cdd7..38ed7344c 100644 --- a/src/Vulkan/vk_swiftshader.lds +++ b/src/Vulkan/vk_swiftshader.lds @@ -3,6 +3,7 @@ global: # Loader-ICD interface functions vk_icdGetInstanceProcAddr; vk_icdNegotiateLoaderICDInterfaceVersion; + vk_icdGetPhysicalDeviceProcAddr; # Vulkan 1.0 API entry functions vkCreateInstance; |