locked
Load compiled shader with plain C++

    Question

  • Is this possible to load .cso file without using <wrl.h> and "d3dcompiler*.dll"?

    Something like:

    ifstream ifs("filename.cso");  
    ifs.seekg( 0, ios::end );  
    size_t size = ifs.tellg();  
    char* buf = new char[size];
    ifs.seekg(0, ios::beg);  
    ifs.read( &data[0], size);  
    ifs.close();
    if(FAILED(CreateVertexShader(buf, size, 0, &m_pVertexShader)))
       return 0;
    delete[]  buf; 

    tells invalid arg.

    Does binary needs some preprocessing before passing to "Create*Shader" functions?

    Thanks!

    Thursday, October 25, 2012 4:47 PM

Answers

  • Once you have the compiled shader binary, you are free to package that data in whatever form you want.

    It is important you load that data as BINARY and not as ASCII or you will corrupt the shader blob, which is likely what's happening here. Try:

    ifstream ifs("filename.cso", ifstream::in | ifstream::binary );  

    Also, you should really look into learning how to use the RAII pattern to make your code exception-safe which is an important habit in Windows Store app development. ifstream is already exception-safe for the file handle, but you should use std::unique_ptr for the heap memory allocation:

    #include <memory> // for std::unique_ptr
    #include <stdint.h> // for uint8_t
    
    ifstream ifs("filename.cso");  
    ifs.seekg( 0, ios::end );  
    size_t size = ifs.tellg(); 
    std::unique_ptr<uint8_t*> buf( new uint8_t[size] );
    ifs.seekg(0, ios::beg);  
    ifs.read( buf.get(), size);  
    ifs.close();
    if(FAILED(CreateVertexShader(buf.get(), size, 0, &m_pVertexShader)))
       return 0;
    
    You might want to read the Exception-Safe-Coding section of this blog post.


    Thursday, October 25, 2012 5:39 PM

All replies

  • Once you have the compiled shader binary, you are free to package that data in whatever form you want.

    It is important you load that data as BINARY and not as ASCII or you will corrupt the shader blob, which is likely what's happening here. Try:

    ifstream ifs("filename.cso", ifstream::in | ifstream::binary );  

    Also, you should really look into learning how to use the RAII pattern to make your code exception-safe which is an important habit in Windows Store app development. ifstream is already exception-safe for the file handle, but you should use std::unique_ptr for the heap memory allocation:

    #include <memory> // for std::unique_ptr
    #include <stdint.h> // for uint8_t
    
    ifstream ifs("filename.cso");  
    ifs.seekg( 0, ios::end );  
    size_t size = ifs.tellg(); 
    std::unique_ptr<uint8_t*> buf( new uint8_t[size] );
    ifs.seekg(0, ios::beg);  
    ifs.read( buf.get(), size);  
    ifs.close();
    if(FAILED(CreateVertexShader(buf.get(), size, 0, &m_pVertexShader)))
       return 0;
    
    You might want to read the Exception-Safe-Coding section of this blog post.


    Thursday, October 25, 2012 5:39 PM
  • Thanks for reply, Chuck!

    In my first message it was just simplified code. In my main app I'm using std::vector<char> as data array here. Then resize, read, etc. Its pretty okay?

    Fixed now! My bad was not to pass binary flag.

    Thanks again Chuck! You are my hero!

    By the way, are there any references about *.cso binary structure? Any news about alternative reflection interface? Looks like shader constants buffers' data members are in open view in hex-editor.


    • Edited by mickeytm Thursday, October 25, 2012 10:16 PM
    Thursday, October 25, 2012 10:07 PM
  • std::vector is exception-safe if that's the model you want to use.

    The shader reflection support for Windows Store apps is something we are looking into. No news as of yet.

    Wednesday, October 31, 2012 6:43 PM