RenderIndex creation crashes because of std::type_info mismatch for Hgi*

Hi Guys,
I am setting up a small POC program, which uses a custom Scene delegate with the Vulkan HGI on OpenUSD version 24.03. I am linking OpenUSD dynamically. I did the hydra initialisation similar to testHdxCameraAndLight.cpp So I created the HGI, constructed drivers from it and gave it into the constructor of RenderIndex:

   HgiUniquePtr hgi = Hgi::CreatePlatformDefaultHgi();
    HdDriver driver{HgiTokens->renderDriver, VtValue(hgi.get())};

    HdStRenderDelegate renderDelegate;
    std::unique_ptr<HdRenderIndex> index(HdRenderIndex::New(&renderDelegate, {&driver})); 

During construction it crashes, because the driver VtValue is checked if it is holding an Hgi*. This check compares the std::type_info (T1) stored in the VtValue (which is typeid(Hgi*)) with the std::type_info of Hgi* (T2) in HdStRenderDelegate::SetDrivers() (hdDriver->driver.IsHolding<Hgi*>, which does the comparison with TfSafeTypeCompare, which compares the two std::type_infos).

This check fails and so the RenderDelegates Hgi* is left a nullptr which is making the program crash later.

I read into the typeid handling and std::type_info comparison. It seems, that it is not safe to compare two std::type_infos across library borders. The issue could be, that T1 was gained at compile time of the main program and T2 was gained at compile time of the appropriate dynamic OpenUSD library. From what I understood the std::type_info is not only dependent on the type, but also on the compiler and the used compile settings. I checked the type names of both std::type_info and they are equal. The == operator returns false still. The names are equal but the hash is different, which hints, that they are seen as different types while comparing them.

So the big question is: Is it a valid approach at all to do hydra initialisation that way or do I need to create the Hgi and the driver indirect through a compatible dynlib? Do I need some specific compiler settings and compiler versions? Is it mandatory to compile the main program, which is using the OpenUSD libraries with the same relevant compiler switches and what switches are that exactly?

For now I am really stuck. I don’t want to debug through the disassembly of the type_info comparison.

I am using a MacBook 2 on arm architecture with clang compiler. I am compiling OpenUSD locally to be able to debug through it. I also got the problem with the default HGI (Vulkan disabled).

Any help would be appreciated :slight_smile:

Cheers,
Robert

This is possibly a case of this issue which I filed a couple of years ago. I note that the Hgi class is not marked with an _API macro, so would be problematic when placed in a VtValue.

Jerry

@Grimmigbeisser Could you add your message to the issue Jerry has linked please? I think Jerry’s right that it’s likely the same issue.

Hi guys,

thank you for pointing me to this issue! I already lost a day due to the investigations and I am happy that somebody already investigated deeper and found the real cause! I verified, that I am using -fvisibility=hidden. So it is exactly the same problem. I posted this also in the issue as @nporcino suggested.

Cheers,
Robert

1 Like