public void LinkLibrary() { var testShader = @" // This file defines the defaults for the editor. // This is the default code in the fixed header section. // @@@ Begin Header Texture2D<float3> Texture : register(t0); SamplerState Anisotropic : register(s0); cbuffer CameraData : register(b0) { float4x4 Model; float4x4 View; float4x4 Projection; }; cbuffer TimeVariantSignals : register(b1) { float SineWave; float SquareWave; float TriangleWave; float SawtoothWave; }; // @@@ End Header // This is the default code in the source section. // @@@ Begin Source export void VertexFunction( inout float4 position, inout float2 texcoord, inout float4 normal) { position = mul(position, Model); position = mul(position, View); position = mul(position, Projection); normal = mul(normal, Model); } export float3 ColorFunction(float2 texcoord, float3 normal) { return Texture.Sample(Anisotropic, texcoord); } // @@@ End Source // This code is not displayed, but is used as part of the linking process. // @@@ Begin Hidden cbuffer HiddenBuffer : register(b2) { float3 LightDirection; }; export float3 AddLighting(float3 color, float3 normal) { static const float ambient = 0.2f; float brightness = ambient + (1.0f - ambient) * saturate(dot(normal, LightDirection)); return color * brightness; } export float3 AddDepthFog(float3 color, float depth) { float3 fogColor = float3(0.4f, 0.9f, 0.5f); // Greenish. return lerp(color, fogColor, exp2(-depth)); } export float3 AddGrayscale(float3 color) { float luminance = 0.2126f * color.r + 0.7152f * color.g + 0.0722f * color.b; return float3(luminance, luminance, luminance); } export float4 Float3ToFloat4SetW1(float3 value) { // Convert a float3 value to a float4 value with the w component set to 1.0f. // Used for initializing homogeneous 3D coordinates and generating fully opaque color values. return float4(value, 1.0f); } // @@@ End Hidden "; //1. Compiling your shader code var compilationResult = ShaderBytecode.Compile(testShader, "lib_5_0", ShaderFlags.OptimizationLevel3, EffectFlags.None); var bytecode = compilationResult.Bytecode; // 2.Load the compiled code into a shader library var shaderLibrary = new Module(bytecode); //3. Bind resources from source slots to destination slots var shaderLibraryInstance = new ModuleInstance("", shaderLibrary); shaderLibraryInstance.BindResource(0, 0, 1); shaderLibraryInstance.BindSampler(0, 0, 1); shaderLibraryInstance.BindConstantBuffer(0, 0, 0); shaderLibraryInstance.BindConstantBuffer(1, 1, 0); shaderLibraryInstance.BindConstantBuffer(2, 2, 0); //1. Construct a function-linking-graph for the vertex shader. var vertexShaderGraph = new FunctionLinkingGraph(); var vertexShaderInputNode = vertexShaderGraph.SetInputSignature( ParamDesc("inputPos", "POSITION0", ShaderVariableType.Float, ShaderVariableClass.Vector, 1, 3, SharpDX.Direct3D.InterpolationMode.Linear, ParameterFlags.In, 0, 0, 0, 0), ParamDesc("inputTex", "TEXCOORD0", ShaderVariableType.Float, ShaderVariableClass.Vector, 1, 2, SharpDX.Direct3D.InterpolationMode.Linear, ParameterFlags.In, 0, 0, 0, 0), ParamDesc("inputNorm", "NORMAL0", ShaderVariableType.Float, ShaderVariableClass.Vector, 1, 3, SharpDX.Direct3D.InterpolationMode.Linear, ParameterFlags.In, 0, 0, 0, 0)); var homogenizeCallNodeForPos = vertexShaderGraph.CallFunction("", shaderLibrary, "Float3ToFloat4SetW1"); var homogenizeCallNodeForNorm = vertexShaderGraph.CallFunction("", shaderLibrary, "Float3ToFloat4SetW1"); vertexShaderGraph.PassValue(vertexShaderInputNode, 0, homogenizeCallNodeForPos, 0); vertexShaderGraph.PassValue(vertexShaderInputNode, 2, homogenizeCallNodeForNorm, 0); var vertexFunctionCallNode = vertexShaderGraph.CallFunction("", shaderLibrary, "VertexFunction"); vertexShaderGraph.PassValue(homogenizeCallNodeForPos, -1, vertexFunctionCallNode, 0); vertexShaderGraph.PassValue(vertexShaderInputNode, 1, vertexFunctionCallNode, 1); vertexShaderGraph.PassValue(homogenizeCallNodeForNorm, -1, vertexFunctionCallNode, 2); var vertexShaderOutputNode = vertexShaderGraph.SetOutputSignature( ParamDesc("outputTex", "TEXCOORD0", ShaderVariableType.Float, ShaderVariableClass.Vector, 1, 2, SharpDX.Direct3D.InterpolationMode.Undefined, ParameterFlags.Out, 0, 0, 0, 0), ParamDesc("outputNorm", "NORMAL0", ShaderVariableType.Float, ShaderVariableClass.Vector, 1, 3, SharpDX.Direct3D.InterpolationMode.Undefined, ParameterFlags.Out, 0, 0, 0, 0), ParamDesc("outputPos", "SV_POSITION", ShaderVariableType.Float, ShaderVariableClass.Vector, 1, 4, SharpDX.Direct3D.InterpolationMode.Undefined, ParameterFlags.Out, 0, 0, 0, 0)); vertexShaderGraph.PassValue(vertexFunctionCallNode, 0, vertexShaderOutputNode, 2); vertexShaderGraph.PassValue(vertexFunctionCallNode, 1, vertexShaderOutputNode, 0); vertexShaderGraph.PassValue(vertexFunctionCallNode, 2, vertexShaderOutputNode, 1); var vertexShaderGraphInstance = vertexShaderGraph.CreateModuleInstance(); // 2. Link the vertex shader var vertexLinker = new Linker(); vertexLinker.UseLibrary(shaderLibraryInstance); var vertexShaderBlob = vertexLinker.Link(vertexShaderGraphInstance, "main", "vs_5_0", 0); Directory.CreateDirectory($"{OutputDir}"); File.WriteAllBytes($"{OutputDir}/TestLinkedVertexShader.o", vertexShaderBlob.Data); File.WriteAllText($"{OutputDir}/TestLinkedVertexShader.asm", vertexShaderBlob.Disassemble()); File.WriteAllText($"{OutputDir}/TestLinkedVertexShader.hlsl", vertexShaderGraph.GenerateHlsl(0)); var vertexContainer = new BytecodeContainer(vertexShaderBlob.Data); File.WriteAllText($"{OutputDir}/TestLinkedVertexShader.d.asm", vertexContainer.ToString()); bool enableLighting = true; bool enableDepthFog = true; bool enableGreyScale = true; //1. Construct a function-linking-graph for the vertex shader. var pixelShaderGraph = new FunctionLinkingGraph(); var pixelShaderInputNode = pixelShaderGraph.SetInputSignature( ParamDesc("inputTex", "TEXCOORD0", ShaderVariableType.Float, ShaderVariableClass.Vector, 1, 2, SharpDX.Direct3D.InterpolationMode.Undefined, ParameterFlags.In, 0, 0, 0, 0), ParamDesc("inputNorm", "NORMAL0", ShaderVariableType.Float, ShaderVariableClass.Vector, 1, 3, SharpDX.Direct3D.InterpolationMode.Undefined, ParameterFlags.In, 0, 0, 0, 0), ParamDesc("inputPos", "SV_POSITION", ShaderVariableType.Float, ShaderVariableClass.Vector, 1, 4, SharpDX.Direct3D.InterpolationMode.Undefined, ParameterFlags.In, 0, 0, 0, 0)); var colorValueNode = pixelShaderGraph.CallFunction("", shaderLibrary, "ColorFunction"); pixelShaderGraph.PassValue(pixelShaderInputNode, 0, colorValueNode, 0); pixelShaderGraph.PassValue(pixelShaderInputNode, 1, colorValueNode, 1); if (enableLighting) { var tempNode = pixelShaderGraph.CallFunction("", shaderLibrary, "AddLighting"); pixelShaderGraph.PassValue(colorValueNode, -1, tempNode, 0); pixelShaderGraph.PassValue(pixelShaderInputNode, 1, tempNode, 1); colorValueNode = tempNode; } if (enableDepthFog) { var tempNode = pixelShaderGraph.CallFunction("", shaderLibrary, "AddDepthFog"); pixelShaderGraph.PassValue(colorValueNode, -1, tempNode, 0); pixelShaderGraph.PassValueWithSwizzle(pixelShaderInputNode, 2, "z", tempNode, 1, "x"); colorValueNode = tempNode; } if (enableGreyScale) { var tempNode = pixelShaderGraph.CallFunction("", shaderLibrary, "AddGrayscale"); pixelShaderGraph.PassValue(colorValueNode, -1, tempNode, 0); colorValueNode = tempNode; } var fillAlphaCallNode = pixelShaderGraph.CallFunction("", shaderLibrary, "Float3ToFloat4SetW1"); pixelShaderGraph.PassValue(colorValueNode, -1, fillAlphaCallNode, 0); var pixelShaderOutputNode = pixelShaderGraph.SetOutputSignature( ParamDesc("outputColor", "SV_TARGET", ShaderVariableType.Float, ShaderVariableClass.Vector, 1, 4, SharpDX.Direct3D.InterpolationMode.Undefined, ParameterFlags.Out, 0, 0, 0, 0)); pixelShaderGraph.PassValue(fillAlphaCallNode, -1, pixelShaderOutputNode, 0); var pixelShaderGraphInstance = pixelShaderGraph.CreateModuleInstance(); // 2. Link the vertex shader var pixelLinker = new Linker(); pixelLinker.UseLibrary(shaderLibraryInstance); var pixelShaderBlob = pixelLinker.Link(pixelShaderGraphInstance, "main", "ps_5_0", 5); Directory.CreateDirectory($"{OutputDir}"); File.WriteAllBytes($"{OutputDir}/TestLinkedPixelShader.o", pixelShaderBlob.Data); File.WriteAllText($"{OutputDir}/TestLinkedPixelShader.asm", pixelShaderBlob.Disassemble()); File.WriteAllText($"{OutputDir}/TestLinkedPixelShader.hlsl", pixelShaderGraph.GenerateHlsl(0)); var pixelContainer = new BytecodeContainer(pixelShaderBlob.Data); File.WriteAllText($"{OutputDir}/TestLinkedPixelShader.d.asm", pixelContainer.ToString()); }