libcruft-vk/cruft/vk/load/vendor_win32.cpp

52 lines
1.7 KiB
C++

#include "vendor.hpp"
#include <cruft/json/tree.hpp>
#include <cruft/util/io.hpp>
#include <cruft/util/log.hpp>
#include <cruft/util/win32/registry.hpp>
#include <cruft/util/win32/except.hpp>
///////////////////////////////////////////////////////////////////////////////
std::vector<cruft::vk::load::icd_t>
cruft::vk::load::enumerate()
{
std::vector<icd_t> res;
win32::key root (HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Class\\");
for (auto &&adapter: root.subkeys ()) {
for (auto &&device: adapter.subkeys ()) {
// device keys must be of the form '000X'
auto const name = device.name ();
if (name.size () != 4 ||
name[0] != '0' ||
name[1] != '0' ||
name[2] != '0' ||
!std::isdigit(name[3]))
{
continue;
}
// 'VulkanDriverName' contains the JSON for the ICD data. Parse
// this and add to the list. If we encounter an error then
// quietly drop it.
try {
auto const path = device.data<std::string> ("VulkanDriverName");
auto const text = cruft::slurp<char> (path);
auto const jobj = json::tree::parse (cruft::view{text});
auto const data = from_json<icd_t> (*jobj);
res.push_back (data);
} catch (win32::error const&) {
;
} catch (std::exception const &e) {
LOG_WARNING ("error loading Vulkan ICD manifest, %!", e.what ());
}
}
}
return res;
}