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 (PythonInterp 3 REQUIRED)
|
||||||
find_package (glfw3 REQUIRED)
|
find_package (glfw3 REQUIRED)
|
||||||
|
|
||||||
@ -15,6 +14,7 @@ endif ()
|
|||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
file (MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/icd")
|
||||||
include_directories ("${CMAKE_CURRENT_BINARY_DIR}")
|
include_directories ("${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
|
||||||
|
|
||||||
@ -31,6 +31,7 @@ endif()
|
|||||||
add_custom_command (
|
add_custom_command (
|
||||||
OUTPUT
|
OUTPUT
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/vk.hpp"
|
"${CMAKE_CURRENT_BINARY_DIR}/vk.hpp"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/icd/dispatch.cpp"
|
||||||
COMMENT
|
COMMENT
|
||||||
"[spec.py] vk.hpp"
|
"[spec.py] vk.hpp"
|
||||||
COMMAND
|
COMMAND
|
||||||
@ -38,6 +39,7 @@ COMMAND
|
|||||||
"${CMAKE_CURRENT_SOURCE_DIR}/tools/spec.py"
|
"${CMAKE_CURRENT_SOURCE_DIR}/tools/spec.py"
|
||||||
"--src" "${CMAKE_CURRENT_SOURCE_DIR}/specs/xml/vk.xml"
|
"--src" "${CMAKE_CURRENT_SOURCE_DIR}/specs/xml/vk.xml"
|
||||||
"--dst" "${CMAKE_CURRENT_BINARY_DIR}/vk.hpp"
|
"--dst" "${CMAKE_CURRENT_BINARY_DIR}/vk.hpp"
|
||||||
|
"--dispatch" "${CMAKE_CURRENT_BINARY_DIR}/icd/dispatch.cpp"
|
||||||
"--platform" "${VK_PLATFORM}"
|
"--platform" "${VK_PLATFORM}"
|
||||||
DEPENDS
|
DEPENDS
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/tools/spec.py"
|
"${CMAKE_CURRENT_SOURCE_DIR}/tools/spec.py"
|
||||||
@ -47,7 +49,27 @@ DEPENDS
|
|||||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/specs/include/vulkan")
|
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
|
list (APPEND sources
|
||||||
vk.hpp
|
vk.hpp
|
||||||
|
|
||||||
@ -107,7 +129,7 @@ list (APPEND sources
|
|||||||
|
|
||||||
##-----------------------------------------------------------------------------
|
##-----------------------------------------------------------------------------
|
||||||
add_library (cruft-vk STATIC ${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 <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
#include "../icd/vendor.hpp"
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
int
|
int
|
||||||
main (int, char**)
|
main (int, char**)
|
||||||
{
|
{
|
||||||
|
auto all = cruft::vk::icd::enumerate ();
|
||||||
|
for (auto const &i: all) {
|
||||||
|
cruft::vk::icd::vendor v (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::cout << "available_layers: [ "
|
std::cout << "available_layers: [ "
|
||||||
<< cruft::make_infix (cruft::vk::instance::available_layers ())
|
<< cruft::make_infix (cruft::vk::instance::available_layers ())
|
||||||
<< " ]\n";
|
<< " ]\n";
|
||||||
|
@ -652,6 +652,7 @@ if __name__ == '__main__':
|
|||||||
parser = argparse.ArgumentParser(description='Transform XML API specification into C++ headers')
|
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('--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('--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(
|
parser.add_argument(
|
||||||
'--platform',
|
'--platform',
|
||||||
type=str,
|
type=str,
|
||||||
@ -662,7 +663,6 @@ if __name__ == '__main__':
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
src = open(args.src, 'r')
|
src = open(args.src, 'r')
|
||||||
dst = open(args.dst, 'w')
|
|
||||||
|
|
||||||
tree = ET.parse(src)
|
tree = ET.parse(src)
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
@ -689,7 +689,7 @@ if __name__ == '__main__':
|
|||||||
extensions = ["VK_KHR_swapchain", "VK_EXT_debug_report", "VK_KHR_external_memory"]
|
extensions = ["VK_KHR_swapchain", "VK_EXT_debug_report", "VK_KHR_external_memory"]
|
||||||
q = reg.serialise(args.platform)
|
q = reg.serialise(args.platform)
|
||||||
|
|
||||||
|
with open(args.dst, 'w') as dst:
|
||||||
dst.write("#pragma once\n")
|
dst.write("#pragma once\n")
|
||||||
dst.write('extern "C" {\n')
|
dst.write('extern "C" {\n')
|
||||||
for obj in q:
|
for obj in q:
|
||||||
@ -699,4 +699,19 @@ if __name__ == '__main__':
|
|||||||
dst.write('\n')
|
dst.write('\n')
|
||||||
dst.write('}\n')
|
dst.write('}\n')
|
||||||
|
|
||||||
#write_types(dst, types)
|
with open(args.dispatch, 'w') as dispatch:
|
||||||
|
dispatch.write("""
|
||||||
|
#include "vk.hpp"
|
||||||
|
#include <cruft/util/debug.hpp>
|
||||||
|
|
||||||
|
#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