Osspial / vk-rs

Collection of Rust libraries for the Vulkan API
MIT License
24 stars 4 forks source link

Cannot generate bindings for debug_report extension #2

Closed jamsch0 closed 8 years ago

jamsch0 commented 8 years ago

I've set up vk_generator to generate some vulkan bindings for both core and some surface extensions. However when I attempt to add the VK_EXT_debug_report extension to the list of extension bindings to generate, the generator fails.

The prelude is outputted (panic function, macro definitions etc.), but nothing else. I tried purposely spelling the extension name wrong just to triple check that I hadn't typed it wrong initially and the generator outputs nothing at all, so I definitely spelt it correctly.

Am I doing something wrong, or is this an issue? Thanks.

Edit: Just run my build script manually and found that vk_generator is panicking. Here's the error and backtrace:

thread '<main>' panicked at 'Unexpected U in Unknown VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; U', /home/toxicwolf/.cargo/registry/src/github.com-1ecc6299db9ec823/vk_generator-0.1.2/src/generator/mod.rs:877
stack backtrace:
   1:     0x556d95d6cabf - std::sys::backtrace::tracing::imp::write::h3800f45f421043b8
   2:     0x556d95d6f6fb - std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::h0ef6c8db532f55dc
   3:     0x556d95d6f383 - std::panicking::default_hook::hf3839060ccbb8764
   4:     0x556d95d67ffd - std::panicking::rust_panic_with_hook::h5dd7da6bb3d06020
   5:     0x556d95d6f941 - std::panicking::begin_panic::h9bf160aee246b9f6
   6:     0x556d95d68f7a - std::panicking::begin_panic_fmt::haf08a9a70a097ee1
   7:     0x556d95d2e9e0 - vk_generator::generator::GenTypes::new::ha13e959c31427176
                        at /mnt/alpha/Development/rust/sonar/sonar-window/<std macros>:8

   8:     0x556d95cc0e1f - vk_generator::generator::_<impl vk_generator..VkRegistry<'a>>::gen_global::h41d8f0f32f9057ea
                        at /home/toxicwolf/.cargo/registry/src/github.com-1ecc6299db9ec823/vk_generator-0.1.2/src/generator/mod.rs:1090
   9:     0x556d95cbb605 - build_script_build::main::he5071e1b00fcfe0e
                        at /mnt/alpha/Development/rust/sonar/sonar-window/build.rs:23
  10:     0x556d95d6efc8 - std::panicking::try::call::hbbf4746cba890ca7
  11:     0x556d95d795ab - __rust_try
  12:     0x556d95d7954e - __rust_maybe_catch_panic
  13:     0x556d95d6ea6e - std::rt::lang_start::hbcefdc316c2fbd45
  14:     0x556d95ccc2f9 - main
  15:     0x7f46981ae2d0 - __libc_start_main
  16:     0x556d95cbaff9 - _start
  17:                0x0 - <unknown>
jamsch0 commented 8 years ago

After some digging, I found this to be the culprit (in the GenPreproc.types hashmap):

"VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT": ApiConst {
    name: Some("VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT"),
    value: Some("VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT")
}

which is generated from this (in the VkRegistry.extns hashmap):

"VK_EXT_debug_report": VkExtn {
    name: Some("VK_EXT_debug_report"),
    num: 12,
    require: [
        ...
        ExtnEnum {
            extends: Some("VkStructureType"),
            profile: None,
            variant: Value {
                name: Some("VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT"),
                value: 1000011000
            }
        },
        ...
        ConstDef {
            name: Some("VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT"),
            value: Some("VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT"),
            profile: None
        },
        ...
    ],
    remove: []
}

In the generated vulkan.h C header, this turns into:

#define VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT

but with the way the generator currently works, VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT is not a valid type and defaults to Unknown, and henceforth the backtrace above.

Osspial commented 8 years ago

The generator's default behavior when encountering this type of constant definition is to ignore it, although that clearly isn't happening with this. I tried to do some fixes on the legacy-enum-patch branch through the GitHub editor, but those are making even the basic tests fail. I'll look into this more when I get access to an actual computer, but if you can make a proper fix for this I'll gladly pull it. The relevant code is in here, where the generator resolves the type of API constants (constants like VK_TRUE, VK_MAX_EXTENSION_NAME_SIZE, etc.). This code also detects whether or not the enum is a renamed enum (dubbed ConstType::LegacyEnum in the code), in which case the constant should get ignored and shouldn't have anything get generated.

jamsch0 commented 8 years ago

I got as far as finding the relevant code you linked, but haven't looked at it enough to determine a proper fix. I quickly tried commenting out this line which seems to solve the problem, but then I get a bunch of errors about function pointers (I assume the debug_report extension function pointers aren't being parsed properly either). I'll take another look tomorrow and see about a fix.

jamsch0 commented 8 years ago

I've fixed the issue with legacy enums here, and have tracked the function pointer issue to this (in the VkRegistry.types):

"PFN_vkDebugReportCallbackEXT": FuncPointer {
    name: Some("PFN_vkDebugReportCallbackEXT"),
    ret: Var(Some("VkBool32")),
    params: [
        Var(Some("VkDebugReportFlagsEXT")),
        Var(Some("VkDebugReportObjectTypeEXT")),
        Var(Some("uint64_t")),
        Var(Some("size_t")),
        Const(Some("int32_t")),
        Const(Some("c_char")),
        MutPtr(Some("c_char"), 1),
        MutPtr(Some("c_void"), 1)
    ]
}

with the relevant lines here and here. Basically, the generator doesn't know what to do with const params.

Edit: I'm not sure that those param types above have been inferred properly, since this is what the generated vulkan.h C header has:

typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)(
    VkDebugReportFlagsEXT                       flags,
    VkDebugReportObjectTypeEXT                  objectType,
    uint64_t                                    object,
    size_t                                      location,
    int32_t                                     messageCode,
    const char*                                 pLayerPrefix,
    const char*                                 pMessage,
    void*                                       pUserData);

To me it looks like the Const(Some("int32_t")) should be Var(..), the Const(Some("c_char")) should be ConstPtr(.., 1)and the MutPtr(Some("c_char"), 1) should be ConstPtr(..).

Edit 2: I think the issue is with the crawler here, at a glance it looks like the "const" is being attached to the tag before it, rather than the tag after (relevant xml).