locked
Trouble Loading a Shader File

    Question

  • My C#/XAML game includes a C++ DLL to apply a pixel shader effect to game pieces. The C++ project includes shader source files (.hlsl) which VS successfully compiles into .cso shader files. However, my attempt to load a .cso file in C++ is not working:

        CREATEFILE2_EXTENDED_PARAMETERS extendedParams = {0};
        extendedParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
        extendedParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
        extendedParams.dwFileFlags = FILE_FLAG_SEQUENTIAL_SCAN;
        extendedParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
        extendedParams.lpSecurityAttributes = nullptr;
        extendedParams.hTemplateFile = nullptr;
     
        Wrappers::FileHandle file(
            CreateFile2(
                "MyShaderFile.cso",
                GENERIC_READ,
                FILE_SHARE_READ,
                OPEN_EXISTING,
                &extendedParams
                )
            );

    I am assuming VS automatically includes my .cso files as resources in the DLL. If this is wrong, how do I get VS to include the .cso files as DLL resources?

    I suspect the real problem is that I specify "MyShaderFile.cso" as the shader file rather than providing a complete path. Can someone tell me what the proper path is for a file resource residing in a DLL?

    Or, is there something else wrong in the code above?

    Tuesday, September 04, 2012 4:36 PM

Answers

  • For Windows Store apps, you are generally putting 'resources' like .cso files into the AppX package rather than bundling them inside a DLL or a .resx file. You can organize it however you want because in the end a compiled HLSL shader is just a chunk of bytes.
    • Marked as answer by Bob Flora Thursday, September 06, 2012 9:41 PM
    Wednesday, September 05, 2012 5:13 PM

All replies

  • I should have stated... The call to CreateFileHandle2 is returning INVALID_HANDLE_VALUE.
    Tuesday, September 04, 2012 5:26 PM
  • If CreateFile2 failed, it's only a filesystem issue. Check GetLastError.


    C++ DX11

    Wednesday, September 05, 2012 3:10 AM
  • If CreateFile2 failed, it's only a filesystem issue. Check GetLastError.


    C++ DX11

    GetLastError returns ERROR_FILE_NOT_FOUND, which is what I expected.

    I tried adding the .cso file as a resource file to the C++ project since I don't know whether VS is already doing this in some way. But CreateFile2 still can't find it, probably because I just don't know the proper path to the file. Sigh.

    Well, I know how to load resource files from the C# side, so I'll just load the .cso file from there. Then I should be able to pass the bytes to the C++ side. Not pretty, but I need a solution.

    Wednesday, September 05, 2012 2:28 PM
  • For Windows Store apps, you are generally putting 'resources' like .cso files into the AppX package rather than bundling them inside a DLL or a .resx file. You can organize it however you want because in the end a compiled HLSL shader is just a chunk of bytes.
    • Marked as answer by Bob Flora Thursday, September 06, 2012 9:41 PM
    Wednesday, September 05, 2012 5:13 PM
  • Here's what I do:

    static wchar_t wzInstallDirectory[MAX_PATH];
    
    //-------------------------
    // Call at app startup
    
    void InitializeDirs()
     {
      wcscpy_s( wzInstallDirectory, MAX_PATH, Package::Current->InstalledLocation->Path->Data() );
      wcscat_s( wzInstallDirectory, MAX_PATH, L"\\" );
     }
    
    
    //-------------------------
    // Call anytime later
    
    FILE *OpenInstalledFile( wchar_t *wzFilePart )
     {
      FILE    *fp;
      wchar_t wzFile[MAX_PATH];
    
      wcscpy_s( wzFile, MAX_PATH, wzInstallDirectory );
      wcscat_s( wzFile, MAX_PATH, wzFilePart );
    
      fp = 0;
      _wfopen_s( &fp, wzFile, L"rb" );
    
      return fp;
     }
    
    

    It may not be right but it works and lets me use the regular C++ libraries for IO.

    Wednesday, September 05, 2012 6:49 PM
  • The ResourceLoading sample shows how to manage all your loading using async WinRT APIs which is more efficient for large amounts of data.
    Thursday, September 06, 2012 8:51 PM
  • For Windows Store apps, you are generally putting 'resources' like .cso files into the AppX package rather than bundling them inside a DLL or a .resx file. You can organize it however you want because in the end a compiled HLSL shader is just a chunk of bytes.

    Thanks, Chuck. Your mention of the AppX package led me to the answer. I haven't paid attention to how packaging works since I still have a lot of development to do. But now I understand (I think) that the AppX folder contains everything that will be part of the deployed app package. My .cso files are indeed being added to the C++ DLL project subfolder under AppX by VS (i.e., I don't have to manually add the .cso files as resource files). As a result, I can now see the proper path for accessing the .cso files, and everything works great now. Thanks again.
    Thursday, September 06, 2012 9:41 PM

  • Thanks, Henador. My main concern about using _wfopen_s is that I'm not sure if it would pass app store certification. If I understand correctly, C++ file I/O routines won't pass certification, so you have to be careful to use an approved means of loading files.
    Thursday, September 06, 2012 9:48 PM

  • Thanks, Henador. My main concern about using _wfopen_s is that I'm not sure if it would pass app store certification. If I understand correctly, C++ file I/O routines won't pass certification, so you have to be careful to use an approved means of loading files.

    I just checked my Metro app (which uses the C++ file io calls) with the RTM VS2012 Windows App Cert kit and it passed with no issues. One of the tests is a "Supported API Test" so I have to assume that wfopen_s is a valid call to make (I assume it uses the approved WinRT APIs internally).

    Does a PASS in the Windows App Cert Kit mean that your program itself will be approved by the AppStore? I know there are many reasons why the whole submission may be rejected (privacy policy, etc.). I'm just concerned about the code itself.

    Friday, September 07, 2012 1:08 AM
  • fopen is available for app (appx & localdata) , http://msdn.microsoft.com/en-us/library/jj606124.aspx 

    That can be used for cross-platform code.

    Or use CreateFile2 directly.


    C++ DX11

    Friday, September 07, 2012 2:56 AM
  • fopen is available for app (appx & localdata) , http://msdn.microsoft.com/en-us/library/jj606124.aspx 

    That can be used for cross-platform code.

    Or use CreateFile2 directly.


    C++ DX11

    Thanks for the link, RaptorK.
    Friday, September 07, 2012 3:55 AM
  • Note that fopen is the insecure version. You should use fopen_s instead.

    You can also make Win32 code that compiles for both Windows Store apps and 'downlevel' desktop platforms by using _WIN32_WINNT

     #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8 /*0x0602*/)
         CreateFile2(...)
     #else
         CreateFile(...)
     #endif

    Monday, September 10, 2012 6:58 PM