Put all of the parsing for ICD Manifest data into a separate function.
This cleans it up by not requiring manual tracking of allocated resources
while parsing, and allow much saner 'skipping' of incorrect ICD's.
This commit also addresses an issue where OOM during ICD parsing wasn't
immediately ending parsing and returning.
There was a small issue with the initial version of the portability
enumeration extension where the portability enumeration flag bit would
be passed down to ICDs which did not expect flags to contain anything
other than zero.
While an argument could be made for those drivers to ignore flags they
do not recognize, just like extensions and other 'unknown' things, it
is best to play nice as this is the first instance creation flag bit
added.
When creating a device, the loader looks for the VkDeviceGroupCreateInfo
structure and replaces it with its own. This allows the loader to edit the
struct. However, to do this required editing the pNext chain. Because the
edited chain contained pointers to structures whose lifetimes end when the
vkCreateDevice function returns, the pNext chain is now corrupted.
This commit fixes that by storing a pointer to the user's
VkDeviceGroupCreateInfo and fixing up the pNext chain to use that instead.
Allows drivers and layers to specify if they are 32 bit or 64 bit in the
manifest file. This makes the loader able to prune manifests without
loading the library and finding that it failed to load.
Shuffle the bus IDs for discrete devices pd0, pd3, and pd4. Notably this
puts pd0 from icd0 in between pd4 and pd3 from icd2, making default
sorted order extremely unlikely if not impossible.
When checking for the portability driver field of driver manifests,
the loader did not check if inst was NULL first. Since this function
is called in pre-instance functions, this crashes the loader.
Unless the portability enumeration extension is enabled and the create instance flags
contain VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR, do not enumerate drivers that
contain `is_portability_driver` in their JSON Manifest. This is phase 2 of the release
for the VK_KHR_portability_enumeration extension.
An error message will be printed when no drivers were reported but there was a
portability driver which was skipped over.
Log an error if an application creates a VkDevice from a physical device which
was enumerated from a driver that is a portability driver but the application
didn't correctly enable the portability enumeration flag & extension.
Many tests were using the V6 TestICD, which means that it exports the
EnumerateAdapterPhysicalDevices. The loader then only looks for devices
using that functionality and if the test didn't set it up, the driver
won't have its devices found.
Also:
* Cleaned up handle_validation_tests
* Added WSI setup helpers, which put all the setup code for WSI in one place
* Created a to/from_nondispatch_handle function for TestICD, probably should
be in a more general location
Test fixturing (TEST_F) is useful when there is a lot of common code that needs
to be run for a suite of tests. However, the FrameworkEnvironment encapsulates
almost all of the setup work all tests needs, and so doesn't need to be in a
fixture. Making the add_icd call inside the tests makes it clear which binary
is being used.
This commit also uses the corrent signed/unsigned constants in tests, as was
warned by compilers when enhanced warnings were enabled (/W4 in msvc).
The sorting algorithm needed to take into account both the application
API version as well as the driver API version.
This required additional changes to the sorting algorithm for the fallback
since even if the instance supports the extension or Vulkan 1.1, the individual
drivers may not.
Also, add supporting tests which would catch these cases in the future.
In the process, I realized we assumed that the presence of an extension in the
test_icd indicated "enablement" which was incorrect. So I separated out
that into a set of "enabled instance extensions"
Add "additive" environment variables for adding additional layer
paths or driver JSON files instead of replacing default ones.
Also, rename VK_ICD_FILENAMES to VK_DRIVER_FILES since we're trying
to remove references to ICDs because software driver implementations
of Vulkan aren't ICDs (but continue to support the old name as well).
Added documentation around these changes to reflect the new name and
the new variables.
Angle drops the security enforcement of the loader on environment
variables and the additional "is_high_integrity" checks on my
previous loader change caused failures in the Angle run.
Revert the high-integrity checks and update the layer test to
work properly.
Enable testing to check if the loader is running with elevated
privileges. This is to make sure we're ignoring the appropriate
environment variables in those scenarios to potentially avoid
escalation exploits.
The loader trampoline previously would query all devices every time
vkEnumeratePhysicalDevices was called.
To do this, it would make two calls every time:
- First, it would ignore the passed in user values
- Second, it would query the total number of available devices.
- Third, it would query the values for every available device
This resulted in layers reporting 2 vkEnumeratePhysicalDevices call for
every 1 the application made which could get very polluted in output.
It didn't break any functionality, just made things messy.
This change removes that behavior and adds a bunch of test cases to verify
nothing broke in the move.
If a meta layer which contains `override_paths` is active, all of the paths in
VK_LAYER_PATH are ignored when searchign for explicit layers. This may be changed
changed in the future but for now is better tested and documented.
Adds 2 tests:
* ZeroPhysicalDevices - Return VK_ERROR_INITIALIZATION_FAILED if the driver has zero
physical devices.
* ZeroPhyiscalDeviceExtensions - Return VK_SUCCESS if no physical device extensions are
found.
Add 2 tests to verify that physical devices supporting instance
and device extensions (which are really physical device extensions)
are properly handled.
This should throw an error message if a requested layer didn't load.
This could happen if the JSON file is present, but only a library
exists on the system for the wrong target (like 32 vs 64-bit).
If it did fail because of being the wrong bit-type, we report an info
message only, unless it was directly requested by the application.
Modify the improper bit-depth layer loading test so that it is now 4
tests:
- Verify bad explicit layer generates VK_ERROR_LAYER_NOT_PRESENT error
- Verify bad implicit layer generates only an info in the loader output
- Test case with both a bad implicit and explicit layer with INFO logging
we should see both messages.
- Test case with both a bad implicit and explicit layer with ERROR logging
we should see only the explicit failure message.
Report info failure for ICD wrong bit-type as well.
Finally, fixed a small compilation warning for disabled code.
Increasingly it is common to need more control over what the framework
environment does when adding layers. While only a refactor, this change
makes it easier to extend the functionality by adding data to the
TestLayerDetails struct.
The code to check whether the lib_path specified in add_layer_impl was
improved by using the `.stem()` functionality of the fs::path abstraction.
size_t was replaced with uint32_t where the compiler gave warnings.
Condense the overloaded write function from taking either an icd manifest or a layer manifest
and only take a string. This reduces the amount of copy-paste code.
The loader ICD ordering could be random on Linux based on using readdir
to find ICD manifest files. This can result in random behaviors as
applications that select only the first device can switch which device is
used. To resolve this, we now sort based on device type and then
internally to the types based on PCI bus information.
This also introduces a VK_LOADER_DEFAULT_DEVICE environment variable
that can be used to force a specific PCI device. This environment variable
is actually a duplicate of the MESA_VK_DEVICE_SELECT variable, which is
also looked for if the loader environment variable is not found.
Note, that at least one ICD must support it for the extension to be used at all.
So we only do the sorting if one ICD supports it.
Fixes part of #657
Fix some loader terminator functions for instance physical device
functions (that were pre-Vulkan 1.1). At that point in the API, we
didn't treat VkPhysicalDevices like VkDevices. Now, you must first
query the device for extension support for even VkPhysicalDevice calls.
Back then, the loader had to emulate the functionality.
Added tests to validate many of these functions.
By adding builder style usage to most of the layer interface, it is easier to
create and use layers in tests. This commit refactors the layer interface and
updates most of the tests to use this style.
Move all the behavior found in child classes of FrameworkEnvironment to the
FrameworkEnvironment itself, allowing easier composibility of behavior. The
original idea was to allow special case behavior for specific test cases but
this resulted in a lot of code duplication and difficulty combining different
framework behavior, such as adding a fake ICD and setting VK_ICD_FILENAMES at
the same time.
Passing in a VkInstanceCreateInfo where the layer count or extension count was non zero but
their respective pointers were NULL caused a nullptr dereference. The loader now checks for
this condition in the layer and instance extension validation functions and returns
VK_ERROR_LAYER|EXTENSION_NOT_PRESENT.
The loader recently added support for calling into drivers in
vkGetPhysicalDeviceToolPropertieesEXT. However, it only used the value of
the function pointer to determine if it was safe. It was found that Mesa
drivers will return a non-null function pointer, even though they do not
support the extension, and so the loader called this function pointer which
would then segfault.
The loader prevents this by first checking if the extension is supported by
the physical device. This necessitates calling
vkEnumerateDeviceExtensionProperties and allocating some memory on each call
but since the number of times this function is called should be low, it is
not an undue performance burden. In the future, the loader should cache the
list of extensions when calling vkEnumeratePhysicalDevices so that checking if
a extension function is supported is fast and easy.
Basic tests which just makes sure the trampoline + terminator pass the data
through correctly. Data only originates from TestICD, TestLayer has no
support for the extension.
Warnings/fixes include:
* strcpy/strncpy/wstrcpy
* Dropping static on inline functions
* Use localtime_s
* Name shadowing
* Use wcstombs_s
* 32<->64 bit int conversion
* Silence spurious C4996 generated in vs2015
Added FreeBSD in supported platforms in vk_loader_platform.h, and tests,
defined BSD_VISIBLE and included some necessary header files for
Vulkan-Loader to compile on FreeBSD.
v2: did the same in loader/loader.c (Charles Giessen)
v3: did the same in the tests (Charles Giessen)
v4: applied this downstream patch from Jan Beich because there's no /proc
on FreeBSD: https://github.com/freebsd/freebsd-ports/blob/7caf52e37ba2174dc50a7440d63eec70d7d58ebc/graphics/vulkan-loader/files/patch-loader_vk__loader__platform.h (Jan Beich)
v4: rebased to master and modified tests/loader_regression_tests.cpp,
tests/loader_testing_main.cpp
v5: moved the definition of __BSD_VISIBLE 1 (required for alloca to
work) in CMakeLists.txt from header files (Charles Giessen)
v6: replaced ${CMAKE_SYSTEM_NAME} with CMAKE_SYSTEM_NAME in
loader/CMakeLists.txt to match the style of previous checks (Jan Beich)
v7: replaced add_compile_definitions with target_compile_definitions to
prevent the macro from being applied unnecessarily (Charles Giessen)
More tests can now be written with the new framework. Several of the
shell scripts used tests in vk_loader_validation_tests which were phased
out so no longer necessary.
Tests check to see if the paths are searched by looking at the log.
Makde FrameworkEnvironment contain a debug_log, this is to prevent any
lifetime issues. This prevents the possibility of creating a DebugUtilsLogger
after the InstWrapper.
Had to redo the test framework a bit to make them work.