sharpdx / SharpDX

SharpDX GitHub Repository
http://sharpdx.org
MIT License
1.68k stars 643 forks source link

D3D_COMPILE_STANDARD_FILE_INCLUDE missing #1083

Open AnyOldName3 opened 5 years ago

AnyOldName3 commented 5 years ago

In regular DirectX, a shader can be compiled with the pInclude parameter set to D3D_COMPILE_STANDARD_FILE_INCLUDE to use a default include handler. This macro isn't available in SharpDX, and as far as I can find, there isn't an equivalent constant which can be passed instead.

mrvux commented 5 years ago

This is a funny one indeed, the land of Microsoft passing magic pointer numbers :)

The issue is that we somehow need to pass 1 as a native pointer, but of course our include is an interface. I'm not certain what is the most grateful way to solve that, but in the mean time, there's a trick (just tried it, and it's perfectly working, create a dummy implementation of Include, that also inherits from CppObject

    public class StandardIncludeHandler : CppObject, Include
    {
    public StandardIncludeHandler() : base(new IntPtr(1)) { }

    public void Close(Stream stream) { }

    public Stream Open(IncludeType type, string fileName, Stream parentStream) { throw new NotImplementedException(); }
}

The main reason to inherit from CppObject (and why it does not work otherwise), is that internally when you pass an Include to D3DCompile, sharpdx will check if you provide a native version (eg : by bein g a cpp object), in that case, it directly returns the magic pointer instead of creating a "Shadow interface". So technically close and open in that case willl never be called .

Using that "dummy handler" in the call like :
SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile(path, "VS", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.OptimizationLevel0, SharpDX.D3DCompiler.EffectFlags.None, null, new StandardIncludeHandler()); Works as expected.

PS : It's not the most elegant way to solve, but I guess that class could be added as PR in sharpdx as it is? @xoofx ?