Michal Pokluda
Michal Pokluda

Reputation: 390

SharpDX compile shaders

How to compile vertex and pixel shaders at build time in SharpDX? The way you can read about in "Direct3D Rendering Cookbook" is to use HLSLCompiler.CompileFromFile. This will compile shaders at runtime, which is not always good.

Upvotes: 4

Views: 1823

Answers (2)

Michal Pokluda
Michal Pokluda

Reputation: 390

Well I found out, the above way is not that good for deployment. The problem is, content files are located outside of exe or dll, so I rather use them as "Embedded Resource" - this way the cso files are embedded inside assembly (dll or exe). To load the stream for embedded resources use:

protected SharpDX.D3DCompiler.ShaderBytecode LoadShaderFromManifestResourceFile(
            System.Reflection.Assembly assembly, string resourceName)
    {
        SharpDX.D3DCompiler.ShaderBytecode shaderBytecode = null;

        using (var shaderCodeReader = assembly.GetManifestResourceStream(resourceName))
        {
            shaderBytecode = ToDispose(ShaderBytecode.FromStream(shaderCodeReader));
        }

        return shaderBytecode;
    }

To get the resource path/identifier (it can be pretty long) you can use:

var assembly = Assembly.GetExecutingAssembly();
string[] resources = assembly.GetManifestResourceNames();

Upvotes: 3

Michal Pokluda
Michal Pokluda

Reputation: 390

In latest SharpDX 4 you can compile pixel and vertex shader at runtime, the problem is, most of the (not updated) Windows 7 don't have D3DCompiler_47.dll, which won't allow you to even run the SharpDX (SharpDX.D3DCompiler won't be available). It's better to use fxc from DirectX SDK to compile shaders at build time as follows:

ComplieShaders.bat (this bat file I have as a part of the project and I call it when building app):

Echo Building shaders
Echo Launch dir: "%~dp0"
Echo Current dir: "%CD%"
cd "%~dp0"
PATH="c:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Utilities\bin\x86\"
fxc /T vs_5_0 /E VSMain "Laser.hlsl" /Fo "MyVS.cso"
fxc /T ps_5_0 /E PSMain "Laser.hlsl" /Fo "MyPS.cso"

The strange cd "%~dp0" will move to correct directory. This bat file I call from Pre-build event command line (in C# project settings -> Build Events).

This will produce binary shader data as MyVS.cso (for vertex shader) and MyPS.cso (for pixel shader). These two files I again insert as Content to C# project.

Then you can use both files in C#:

    string shaderFile = @"SomeDirectoryInYourApp\Shaders\MyVS.cso";
    if (!Path.IsPathRooted(shaderFile))
    {
         shaderFile = Path.Combine(System.IO.Path.GetDirectoryName(
             System.Reflection.Assembly.GetEntryAssembly().Location),
        shaderFile);
    }

    using (var shaderCodeReader = new System.IO.StreamReader(shaderFile))
    {
        vertexShaderBytecode = ToDispose(ShaderBytecode.FromStream(
            shaderCodeReader.BaseStream));
    }

    vertexShader = ToDispose(new VertexShader(device, vertexShaderBytecode));

If you have problem finding your MyVS.cso file in your C# app, you can use assembly.GetManifestResourceNames() to get list of all available Content files in assembly (with complete path).

Upvotes: 2

Related Questions