sensics / OSVR-RenderManager

Apache License 2.0
64 stars 45 forks source link

Precompiled Binaries don't work with Windows 8.1 anymore #162

Closed Findus79 closed 8 years ago

Findus79 commented 8 years ago

Seem to be linked against Windows 8.1. Calls CreateDXGIFactory2, not available on Windows 7. Renders RenderManager unusable with Windows 7.

rpavlik commented 8 years ago

So this call only exists in my full source tree in the "Intel" (DXGI2) backend, which only works on Windows 10 1511 and newer anyway. We should presumably delay-load that symbol (whether manually or automatically), and make sure to have the manifests set right and guard that code so it only gets run when it can actually succeed.

I'm assuming you looked at symbol imports with a tool of some sort - did you use one that shows compatibility automatically or did you have to look up symbols manually? FileAlyzer2 had a nice symbol availability feature but it hasn't been updated in forever so it's missing data for modern Windows versions. If there's an automated tool available we could make it part of the build system and CI so that builds fail if we accidentally break Windows 7.

Findus79 commented 8 years ago

Hi

that explains why I couldn't find in the sources :) I just took the error message and checked against MSDN to see which Windows version is required to use it. For symbol lookup I usually use DependencyWalker, but that didn't help me a lot in this case. Can you tell me when there will be a RenderManager version available again to use with Windows 7?

Stormwind99 commented 8 years ago

Just fyi, this bug blocks our release of OSVR support in Descent: Underground (HDK2 bundle title) since Windows 7 64-bit is in our min spec and we have customers already using it (and OSVR-Unreal usage of osvrRenderManager.dll causes UE4 to error on startup when OSVR-Unreal plugin included).

The other VR API UE4 plugins (all enabled since we support all VR APIs with same binary) do not have this issue.

Stormwind99 commented 8 years ago

I think I found an example of delay loading the symbol (well, CreateDXGIFactory1 rather than CreateDXGIFactory2) and checking at runtime in the UE4 source code.

(UE4 is not open-source but is publicly-available source, so we can't copy-and-paste this code - just usable as a reference/example.)

/** This function is used as a SEH filter to catch only delay load exceptions. */
static bool IsDelayLoadException(PEXCEPTION_POINTERS ExceptionPointers)
{
#if WINVER > 0x502  // Windows SDK 7.1 doesn't define VcppException
    switch(ExceptionPointers->ExceptionRecord->ExceptionCode)
    {
    case VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND):
    case VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND):
        return EXCEPTION_EXECUTE_HANDLER;
    default:
        return EXCEPTION_CONTINUE_SEARCH;
    }
#else
    return EXCEPTION_EXECUTE_HANDLER;
#endif
}

// We suppress warning C6322: Empty _except block. Appropriate checks are made upon returning. 
#if USING_CODE_ANALYSIS
    MSVC_PRAGMA(warning(push))
    MSVC_PRAGMA(warning(disable:6322))
#endif  // USING_CODE_ANALYSIS
/**
 * Since CreateDXGIFactory1 is a delay loaded import from the D3D11 DLL, if the user
 * doesn't have VistaSP2/DX10, calling CreateDXGIFactory1 will throw an exception.
 * We use SEH to detect that case and fail gracefully.
 */
static void SafeCreateDXGIFactory(IDXGIFactory1** DXGIFactory1)
{
#if !D3D11_CUSTOM_VIEWPORT_CONSTRUCTOR
    __try
    {
        CreateDXGIFactory1(__uuidof(IDXGIFactory1),(void**)DXGIFactory1);
    }
    __except(IsDelayLoadException(GetExceptionInformation()))
    {
    }
#endif  //!D3D11_CUSTOM_VIEWPORT_CONSTRUCTOR
}

// Re-enable C6322
#if USING_CODE_ANALYSIS
    MSVC_PRAGMA(warning(pop)) 
#endif // USING_CODE_ANALYSIS
Stormwind99 commented 8 years ago

In addition, I believe we'll need /DELAYLOAD:dxgi or similar as a link parameter.

https://msdn.microsoft.com/en-us/library/yx9zd12s.aspx

Stormwind99 commented 8 years ago

Another delay load example: http://www.gamedev.net/topic/552391-having-support-for-dx9--dx10--dx11/

Stormwind99 commented 8 years ago

@rpavlik - what component of the source tree contains the "Intel" (DXGI2) backend where CreateDXGIFactory2() is called? I can't find it.

Findus79 commented 8 years ago

As far as I understood, it's inside the Intel NDA code part.

Stormwind99 commented 8 years ago

Unless someone with access to the Intel NDA code can make the change, can we delay-load the entire Intel DLL (assuming the Intel NDA code compiles to a DLL) containing the call to CreateDXGIFactory2?

russell-taylor commented 8 years ago

The source code for this is indeed in the RenderManager-Intel NDA code repository. The person who handles that repository (me) is traveling on vacation this week -- the lazy bum! Thanks for the pointers to the delay-load example code, it should make it easier to fix this next week when I'm back. Let me know if it is useful to have a 64-bit RenderManager build without the Intel DirectMode until this issue is resolved.

Stormwind99 commented 8 years ago

@russell-taylor - Thanks! If it is easy to do, yeah, a build with osvrRenderManager.dll not including the Intel DirectMode code (and thus no CreateDXGIFactory2 call) would help.

rpavlik commented 8 years ago

the Intel code doesn't build to a DLL, it builds into the single rendermanager DLL. The rest of us who aren't on vacation are also aware of this issue (and many others on our plates) - there is a much simpler way than that to just try loading the symbol from dxgi.dll. (Delay-loading that dll won't solve the problem because we need dxgi.dll for other things - it's just that the version of dxgi.dll in older versions of Windows doesn't have that symbol defined in it. I believe the call is LoadSymbol: for a single call, that seems like a better solution than introducing an SEH handler, etc...)

russell-taylor commented 8 years ago

Okay, there is a RenderManager installer at https://drive.google.com/file/d/0B7VlD2Ofd7vRME00d3RvTG1iNzQ/view?usp=sharing that includes a DLL built against the current master source from OSVR-Core and OSVR-RenderManager, but without the Intel subproject. Hopefully this will work for you until we get the DLL issue resolved.

russell-taylor commented 8 years ago

Fixed and tested in commit 3d557e453a79962aedf36c3b2f31d82a3b5042aa (ran on Windows 7, still opens DirectMode on Windows 10 Intel cards). The next CI autobuild should include this fix.

truegeorg commented 6 years ago

Link nor work