icd: add basic posix icd discovery

This commit is contained in:
Danny Robson 2018-09-08 12:31:43 +10:00
parent 9dfc951193
commit 11c142f849
4 changed files with 71 additions and 15 deletions

View File

@ -10,7 +10,7 @@ cruft::vk::icd::icd_t
json::tree::io<cruft::vk::icd::icd_t>::deserialise (json::tree::node const &obj)
{
return {
.file_format_version = obj["'file_format_version"].as_string (),
.file_format_version = obj["file_format_version"].as_string (),
.icd = {
.library_path = obj["ICD"]["library_path"].as_string ().native (),
.api_version = obj["ICD"]["api_version"].as_string (),

View File

@ -8,6 +8,7 @@
#include <experimental/filesystem>
///////////////////////////////////////////////////////////////////////////////
namespace cruft::vk::icd {
struct icd_t {
std::string file_format_version;
@ -28,7 +29,11 @@ namespace cruft::vk::icd {
vendor (::cruft::library &&);
struct vtable_t {
VkResult (*CreateInstance) (const VkInstanceCreateInfo*, const VkAllocationCallbacks*, VkInstance*) noexcept;
VkResult (*CreateInstance) (
VkInstanceCreateInfo const*,
VkAllocationCallbacks const*,
VkInstance*
) noexcept;
} vtable;
private:

View File

@ -0,0 +1,53 @@
#include "vendor.hpp"
#include <cruft/util/log.hpp>
#include <cruft/util/posix/except.hpp>
#include <cruft/json/tree.hpp>
#include <wordexp.h>
namespace fs = std::experimental::filesystem;
///////////////////////////////////////////////////////////////////////////////
std::vector<cruft::vk::icd::icd_t>
cruft::vk::icd::enumerate (void)
{
// The predefined, ordered, search locations for manifests
static char const *locations[] = {
"/usr/local/etc/vulkan/icd.d/",
"/usr/local/share/vulkan/icd.d/",
"/etc/vulkan/icd.d/",
"/usr/share/vulkan/icd.d/",
"$HOME/.local/share/vulkan/icd.d/",
};
std::vector<icd_t> found;
for (auto const &loc: locations) {
// We use wordexp rather than std::filesystem because we need to
// perform environment expansion to account of $HOME in at least one
// of the paths, so we may as well just use the same approach for
// everything else too.
wordexp_t words;
posix::error::try_call (wordexp, loc, &words, WRDE_NOCMD | WRDE_UNDEF);
std::unique_ptr<wordexp_t, decltype(&wordfree)> cleanup {&words, &wordfree};
// Just try to parse everything we can find in the directory (if it
// happens to exist) and fail out if it doesn't work. Marginally safer
// than doing various tests.
for (size_t i = 0; i < words.we_wordc; ++i) {
try {
for (auto const &path: fs::directory_iterator (words.we_wordv[i])) {
found.push_back (from_json<icd_t> (*json::tree::parse (path)));
}
} catch (std::exception const &e) {
LOG_INFO("failed to parse icd manifest; %!", e.what ());
}
}
}
return found;
}

View File

@ -23,19 +23,17 @@
int
main (int, char**)
{
auto all = cruft::vk::icd::enumerate ();
for (auto const &i: all) {
for (auto const &i: cruft::vk::icd::enumerate ()) {
cruft::vk::icd::vendor v (i);
//std::cout << "available_layers: [ "
// << cruft::make_infix (cruft::vk::instance::available_layers ())
// << " ]\n";
cruft::vk::instance instance;
std::cout << "instance: " << instance << '\n';
for (const auto &d: cruft::vk::physical_device::find (instance))
std::cout << d << '\n';
}
std::cout << "available_layers: [ "
<< cruft::make_infix (cruft::vk::instance::available_layers ())
<< " ]\n";
cruft::vk::instance instance;
std::cout << "instance: " << instance << '\n';
for (const auto &d: cruft::vk::physical_device::find (instance))
std::cout << d << '\n';
}