icd: add stub loader definitions
This commit is contained in:
parent
114f480b4d
commit
cf6ba5e462
@ -4,7 +4,6 @@ project(cruft-vulkan CXX)
|
||||
|
||||
|
||||
###############################################################################
|
||||
find_package (Vulkan REQUIRED)
|
||||
find_package (PythonInterp 3 REQUIRED)
|
||||
find_package (glfw3 REQUIRED)
|
||||
|
||||
@ -15,6 +14,7 @@ endif ()
|
||||
|
||||
|
||||
###############################################################################
|
||||
file (MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/icd")
|
||||
include_directories ("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ endif()
|
||||
add_custom_command (
|
||||
OUTPUT
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/vk.hpp"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/icd/dispatch.cpp"
|
||||
COMMENT
|
||||
"[spec.py] vk.hpp"
|
||||
COMMAND
|
||||
@ -38,6 +39,7 @@ COMMAND
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tools/spec.py"
|
||||
"--src" "${CMAKE_CURRENT_SOURCE_DIR}/specs/xml/vk.xml"
|
||||
"--dst" "${CMAKE_CURRENT_BINARY_DIR}/vk.hpp"
|
||||
"--dispatch" "${CMAKE_CURRENT_BINARY_DIR}/icd/dispatch.cpp"
|
||||
"--platform" "${VK_PLATFORM}"
|
||||
DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tools/spec.py"
|
||||
@ -47,7 +49,27 @@ DEPENDS
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/specs/include/vulkan")
|
||||
|
||||
|
||||
###############################################################################
|
||||
if (WIN32)
|
||||
set(VK_LOADER_VENDOR win32)
|
||||
elseif (LINUX)
|
||||
set(VK_LOADER_VENDOR posix)
|
||||
else ()
|
||||
message (FATAL_ERROR "unhandled vk-loader platform")
|
||||
endif()
|
||||
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
add_library (cruft-vk-icd STATIC
|
||||
${CMAKE_CURRENT_BINARY_DIR}/icd/dispatch.cpp
|
||||
icd/vendor.hpp
|
||||
icd/vendor.cpp
|
||||
icd/vendor_${VK_LOADER_VENDOR}
|
||||
)
|
||||
|
||||
target_link_libraries (cruft-vk-icd cruft-json cruft)
|
||||
|
||||
###############################################################################
|
||||
list (APPEND sources
|
||||
vk.hpp
|
||||
|
||||
@ -107,7 +129,7 @@ list (APPEND sources
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
add_library (cruft-vk STATIC ${sources})
|
||||
target_link_libraries (cruft-vk cruft vulkan)
|
||||
target_link_libraries (cruft-vk cruft-vk-icd cruft)
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
34
icd/vendor.cpp
Normal file
34
icd/vendor.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
#include "vendor.hpp"
|
||||
|
||||
#include <cruft/json/tree.hpp>
|
||||
|
||||
using cruft::vk::icd::vendor;
|
||||
|
||||
|
||||
template <>
|
||||
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 (),
|
||||
.icd = {
|
||||
.library_path = obj["ICD"]["library_path"].as_string ().native (),
|
||||
.api_version = obj["ICD"]["api_version"].as_string (),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
vendor::vendor (icd_t const &_icd):
|
||||
vendor (cruft::library (_icd.icd.library_path))
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
vendor::vendor (::cruft::library &&_library)
|
||||
: m_library (std::move (_library))
|
||||
, m_get_proc (m_library.symbol<decltype(m_get_proc)> ("vk_icdGetInstanceProcAddr"))
|
||||
{
|
||||
vtable.CreateInstance = reinterpret_cast<decltype(vtable.CreateInstance)> (m_get_proc (nullptr, "vkCreateInstance"));
|
||||
}
|
40
icd/vendor.hpp
Normal file
40
icd/vendor.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "vk.hpp"
|
||||
|
||||
#include <cruft/util/library.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <experimental/filesystem>
|
||||
|
||||
|
||||
namespace cruft::vk::icd {
|
||||
struct icd_t {
|
||||
std::string file_format_version;
|
||||
struct {
|
||||
std::experimental::filesystem::path library_path;
|
||||
std::string api_version;
|
||||
} icd;
|
||||
};
|
||||
|
||||
|
||||
std::vector<icd_t>
|
||||
enumerate (void);
|
||||
|
||||
|
||||
class vendor {
|
||||
public:
|
||||
vendor (icd_t const&);
|
||||
vendor (::cruft::library &&);
|
||||
|
||||
struct vtable_t {
|
||||
VkResult (*CreateInstance) (const VkInstanceCreateInfo*, const VkAllocationCallbacks*, VkInstance*) noexcept;
|
||||
} vtable;
|
||||
|
||||
private:
|
||||
using get_proc_t = void* (*)(VkInstance, char const*);
|
||||
|
||||
::cruft::library m_library;
|
||||
get_proc_t const m_get_proc;
|
||||
};
|
||||
}
|
0
icd/vendor_posix.cpp
Normal file
0
icd/vendor_posix.cpp
Normal file
51
icd/vendor_win32.cpp
Normal file
51
icd/vendor_win32.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#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::icd::icd_t>
|
||||
cruft::vk::icd::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;
|
||||
}
|
@ -16,10 +16,19 @@
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#include "../icd/vendor.hpp"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
main (int, char**)
|
||||
{
|
||||
auto all = cruft::vk::icd::enumerate ();
|
||||
for (auto const &i: all) {
|
||||
cruft::vk::icd::vendor v (i);
|
||||
}
|
||||
|
||||
|
||||
std::cout << "available_layers: [ "
|
||||
<< cruft::make_infix (cruft::vk::instance::available_layers ())
|
||||
<< " ]\n";
|
||||
|
@ -652,6 +652,7 @@ if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Transform XML API specification into C++ headers')
|
||||
parser.add_argument('--src', type=str, help='the path to the XML file to transform')
|
||||
parser.add_argument('--dst', type=str, help='the output path for the result')
|
||||
parser.add_argument('--dispatch', type=str, help="the output path for function dispatch")
|
||||
parser.add_argument(
|
||||
'--platform',
|
||||
type=str,
|
||||
@ -662,7 +663,6 @@ if __name__ == '__main__':
|
||||
args = parser.parse_args()
|
||||
|
||||
src = open(args.src, 'r')
|
||||
dst = open(args.dst, 'w')
|
||||
|
||||
tree = ET.parse(src)
|
||||
root = tree.getroot()
|
||||
@ -689,14 +689,29 @@ if __name__ == '__main__':
|
||||
extensions = ["VK_KHR_swapchain", "VK_EXT_debug_report", "VK_KHR_external_memory"]
|
||||
q = reg.serialise(args.platform)
|
||||
|
||||
with open(args.dst, 'w') as dst:
|
||||
dst.write("#pragma once\n")
|
||||
dst.write('extern "C" {\n')
|
||||
for obj in q:
|
||||
dst.write(obj.declare())
|
||||
dst.write('\n')
|
||||
dst.write(obj.define(reg))
|
||||
dst.write('\n')
|
||||
dst.write('}\n')
|
||||
|
||||
dst.write("#pragma once\n")
|
||||
dst.write('extern "C" {\n')
|
||||
for obj in q:
|
||||
dst.write(obj.declare())
|
||||
dst.write('\n')
|
||||
dst.write(obj.define(reg))
|
||||
dst.write('\n')
|
||||
dst.write('}\n')
|
||||
with open(args.dispatch, 'w') as dispatch:
|
||||
dispatch.write("""
|
||||
#include "vk.hpp"
|
||||
#include <cruft/util/debug.hpp>
|
||||
|
||||
#write_types(dst, types)
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
""")
|
||||
for obj in q:
|
||||
if not isinstance(obj, command):
|
||||
continue
|
||||
|
||||
dispatch.write(f"""
|
||||
extern "C" {obj.result} {rename(obj.name)} ({", ".join(obj.params)}) noexcept {{
|
||||
unimplemented ();
|
||||
}}
|
||||
""")
|
||||
|
Loading…
Reference in New Issue
Block a user