spec: avoid infinite InstanceProcAddr cycles

This commit is contained in:
Danny Robson 2019-03-03 22:12:46 +11:00
parent de9418efe6
commit 253d5414da
4 changed files with 38 additions and 18 deletions

View File

@ -1,7 +1 @@
#include <cruft/vk/load/vtable.hpp>
using cruft::vk::load::instance_table;
///////////////////////////////////////////////////////////////////////////////
cruft::vk::load::vendor_table const *cruft::vk::load::v_table = nullptr;

View File

@ -314,7 +314,7 @@ main (void)
//-------------------------------------------------------------------------
cruft::vk::instance instance (
cruft::make_view (layers),
cruft::make_view (extensions.data (), extensions.data () + extensions.size ())
cruft::make_view (extensions.data (), extensions.size ())
);
load_traits (instance);
@ -332,6 +332,13 @@ main (void)
;
debug_info.pfnCallback = vk_debug_callback;
if (0) {
VkDebugReportCallbackEXT obj;
auto res = vkCreateDebugReportCallbackEXT (instance.native (), &debug_info, nullptr, &obj);
if (res != VK_SUCCESS)
panic ("deport report callback");
}
auto debug_callback = cruft::vk::make_owned<cruft::vk::debug_report> (
instance, &debug_info, nullptr
);

View File

@ -852,6 +852,8 @@ def write_dispatch(dst: TextIO, q: List[Type], reg: Registry):
#include <cruft/util/debug.hpp>
#include <cstring>
#pragma GCC diagnostic ignored "-Wunused-parameter"
template <typename HandleT, typename TableT>
@ -881,15 +883,10 @@ def write_dispatch(dst: TextIO, q: List[Type], reg: Registry):
""",
'vkGetInstanceProcAddr': """
if (instance == VK_NULL_HANDLE) {
return (PFN_vkVoidFunction)cruft::vk::load::v_table->vk_icdGetInstanceProcAddr (instance, pName);
}
auto const entry = reinterpret_cast<indirect<VkInstance,cruft::vk::load::instance_table> const*> (instance);
return (entry->table.vkGetInstanceProcAddr)(
entry->handle, pName
);
#define ATTEMPT(NAME) if (!strcmp (#NAME, pName)) return reinterpret_cast<PFN_vkVoidFunction> (&NAME);
MAP_INSTANCE_COMMANDS(ATTEMPT)
#undef ATTEMPT
return nullptr;
""",
'vkCreateDevice': """
@ -924,7 +921,7 @@ def write_dispatch(dst: TextIO, q: List[Type], reg: Registry):
auto wrapped = std::make_unique<indirect<VkPhysicalDevice,cruft::vk::load::instance_table>> ();
wrapped->handle = res[i];
#define GET(NAME) wrapped->table.NAME = wrapped->table.NAME ?: reinterpret_cast<decltype(&NAME)> (vkGetInstanceProcAddr (instance, #NAME));
#define GET(NAME) wrapped->table.NAME = wrapped->table.NAME ?: reinterpret_cast<decltype(&NAME)> (entry->table.vkGetInstanceProcAddr (instance, #NAME));
MAP_INSTANCE_COMMANDS(GET)
#undef GET
@ -957,13 +954,29 @@ def write_dispatch(dst: TextIO, q: List[Type], reg: Registry):
is_creating = False
if obj.is_instance(reg) and obj.params[0].type not in ['VkInstance', 'VkPhysicalDevice']:
forwarding = f"return ::cruft::vk::load::i_table->{obj.name} ({', '.join (i.name for i in obj.params)});"
forwarding = f"""
if (::cruft::vk::load::i_table->{obj.name})
return ::cruft::vk::load::i_table->{obj.name} ({', '.join (i.name for i in obj.params)});
else {{
auto ptr= cruft::vk::load::v_table->vk_icdGetInstanceProcAddr (nullptr, "{obj.name}");
return ((decltype({obj.name})*) (ptr)) ({', '.join (i.name for i in obj.params)});
}}
"""
else:
forwarding = f"""
if constexpr (std::is_same_v<{obj.params[0].type}, VkInstance> ||
std::is_same_v<{obj.params[0].type}, VkPhysicalDevice>) {{
if ({obj.params[0].name} == VK_NULL_HANDLE) {{
auto ptr= cruft::vk::load::v_table->vk_icdGetInstanceProcAddr (nullptr, "{obj.name}");
return ((decltype({obj.name})*) (ptr)) ({', '.join (i.name for i in obj.params)});
}}
}}
auto const entry = reinterpret_cast<
indirect<{obj.params[0].type},cruft::vk::load::{table}_table> const*
> ({obj.params[0].name});
std::clog << "{obj.name}\\n";
return (entry->table.{obj.name})(
{", ".join(['entry->handle'] + [p.name for p in obj.params[1:]])}
);

View File

@ -13,17 +13,20 @@
///////////////////////////////////////////////////////////////////////////////
#if 0
#define INSTANTIATE(KLASS, NAME, FUNC) \
decltype(FUNC)* cruft::vk::life_traits<KLASS>::NAME = nullptr
INSTANTIATE(VkDebugReportCallbackEXT, create, vkCreateDebugReportCallbackEXT);
INSTANTIATE(VkDebugReportCallbackEXT, destroy, vkDestroyDebugReportCallbackEXT);
#endif
///////////////////////////////////////////////////////////////////////////////
void
cruft::vk::load_traits (instance &i)
{
#if 0
#define LOAD(KLASS,NAME,FUNC) \
try { \
cruft::vk::life_traits<KLASS>::NAME = i.proc<decltype(&FUNC)> (#FUNC); \
@ -32,4 +35,7 @@ cruft::vk::load_traits (instance &i)
LOAD(VkDebugReportCallbackEXT, create, vkCreateDebugReportCallbackEXT);
LOAD(VkDebugReportCallbackEXT, destroy, vkDestroyDebugReportCallbackEXT);
#else
(void)i;
#endif
}