Advertisement
xoofx

C# HLSL Binary FX File loader

Jan 5th, 2012
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 89.13 KB | None | 0 0
  1. // This is an extract of a HLSL fx binary file loader in C# developed in an unreleased internal project in SharpDX
  2. // The principle is to use this loader to discover annotations/techniques/passes/vertex|pixel shader bytecodes, blend|rasterizer|depth states and D3D11 reflection for variable binding in constant buffers.
  3.  
  4. // Copyright (c) 2010 SharpDX - Alexandre Mutel
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23.  
  24. using System;
  25. using System.Collections.Generic;
  26. using System.Diagnostics;
  27. using System.IO;
  28. using System.Runtime.InteropServices;
  29. using SharpDX.D3DCompiler;
  30.  
  31. namespace SharpDX.Framework.Graphics
  32. {
  33.     /// <summary>
  34.     /// Effect provider for HLSL EffectsHLSLFx.
  35.     ///
  36.     /// Doc StreamOutputDeclaration : http://msdn.microsoft.com/en-us/library/ff476168%28v=VS.85%29.aspx
  37.     /// </summary>
  38.     public class EffectsHLSLFx : IEffectCompiler, IEffectCompilerFactory
  39.     {
  40.         private BinaryHeader _binaryHeader;
  41.         private BinaryHeader11 _binaryHeader11;
  42.         private IntPtr _currentPtr;
  43.         private IntPtr _unStructuredDataBlock;
  44.         private CConstantBuffer[] _binaryConstantBuffers;
  45.         private CObjectVariable[] _objectVariables;
  46.         private CInterfaceVariable[] _interfaceVariables;
  47.         private CFxGroup[] _fxGroups;
  48.  
  49.         /// <summary>
  50.         /// Instantiate a new effect compiler from this factory.
  51.         /// </summary>
  52.         /// <returns>an effect compiler</returns>
  53.         public IEffectCompiler NewCompiler()
  54.         {
  55.             return new EffectsHLSLFx();
  56.         }
  57.  
  58.         /// <summary>
  59.         /// Compiles the specified Effect source code.
  60.         /// </summary>
  61.         /// <param name="source">The Effect source code.</param>
  62.         /// <param name="compilerOptions">The compiler options.</param>
  63.         /// <returns></returns>
  64.         EffectBytecode IEffectCompiler.Compile(string source, EffectCompilerOptions compilerOptions)
  65.         {
  66.             var bytecode = ShaderBytecode.Compile(source, "fx_5_0", (ShaderFlags)compilerOptions, EffectFlags.None);
  67.             return new EffectsHLSLFxBytecode(bytecode);
  68.         }
  69.  
  70.         /// <summary>
  71.         /// Reads the specified bytecode from the stream.
  72.         /// </summary>
  73.         /// <param name="bytecodeStream">The bytecode stream.</param>
  74.         /// <returns>an instance of EffectBytecode if this compiler was able to read the bytecode, null otherwise</returns>
  75.         EffectBytecode IEffectCompiler.Read(Stream bytecodeStream)
  76.         {
  77.             var reader = new BinaryReader(bytecodeStream);
  78.             int version = reader.ReadInt32();
  79.             if (Enum.IsDefined(typeof(VersionTag), version))
  80.             {
  81.                 bytecodeStream.Position = 0;
  82.                 var bytecode = ShaderBytecode.FromStream(bytecodeStream);
  83.                 if (bytecode != null)
  84.                     return new EffectsHLSLFxBytecode(bytecode);
  85.             }
  86.             return null;
  87.         }
  88.  
  89.         /// <summary>
  90.         /// Loads the specified effect from bytecode.
  91.         /// </summary>
  92.         /// <param name="bytecode">The compiled bytecode for an effect.</param>
  93.         /// <param name="toEffect">The effect to be filled-in by this provider.</param>
  94.         /// <returns>
  95.         ///     <c>true</c> if this Effect Provider was able to load this bytecode otherwise, <c>false</c>.
  96.         /// </returns>
  97.         bool IEffectCompiler.Load(EffectBytecode bytecode, Effect toEffect)
  98.         {
  99.             IntPtr buffer = bytecode.DataPointer;
  100.             _currentPtr = buffer;
  101.  
  102.             // Bytecode should be EffectsHLSLFx
  103.             if (!(bytecode is EffectsHLSLFxBytecode))
  104.                 return false;
  105.             if (toEffect.Bytecode != null)
  106.                 return false;
  107.  
  108.             // Just make sure that the bytecode buffer is enough large, otherwise, return false
  109.             if (buffer == IntPtr.Zero || bytecode.Length < 4)
  110.                 return false;
  111.  
  112.  
  113.             // Check version of this effect bytecode
  114.             var tag = (VersionTag) Marshal.ReadInt32(buffer);
  115.             if (tag == VersionTag.Fx50)
  116.             {
  117.                 _binaryHeader11 = Read<BinaryHeader11>();
  118.                 _binaryHeader = _binaryHeader11.Header;
  119.             }
  120.             else if (tag == VersionTag.Fx40 || tag == VersionTag.Fx41)
  121.             {
  122.                 _binaryHeader = Read<BinaryHeader>();
  123.             }
  124.             else
  125.             {
  126.                 // The fileformat is not recognized
  127.                 return false;
  128.             }
  129.  
  130.             // Set the bytecode to the effect
  131.             toEffect.Bytecode = bytecode;
  132.             bytecode.Position = 0;
  133.  
  134.             // Effect file format structures /////////////////////////////////////////////
  135.             // File format:
  136.             //   File Header (BinaryHeader Header)
  137.             //   Unstructured data block (BYTE[Header.cbUnstructured))
  138.             //   Structured data block
  139.             //     ConstantBuffer (BinaryContantBuffer CB) * Header.Effect.ConstantBufferCount
  140.             //       uint  NumAnnotations
  141.             //       Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  142.             //       Variable data (BinaryNumericVariable Var) * (CB.VariableCount)
  143.             //         uint  NumAnnotations
  144.             //         Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  145.             //     Object variables (BinaryObjectVariable Var) * (Header.ObjectVariableCount) *this structure is variable sized
  146.             //       uint  NumAnnotations
  147.             //       Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  148.             //     Interface variables (BinaryInterfaceVariable Var) * (Header.InterfaceVariableCount) *this structure is variable sized
  149.             //       uint  NumAnnotations
  150.             //       Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  151.             //     Groups (BinaryGroup Group) * Header.GroupCount
  152.             //       uint  NumAnnotations
  153.             //       Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  154.             //       Techniques (BinaryTechnique Technique) * Group.TechniqueCount
  155.             //         uint  NumAnnotations
  156.             //         Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  157.             //         Pass (BinaryPass Pass) * Technique.PassCount
  158.             //           uint  NumAnnotations
  159.             //           Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  160.             //           Pass assignments (BinaryAssignment) * Pass.AssignmentCount
  161.  
  162.             _unStructuredDataBlock = _currentPtr;
  163.             _currentPtr += (int)_binaryHeader11.Header.cbUnstructured;
  164.  
  165.             // Load binary data from fx bytecode
  166.             LoadContantBuffers();
  167.             LoadObjectVariables();
  168.             LoadInterfaceVariables();
  169.             LoadFxGroups();
  170.  
  171.             // Transform binary data to effect object model.
  172.             Fill(toEffect);
  173.             return true;
  174.         }
  175.  
  176.         private void Fill(Effect effect)
  177.         {
  178.             FillGroups(effect);
  179.  
  180.             effect.Init();
  181.            
  182.             PostFillInformationForParameters(effect);
  183.         }
  184.  
  185.         private static void FillAnnotations(CAnnotation[] fromAnnotations, EffectAnnotationCollection toAnnotationCollection)
  186.         {
  187.             foreach (var fromAnnotation in fromAnnotations)
  188.                 toAnnotationCollection.Add(new EffectAnnotation(fromAnnotation.Name) {Value = fromAnnotation.Value});
  189.         }
  190.  
  191.         /// <summary>
  192.         /// Postfill annotations and semantic for parameters.
  193.         /// </summary>
  194.         /// <param name="effect">The effect.</param>
  195.         private void PostFillInformationForParameters(Effect effect)
  196.         {
  197.             // Fill annotation for paramaters
  198.             // TODO handle annotation for structure members
  199.             foreach (var rawConstantBuffer in _binaryConstantBuffers)
  200.             {
  201.                 var constantBuffer = effect.ParameterBuffers[rawConstantBuffer.Name];
  202.                 FillAnnotations(rawConstantBuffer.Annotations, constantBuffer.Annotations);
  203.  
  204.                 foreach (var rawNumericVariable in rawConstantBuffer.Variables)
  205.                 {
  206.                     var parameter = constantBuffer.Parameters[rawNumericVariable.Name];
  207.                     if (parameter != null)
  208.                     {
  209.                         FillAnnotations(rawNumericVariable.Annotations, parameter.Annotations);
  210.                         parameter.Semantic = rawNumericVariable.Semantic;
  211.                     }
  212.                 }
  213.             }
  214.  
  215.             // Fill annotation for all object variables
  216.             foreach (var rawObjectVariable in _objectVariables)
  217.             {
  218.                 var objectVariable = effect.Parameters[rawObjectVariable.Name];
  219.                 if (objectVariable != null)
  220.                 {
  221.                     FillAnnotations(rawObjectVariable.Annotations, objectVariable.Annotations);
  222.                     objectVariable.Semantic = rawObjectVariable.Semantic;
  223.                 }
  224.             }
  225.         }
  226.  
  227.         private void FillGroups(Effect effect)
  228.         {
  229.             // Add object variable (SamplerState) that are instantiated by the fx file
  230.             foreach (var rawObjectVariable in _objectVariables)
  231.             {
  232.                 if (rawObjectVariable.GraphicsResource != null)
  233.                 {
  234.                     var parameter = new EffectParameter(rawObjectVariable.Name)
  235.                                         {
  236.                                             ParameterClass = EffectParameterClass.Object,
  237.                                             ParameterType = rawObjectVariable.GraphicsResourceType,
  238.                                             GraphicsResource = rawObjectVariable.GraphicsResource,
  239.                                             Parent = effect,
  240.                                         };
  241.  
  242.                     effect.InternalParameters.Add(parameter);
  243.                 }
  244.             }
  245.  
  246.             // Add Effect groups, techniques, pass
  247.             foreach (var rawFxGroup in _fxGroups)
  248.             {
  249.                 var fxGroup = new EffectGroup(rawFxGroup.Name) {Parent = effect};
  250.                 effect.Groups.Add(fxGroup);
  251.                 FillAnnotations(rawFxGroup.Annotations, fxGroup.Annotations);
  252.  
  253.                 foreach (var rawTechnique in rawFxGroup.Techniques)
  254.                 {
  255.                     var technique = new EffectTechnique(rawTechnique.Name) { Parent = fxGroup};
  256.                     FillAnnotations(rawTechnique.Annotations, technique.Annotations);
  257.  
  258.                     fxGroup.Techniques.Add(technique);
  259.  
  260.                     // Add also the technique to the top effect
  261.                     effect.Techniques.Add(fxGroup.Name, technique);
  262.  
  263.                     foreach (var rawPass in rawTechnique.Passes)
  264.                     {
  265.                         var pass = new EffectPass(rawPass.Name, effect) {Parent = technique};
  266.                         FillAnnotations(rawPass.Annotations, pass.Annotations);
  267.                         technique.Passes.Add(pass);
  268.  
  269.                         foreach (var rawAssignment in rawPass.Assignments)
  270.                         {
  271.                             ShaderBytecode bytecode = null;
  272.  
  273.                             if (rawAssignment.ByteCode != null)
  274.                             {
  275.                                 bytecode = new ShaderBytecode(rawAssignment.ByteCode.Pointer, rawAssignment.ByteCode.Size);
  276.                                 if (rawAssignment.StreamOutputDeclarationString != null)
  277.                                     pass.GeometryStreamOutputDeclaration = new string[] {rawAssignment.StreamOutputDeclarationString};
  278.                             }
  279.                             else if (rawAssignment.InlineShader5 != null)
  280.                             {
  281.                                 bytecode = new ShaderBytecode(rawAssignment.InlineShader5.Bytecode.Pointer, rawAssignment.InlineShader5.Bytecode.Size);
  282.                                 pass.GeometryStreamOutputDeclaration = rawAssignment.InlineShader5.StreamOutputDeclarationString;
  283.                                 pass.GeometryStreamOutputRasterizedStream = rawAssignment.InlineShader5.RasterizedStream;
  284.                             }
  285.  
  286.                             if (bytecode != null)
  287.                             {
  288.                                 switch (rawAssignment.LeftHandSideValue.ShaderType)
  289.                                 {
  290.                                     case ShaderVariableType.Vertexshader:
  291.                                         pass.VertexShaderBytecode = bytecode;
  292.                                         break;
  293.                                     case ShaderVariableType.Geometryshader:
  294.                                         pass.GeometryShaderBytecode = bytecode;
  295.                                         break;
  296.                                     case ShaderVariableType.Pixelshader:
  297.                                         pass.PixelShaderBytecode = bytecode;
  298.                                         break;
  299.                                     case ShaderVariableType.Computeshader:
  300.                                         pass.ComputeShaderBytecode = bytecode;
  301.                                         break;
  302.                                     case ShaderVariableType.Domainshader:
  303.                                         pass.DomainShaderBytecode = bytecode;
  304.                                         break;
  305.                                     case ShaderVariableType.Hullshader:
  306.                                         pass.HullShaderBytecode = bytecode;
  307.                                         break;
  308.                                 }
  309.                             }
  310.                         }
  311.                     }
  312.                 }
  313.             }
  314.         }
  315.  
  316.         /// <summary>
  317.         /// Loads the contant buffers.
  318.         /// </summary>
  319.         private void LoadContantBuffers()
  320.         {
  321.             _binaryConstantBuffers = new CConstantBuffer[_binaryHeader.Effect.ConstantBufferCount];
  322.  
  323.             for (int i = 0; i < _binaryConstantBuffers.Length; i++)
  324.                 _binaryConstantBuffers[i] = LoadContantBuffer();
  325.         }
  326.  
  327.         /// <summary>
  328.         /// Loads a contant buffer.
  329.         /// </summary>
  330.         /// <returns></returns>
  331.         private CConstantBuffer LoadContantBuffer()
  332.         {
  333.             var cBuf = new CConstantBuffer();
  334.             Read(cBuf);
  335.             cBuf.Name = LoadString(cBuf.Binary.OffsetName);
  336.             cBuf.Annotations = LoadAnnotations();
  337.             cBuf.Variables = new CNumericVariable[cBuf.Binary.VariableCount];
  338.             for (int j = 0; j < cBuf.Variables.Length; j++)
  339.                 cBuf.Variables[j] = LoadNumericVariable();
  340.             return cBuf;
  341.         }
  342.  
  343.         /// <summary>
  344.         /// Loads the object variables.
  345.         /// </summary>
  346.         private void LoadObjectVariables()
  347.         {
  348.             _objectVariables = new CObjectVariable[_binaryHeader.Effect.ObjectVariableCount];
  349.  
  350.             for (int i = 0; i < _objectVariables.Length; i++)
  351.                 _objectVariables[i] = LoadObjectVariable();
  352.         }
  353.  
  354.         /// <summary>
  355.         /// Loads an object variable.
  356.         /// </summary>
  357.         /// <returns></returns>
  358.         private CObjectVariable LoadObjectVariable()
  359.         {
  360.             var objectVariable = new CObjectVariable();
  361.             Read(objectVariable);
  362.             objectVariable.Name = LoadString(objectVariable.Binary.OffsetName);
  363.             objectVariable.Semantic = LoadString(objectVariable.Binary.OffsetSemantic);
  364.             objectVariable.Type = LoadType(objectVariable.Binary.OffsetType);
  365.  
  366.             int nbElementToRead = (int)Math.Max(1, objectVariable.Type.Binary.ElementCount);
  367.  
  368.             // Initializer data:
  369.             //
  370.             // The type structure pointed to by OffsetType gives you ElementCount,
  371.             // VarType (must be Object), and ObjectType
  372.             //
  373.             // For ObjectType == Blend, DepthStencil, Rasterizer, Sampler
  374.             // struct
  375.             // {
  376.             //   UINT  AssignmentCount;
  377.             //   BinaryAssignment Assignments[AssignmentCount];
  378.             // } Blocks[ElementCount]
  379.             //
  380.             // For ObjectType == Texture*, Buffer
  381.             // <nothing>
  382.             //
  383.             // For ObjectType == *Shader, String
  384.             // UINT  OffsetData[ElementCount]; // offsets to a shader data block or a NULL-terminated string
  385.             //
  386.             // For ObjectType == GeometryShaderSO
  387.             //   BinaryGeometryShaderStreamOutputInitializer[ElementCount]
  388.             //
  389.             // For ObjectType == *Shader5
  390.             //   BinaryShaderDataFx5[ElementCount]
  391.             switch (objectVariable.Type.ObjectType)
  392.             {
  393.                 case ObjectType.Blend:
  394.                     for (int i = 0; i < nbElementToRead; i++)
  395.                         objectVariable.Assignments = LoadAssignments(Read<int>());
  396.                     objectVariable.UpdateBlendState();
  397.                     break;
  398.                 case ObjectType.DepthStencil:
  399.                     for (int i = 0; i < nbElementToRead; i++)
  400.                         objectVariable.Assignments = LoadAssignments(Read<int>());
  401.                     objectVariable.UpdateDepthStencilState();
  402.                     break;
  403.                 case ObjectType.Rasterizer:
  404.                     for (int i = 0; i < nbElementToRead; i++)
  405.                         objectVariable.Assignments = LoadAssignments(Read<int>());
  406.                     objectVariable.UpdateRasterizerState();
  407.                     break;
  408.                 case ObjectType.Sampler:
  409.                     for (int i = 0; i < nbElementToRead; i++)
  410.                         objectVariable.Assignments = LoadAssignments(Read<int>());
  411.                     objectVariable.UpdateSamplerState();
  412.                     break;
  413.                 case ObjectType.Buffer:
  414.                 case ObjectType.Texture:
  415.                 case ObjectType.Texture1D:
  416.                 case ObjectType.Texture1DArray:
  417.                 case ObjectType.Texture2D:
  418.                 case ObjectType.Texture2DArray:
  419.                 case ObjectType.Texture2DMS:
  420.                 case ObjectType.Texture2DMSArray:
  421.                 case ObjectType.Texture3D:
  422.                 case ObjectType.TextureCube:
  423.                 case ObjectType.TextureCubeArray:
  424.                 case ObjectType.RWBuffer:
  425.                 case ObjectType.RWByteAddressBuffer:
  426.                 case ObjectType.RWStructuredBuffer:
  427.                 case ObjectType.RWTexture1D:
  428.                 case ObjectType.RWTexture2D:
  429.                 case ObjectType.RWTexture3D:
  430.                     break;
  431.  
  432.                 case ObjectType.VertexShader:
  433.                 case ObjectType.GeometryShader:
  434.                 case ObjectType.PixelShader:
  435.                     objectVariable.Bytecodes = new CShaderBytecode[nbElementToRead];
  436.                     for (int i = 0; i < nbElementToRead; i++)
  437.                         objectVariable.Bytecodes[i] = LoadByteCode(Read<uint>());
  438.                     break;
  439.  
  440.                 case ObjectType.GeometryShaderSO:
  441.                     objectVariable.StreamOutputInitializers = new CGeometryShaderStreamOutputInitializer[nbElementToRead];
  442.                     for (int i = 0; i < nbElementToRead; i++)
  443.                     {
  444.                         var streamOutputInitializer = new CGeometryShaderStreamOutputInitializer();
  445.                         Read(streamOutputInitializer);
  446.                         streamOutputInitializer.ByteCode = LoadByteCode(streamOutputInitializer.Binary.OffsetShader);
  447.                         streamOutputInitializer.StreamOutputDeclarationString = LoadString(streamOutputInitializer.Binary.OffsetStreamOutputDeclaration);
  448.                         objectVariable.StreamOutputInitializers[i] = streamOutputInitializer;
  449.                     }
  450.                     break;
  451.                 case ObjectType.PixelShader5:
  452.                 case ObjectType.VertexShader5:
  453.                 case ObjectType.GeometryShader5:
  454.                 case ObjectType.ComputeShader5:
  455.                 case ObjectType.HullShader5:
  456.                 case ObjectType.DomainShader5:
  457.                     objectVariable.ShaderData = new CShaderDataFx5[nbElementToRead];
  458.                     for (int i = 0; i < nbElementToRead; i++)
  459.                         objectVariable.ShaderData[i] = LoadShaderDataFx5();
  460.                     break;
  461.                 default:
  462.                     LogError("Unsupported object variable {0} {1}", objectVariable.Name, objectVariable.Type.ObjectType);
  463.                     break;
  464.             }
  465.  
  466.             objectVariable.Annotations = LoadAnnotations();
  467.  
  468.             return objectVariable;
  469.         }
  470.  
  471.         /// <summary>
  472.         /// Loads the interface variables.
  473.         /// </summary>
  474.         private void LoadInterfaceVariables()
  475.         {
  476.             _interfaceVariables = new CInterfaceVariable[_binaryHeader11.InterfaceVariableCount];
  477.  
  478.             for (int i = 0; i < _interfaceVariables.Length; i++)
  479.                 _interfaceVariables[i] = LoadInterfaceVariable();
  480.         }
  481.  
  482.         /// <summary>
  483.         /// Loads an interface variable.
  484.         /// </summary>
  485.         /// <returns></returns>
  486.         private CInterfaceVariable LoadInterfaceVariable()
  487.         {
  488.             var interfaceVariable = new CInterfaceVariable();
  489.             Read(interfaceVariable);
  490.             interfaceVariable.Name = LoadString(interfaceVariable.Binary.OffsetName);
  491.             interfaceVariable.Type = LoadType(interfaceVariable.Binary.OffsetType);
  492.             interfaceVariable.Annotations = LoadAnnotations();
  493.             return interfaceVariable;
  494.         }
  495.  
  496.         /// <summary>
  497.         /// Loads the fxgroups.
  498.         /// </summary>
  499.         private void LoadFxGroups()
  500.         {
  501.             _fxGroups = new CFxGroup[_binaryHeader11.GroupCount];
  502.  
  503.             for (int i = 0; i < _fxGroups.Length; i++)
  504.                 _fxGroups[i] = LoadFxGroup();
  505.         }
  506.  
  507.         /// <summary>
  508.         /// Loads a fxgroup.
  509.         /// </summary>
  510.         /// <returns></returns>
  511.         private CFxGroup LoadFxGroup()
  512.         {
  513.             var group = new CFxGroup();
  514.             Read(group);
  515.             group.Name = LoadString(group.Binary.OffsetName);
  516.             group.Annotations = LoadAnnotations();
  517.             group.Techniques = LoadTechniques((int)group.Binary.TechniqueCount);
  518.             return group;
  519.         }
  520.  
  521.         /// <summary>
  522.         /// Loads the techniques.
  523.         /// </summary>
  524.         /// <param name="techniqueCount">The technique count.</param>
  525.         /// <returns></returns>
  526.         private CTechnique[] LoadTechniques(int techniqueCount)
  527.         {
  528.             var techniques = new CTechnique[techniqueCount];
  529.  
  530.             for (int i = 0; i < techniques.Length; i++)
  531.                 techniques[i] = LoadTechnique();
  532.             return techniques;
  533.         }
  534.  
  535.         /// <summary>
  536.         /// Loads a technique.
  537.         /// </summary>
  538.         /// <returns></returns>
  539.         private CTechnique LoadTechnique()
  540.         {
  541.             var technique = new CTechnique();
  542.             Read(technique);
  543.             technique.Name = LoadString(technique.Binary.OffsetName);
  544.             technique.Annotations = LoadAnnotations();
  545.             technique.Passes = LoadPasses((int)technique.Binary.PassCount);
  546.             return technique;
  547.         }
  548.  
  549.         /// <summary>
  550.         /// Loads the passes.
  551.         /// </summary>
  552.         /// <param name="passCount">The pass count.</param>
  553.         /// <returns></returns>
  554.         private CPass[] LoadPasses(int passCount)
  555.         {
  556.             var passes = new CPass[passCount];
  557.  
  558.             for (int i = 0; i < passes.Length; i++)
  559.                 passes[i] = LoadPass();
  560.             return passes;
  561.         }
  562.  
  563.         /// <summary>
  564.         /// Loads a pass.
  565.         /// </summary>
  566.         /// <returns></returns>
  567.         private CPass LoadPass()
  568.         {
  569.             var pass = new CPass();
  570.             Read(pass);
  571.             pass.Name = LoadString(pass.Binary.OffsetName);
  572.             pass.Annotations = LoadAnnotations();
  573.             pass.Assignments = LoadAssignments((int)pass.Binary.AssignmentCount);
  574.             return pass;
  575.         }
  576.  
  577.         /// <summary>
  578.         /// Loads the assignments.
  579.         /// </summary>
  580.         /// <param name="nbAssignments">The nb assignments.</param>
  581.         /// <returns></returns>
  582.         private CAssignment[] LoadAssignments(int nbAssignments)
  583.         {
  584.             var assignments = new CAssignment[nbAssignments];
  585.  
  586.             for (int i = 0; i < assignments.Length; i++)
  587.                 assignments[i] = LoadAssignment();
  588.             return assignments;
  589.         }
  590.  
  591.         /// <summary>
  592.         /// Loads an assignment.
  593.         /// </summary>
  594.         /// <returns></returns>
  595.         private CAssignment LoadAssignment()
  596.         {
  597.             var assignment = new CAssignment();
  598.             Read(assignment);
  599.             assignment.LeftHandSideValue = LeftHandSideValues[assignment.Binary.StateIndex];
  600.             assignment.IndexMax = assignment.LeftHandSideValue.IndexMax;
  601.             assignment.Index = unchecked((int)assignment.Binary.Index);
  602.  
  603.             IntPtr initData = _unStructuredDataBlock + (int)assignment.Binary.OffsetInitializer;
  604.  
  605.             // We handle only assignement for shaders
  606.             var shaderVariableType = assignment.LeftHandSideValue.ShaderType;
  607.  
  608.             switch (assignment.Binary.AssignmentType)
  609.             {
  610.                 case CompilerAssignmentType.InlineShader:
  611.                     var inlineShader = Read<BinaryAssignment.InlineShader>(ref initData);
  612.                     assignment.ByteCode = LoadByteCode(inlineShader.OffsetShader);
  613.                     if (assignment.LeftHandSideValue.ShaderType == ShaderVariableType.Geometryshader)
  614.                     {
  615.                         if (inlineShader.OffsetStreamOutputDeclaration != 0)
  616.                             assignment.StreamOutputDeclarationString = LoadString(inlineShader.OffsetStreamOutputDeclaration);
  617.                     }
  618.                     break;
  619.                 case CompilerAssignmentType.InlineShader5:
  620.                     assignment.InlineShader5 = LoadShaderDataFx5(ref initData);
  621.                     break;
  622.                 case CompilerAssignmentType.Variable:
  623.                     string variableName = LoadString(assignment.Binary.OffsetInitializer);
  624.                     var variable = FindVariable(variableName);
  625.  
  626.                     if (variable.ShaderData != null && variable.ShaderData.Length == 1)
  627.                     {
  628.                         assignment.InlineShader5 = variable.ShaderData[0];
  629.                     } else
  630.                     {
  631.                         switch (assignment.LeftHandSideValue.Type)
  632.                         {
  633.                             case LeftHandSideValueType.VertexShaderBlock:
  634.                             case LeftHandSideValueType.GeometryShaderBlock:
  635.                             case LeftHandSideValueType.PixelShaderBlock:
  636.                                 assignment.ByteCode = variable.Bytecodes[0];
  637.                                 break;
  638.                             case LeftHandSideValueType.GeometryShaderSO:
  639.                                 assignment.ByteCode = variable.StreamOutputInitializers[0].ByteCode;
  640.                                 assignment.StreamOutputDeclarationString = variable.StreamOutputInitializers[0].StreamOutputDeclarationString;
  641.                                 break;
  642.                             case LeftHandSideValueType.DepthStencilBlock:
  643.                                 assignment.IsDepthStencilBlock = true;
  644.                                 assignment.Variable = variable;
  645.                                 break;
  646.                             case LeftHandSideValueType.RasterizerBlock:
  647.                                 assignment.IsRasterizerBlock = true;
  648.                                 assignment.Variable = variable;
  649.                                 break;
  650.                             case LeftHandSideValueType.BlendBlock:
  651.                                 assignment.IsBlendBlock = true;
  652.                                 assignment.Variable = variable;
  653.                                 break;
  654.                             default:
  655.                                 LogError("Unexpected object variable assignement [{0}]", variableName);
  656.                                 break;
  657.                         }
  658.                     }
  659.                     break;
  660.                 case CompilerAssignmentType.Constant:
  661.                     uint nbConstants = Read<uint>(ref initData);
  662.                     //if (nbConstants != 1)
  663.                     //{
  664.                     //    LogError("Invalid number of constants [{0}] for variable type [{1}]. Must be == 1", nbConstants,
  665.                     //                               shaderVariableType);
  666.                     //    return assignment;
  667.                     //}
  668.                     object[] values = new object[nbConstants];
  669.  
  670.                     for (int i = 0; i < nbConstants; i++)
  671.                     {
  672.                         var binaryConstant = Read<BinaryConstant>(ref initData);
  673.                         switch (binaryConstant.Type)
  674.                         {
  675.                             case ScalarType.Int:
  676.                             case ScalarType.UInt:
  677.                                 if (shaderVariableType == ShaderVariableType.Bool)
  678.                                 {
  679.                                     values[i] = binaryConstant.IntegerValue != 0;
  680.                                 }
  681.                                 else
  682.                                 {
  683.                                     values[i] = binaryConstant.IntegerValue;
  684.                                 }
  685.                                 break;
  686.                             case ScalarType.Bool:
  687.                                 values[i] = binaryConstant.BooleanValue;
  688.                                 break;
  689.                             case ScalarType.Float:
  690.                                 values[i] = binaryConstant.FloatValue;
  691.                                 break;
  692.                         }
  693.                     }
  694.                     // If this is a single constant value, then store it only this value
  695.                     if (values.Length == 1)
  696.                     {
  697.                         assignment.ConstantValue = values[0];
  698.                     }
  699.                     else
  700.                     {
  701.                         // else store the array
  702.                         assignment.ConstantValue = values;
  703.                     }
  704.                     break;
  705.                 default:
  706.                     LogError("Unexpected assignement type [{0}] for variable type [{1}]", assignment.Binary.AssignmentType, shaderVariableType);
  707.                     break;
  708.             }
  709.             //ResolveDependency(assignment);
  710.             return assignment;
  711.         }
  712.  
  713.         /// <summary>
  714.         /// Loads the shader data FX5.
  715.         /// </summary>
  716.         /// <returns></returns>
  717.         private CShaderDataFx5 LoadShaderDataFx5()
  718.         {
  719.             return LoadShaderDataFx5(ref _currentPtr);
  720.         }
  721.  
  722.         /// <summary>
  723.         /// Loads the shader data FX5.
  724.         /// </summary>
  725.         /// <param name="fromPointer">From pointer.</param>
  726.         /// <returns></returns>
  727.         private CShaderDataFx5 LoadShaderDataFx5(ref IntPtr fromPointer)
  728.         {
  729.             var shader = new CShaderDataFx5 { Binary = Read<BinaryShaderDataFx5>(ref fromPointer) };
  730.             shader.Bytecode = LoadByteCode(shader.Binary.OffsetShader);
  731.             shader.StreamOutputDeclarationString = new string[shader.Binary.StreamOutputDeclarationCount];
  732.             for (int i = 0; i < shader.StreamOutputDeclarationString.Length; i++)
  733.                 shader.StreamOutputDeclarationString[i] = LoadString(shader.Binary.OffsetStreamOutputDeclarationString[i]);
  734.             shader.RasterizedStream = unchecked((int) shader.Binary.RasterizedStream);
  735.             return shader;
  736.         }
  737.  
  738.         /// <summary>
  739.         /// Finds a constant buffer by name.
  740.         /// </summary>
  741.         /// <param name="name">The name.</param>
  742.         /// <returns></returns>
  743.         private CConstantBuffer FindConstantBuffer(string name)
  744.         {
  745.             foreach (var binaryConstantBuffer in _binaryConstantBuffers)
  746.             {
  747.                 if (binaryConstantBuffer.Name == name)
  748.                 {
  749.                     return binaryConstantBuffer;
  750.                 }
  751.             }
  752.             return null;
  753.         }
  754.  
  755.         /// <summary>
  756.         /// Finds a variable by name.
  757.         /// </summary>
  758.         /// <param name="name">The name.</param>
  759.         /// <returns></returns>
  760.         private CObjectVariable FindVariable(string name)
  761.         {
  762.             foreach (var objectVariable in _objectVariables)
  763.             {
  764.                 if (objectVariable.Name == name)
  765.                 {
  766.                     return objectVariable;
  767.                 }
  768.             }
  769.             return null;
  770.         }
  771.  
  772.         /// <summary>
  773.         /// Loads a numeric variable.
  774.         /// </summary>
  775.         /// <returns></returns>
  776.         private CNumericVariable LoadNumericVariable()
  777.         {
  778.             var cNumericVariable = new CNumericVariable();
  779.             Read(cNumericVariable);
  780.             cNumericVariable.Name = LoadString(cNumericVariable.Binary.OffsetName);
  781.             cNumericVariable.Semantic = LoadString(cNumericVariable.Binary.OffsetSemantic);
  782.             cNumericVariable.Type = LoadType(cNumericVariable.Binary.OffsetType);
  783.             cNumericVariable.Annotations = LoadAnnotations();
  784.             return cNumericVariable;
  785.         }
  786.  
  787.         /// <summary>
  788.         /// Loads the annotations.
  789.         /// </summary>
  790.         /// <returns></returns>
  791.         private CAnnotation[] LoadAnnotations()
  792.         {
  793.             int numAnnotations = Read<int>();
  794.             var annotations = new CAnnotation[numAnnotations];
  795.             for (int i = 0; i < annotations.Length; i++)
  796.                 annotations[i] = LoadAnnotation();
  797.             return annotations;
  798.         }
  799.  
  800.         /// <summary>
  801.         /// Loads an annotation.
  802.         /// </summary>
  803.         /// <returns></returns>
  804.         private CAnnotation LoadAnnotation()
  805.         {
  806.             var annotation = new CAnnotation();
  807.             Read(annotation);
  808.             annotation.Name = LoadString(annotation.Binary.OffsetName);
  809.             annotation.Type = LoadType(annotation.Binary.OffsetType);
  810.  
  811.             // For numeric annotations:
  812.             // UINT  OffsetDefaultValue;     // Offset to default initializer value
  813.             //
  814.             // For string annotations:
  815.             // UINT  oStringOffsets[ElementCount]; // ElementCount comes from the type data at OffsetType
  816.  
  817.             if (annotation.Type.Binary.VarType == VariableType.Numeric)
  818.             {
  819.                 object annotationValue = null;
  820.                 uint offsetToUnstructured = Read<uint>();
  821.                 //uint sizeOfElement = annotation.Type.Binary.PackedSize;
  822.                 switch (annotation.Type.Name)
  823.                 {
  824.                     case "int":
  825.                         annotationValue = Read<int>(offsetToUnstructured);
  826.                         break;
  827.                     case "uint":
  828.                         annotationValue = Read<uint>(offsetToUnstructured);
  829.                         break;
  830.                     case "float":
  831.                         annotationValue = Read<float>(offsetToUnstructured);
  832.                         break;
  833.                     case "double":
  834.                         annotationValue = Read<double>(offsetToUnstructured);
  835.                         break;
  836.                     case "bool":
  837.                         annotationValue = Read<int>(offsetToUnstructured) != 0;
  838.                         break;
  839.                     case "float2":
  840.                         annotationValue = Read<Vector2>(offsetToUnstructured);
  841.                         break;
  842.                     case "float3":
  843.                         annotationValue = Read<Vector3>(offsetToUnstructured);
  844.                         break;
  845.                     case "float4":
  846.                         annotationValue = Read<Vector4>(offsetToUnstructured);
  847.                         break;
  848.                     default:
  849.                         LogError("Annotation default value type not handled [{0}]", annotation.Type.Name);
  850.                         break;
  851.                 }
  852.                 annotation.Value = annotationValue;
  853.             }
  854.             else if (annotation.Type.Binary.VarType == VariableType.Object && annotation.Type.ObjectType == ObjectType.String)
  855.             {
  856.                 uint elementCount = Math.Max(1, annotation.Type.Binary.ElementCount);
  857.                 if (elementCount > 1)
  858.                     LogError("Invalid number [{0}] of strings for annotation [{1}]", elementCount, annotation.Name);
  859.                 annotation.Value = LoadString(Read<uint>());
  860.             }
  861.             return annotation;
  862.         }
  863.  
  864.         /// <summary>
  865.         /// Loads a string from the unstructured data block.
  866.         /// </summary>
  867.         /// <param name="offset">The offset.</param>
  868.         /// <returns></returns>
  869.         private string LoadString(uint offset)
  870.         {
  871.             IntPtr ptr = _unStructuredDataBlock + (int)offset;
  872.             return Marshal.PtrToStringAnsi(ptr);
  873.         }
  874.  
  875.         /// <summary>
  876.         /// Loads shader byte code from the unstructured data block.
  877.         /// </summary>
  878.         /// <param name="offset">The offset.</param>
  879.         /// <returns></returns>
  880.         private CShaderBytecode LoadByteCode(uint offset)
  881.         {
  882.             var bytecode = new CShaderBytecode();
  883.             IntPtr typeBuffer = _unStructuredDataBlock + (int)offset;
  884.             bytecode.Size = Read<int>(ref typeBuffer);
  885.             bytecode.Pointer = typeBuffer;
  886.             return bytecode;
  887.         }
  888.  
  889.         /// <summary>
  890.         /// Loads a type from the unstructured data block.
  891.         /// </summary>
  892.         /// <param name="offset">The offset.</param>
  893.         /// <returns></returns>
  894.         private CType LoadType(uint offset)
  895.         {
  896.             var type = new CType();
  897.             IntPtr typeBuffer = _unStructuredDataBlock + (int)offset;
  898.             Read(ref typeBuffer, type);
  899.             type.Name = LoadString(type.Binary.OffsetTypeName);
  900.             if (type.Binary.VarType == VariableType.Object)
  901.             {
  902.                 type.ObjectType = (ObjectType)Read<int>(ref typeBuffer);
  903.             }
  904.             return type;
  905.         }
  906.  
  907.  
  908.         /// <summary>
  909.         /// Reads the T type from the current structured buffer.
  910.         /// </summary>
  911.         /// <typeparam name="T"></typeparam>
  912.         /// <returns></returns>
  913.         private T Read<T>()
  914.         {
  915.             return Read<T>(ref _currentPtr);
  916.         }
  917.  
  918.         /// <summary>
  919.         /// Reads the T type from the unstructured buffer.
  920.         /// </summary>
  921.         /// <typeparam name="T"></typeparam>
  922.         /// <returns></returns>
  923.         private T Read<T>(uint offset)
  924.         {
  925.             IntPtr ptr = _unStructuredDataBlock + (int)offset;
  926.             return Read<T>(ref ptr);
  927.         }
  928.  
  929.         /// <summary>
  930.         /// Reads the T type from the speicifed pointer. The pointer is moved according to the sizeof(T).
  931.         /// </summary>
  932.         /// <typeparam name="T"></typeparam>
  933.         /// <param name="from">From.</param>
  934.         /// <returns></returns>
  935.         private static T Read<T>(ref IntPtr from)
  936.         {
  937.             object o = Marshal.PtrToStructure(from, typeof(T));
  938.             from += Marshal.SizeOf(typeof(T));
  939.             return (T)o;
  940.         }
  941.  
  942.         /// <summary>
  943.         /// Fills a BinaryStruct object.
  944.         /// </summary>
  945.         /// <typeparam name="T"></typeparam>
  946.         /// <param name="from">From.</param>
  947.         /// <param name="value">The value.</param>
  948.         private static void Read<T>(ref IntPtr from, BinaryStruct<T> value)
  949.         {
  950.             value.Binary = Read<T>(ref from);
  951.         }
  952.  
  953.         /// <summary>
  954.         /// Reads a BinaryStruct object.
  955.         /// </summary>
  956.         /// <typeparam name="T"></typeparam>
  957.         /// <param name="value">The value.</param>
  958.         private void Read<T>(BinaryStruct<T> value)
  959.         {
  960.             value.Binary = Read<T>();
  961.         }
  962.  
  963.         /// <summary>
  964.         /// Gets a value indicating whether this instance has error.
  965.         /// </summary>
  966.         /// <value><c>true</c> if this instance has error; otherwise, <c>false</c>.</value>
  967.         private bool HasError { get; set; }
  968.  
  969.         /// <summary>
  970.         /// Logs an error.
  971.         /// </summary>
  972.         /// <param name="message">The message.</param>
  973.         /// <param name="args">The args.</param>
  974.         private void LogError(string message, params object[] args)
  975.         {
  976.             HasError = true;
  977.             Trace.TraceWarning(message, args);
  978.         }
  979.  
  980.         //////////////////////////////////////////////////////////////////////////
  981.         #region Intermediate Struct Container
  982.         //////////////////////////////////////////////////////////////////////////
  983.  
  984.         /// <summary>
  985.         /// Root class for structure container
  986.         /// </summary>
  987.         /// <typeparam name="T"></typeparam>
  988.         class BinaryStruct<T>
  989.         {
  990.             public T Binary;
  991.         }
  992.  
  993.         /// <summary>
  994.         /// Constant Buffer
  995.         /// </summary>
  996.         class CConstantBuffer : BinaryStruct<BinaryContantBuffer>
  997.         {
  998.             public string Name;
  999.             public CAnnotation[] Annotations;
  1000.             public CNumericVariable[] Variables;
  1001.         }
  1002.  
  1003.         /// <summary>
  1004.         /// Annotation
  1005.         /// </summary>
  1006.         class CAnnotation : BinaryStruct<BinaryAnnotation>
  1007.         {
  1008.             public string Name;
  1009.             public CType Type;
  1010.  
  1011.             public object Value;
  1012.         }
  1013.  
  1014.         /// <summary>
  1015.         /// Type
  1016.         /// </summary>
  1017.         class CType : BinaryStruct<BinaryType>
  1018.         {
  1019.             public string Name;
  1020.             public ObjectType ObjectType;
  1021.         }
  1022.  
  1023.         /// <summary>
  1024.         /// Numeric Variable
  1025.         /// </summary>
  1026.         class CNumericVariable : BinaryStruct<BinaryNumericVariable>
  1027.         {
  1028.             public string Name;
  1029.             public string Semantic;
  1030.             public CType Type;
  1031.             public CAnnotation[] Annotations;
  1032.         }
  1033.  
  1034.         /// <summary>
  1035.         /// Object Variable
  1036.         /// </summary>
  1037.         class CObjectVariable : BinaryStruct<BinaryObjectVariable>
  1038.         {
  1039.             public string Name;
  1040.             public string Semantic;
  1041.             public CType Type;
  1042.             public CAnnotation[] Annotations;
  1043.             public CAssignment[] Assignments;
  1044.             public CShaderBytecode[] Bytecodes;
  1045.             public CGeometryShaderStreamOutputInitializer[] StreamOutputInitializers;
  1046.             public CShaderDataFx5[] ShaderData;
  1047.  
  1048.             // Specific data for assignments
  1049.             public EffectParameterType GraphicsResourceType;
  1050.             public GraphicsResource GraphicsResource;
  1051.  
  1052.             /// <summary>
  1053.             /// Creates a BlendState object from the FX description.
  1054.             /// </summary>
  1055.             public void UpdateBlendState()
  1056.             {
  1057.                 if (Assignments == null || Assignments.Length == 0)
  1058.                     return;
  1059.                 var blendState = new BlendState();
  1060.                 GraphicsResourceType = EffectParameterType.SamplerState;
  1061.                 GraphicsResource = blendState;
  1062.  
  1063.                 blendState.AlphaToCoverageEnable = false;
  1064.                 blendState.IndependentBlendEnable = true;
  1065.  
  1066.                 foreach (var assignment in Assignments)
  1067.                 {
  1068.                     int rtIndex = assignment.Index;
  1069.                     switch (assignment.LeftHandSideValue.Type)
  1070.                     {
  1071.                         case LeftHandSideValueType.AlphaToCoverage:
  1072.                             blendState.AlphaToCoverageEnable = (bool)assignment.ConstantValue;
  1073.                             break;
  1074.                         case LeftHandSideValueType.BlendEnable:
  1075.                             blendState.RenderTargets[rtIndex].BlendEnable = (bool)assignment.ConstantValue;
  1076.                             break;
  1077.                         case LeftHandSideValueType.SrcBlend:                            
  1078.                             blendState.RenderTargets[rtIndex].ColorSourceBlend = (Blend)((int)assignment.ConstantValue);
  1079.                             break;
  1080.                         case LeftHandSideValueType.DestBlend:
  1081.                             blendState.RenderTargets[rtIndex].ColorDestinationBlend = (Blend)((int)assignment.ConstantValue);
  1082.                             break;
  1083.                         case LeftHandSideValueType.BlendOp:
  1084.                             blendState.RenderTargets[rtIndex].ColorBlendFunction = (BlendFunction)((int)assignment.ConstantValue);
  1085.                             break;
  1086.                         case LeftHandSideValueType.SrcBlendAlpha:
  1087.                             blendState.RenderTargets[rtIndex].AlphaSourceBlend = (Blend)((int)assignment.ConstantValue);
  1088.                             break;
  1089.                         case LeftHandSideValueType.DestBlendAlpha:
  1090.                             blendState.RenderTargets[rtIndex].AlphaDestinationBlend = (Blend)((int)assignment.ConstantValue);
  1091.                             break;
  1092.                         case LeftHandSideValueType.BlendOpAlpha:
  1093.                             blendState.RenderTargets[rtIndex].AlphaBlendFunction = (BlendFunction)((int)assignment.ConstantValue);
  1094.                             break;
  1095.                         case LeftHandSideValueType.RenderTargetWriteMask:
  1096.                             blendState.RenderTargets[rtIndex].ColorWriteChannels = (ColorWriteChannels)((int)assignment.ConstantValue);
  1097.                             break;
  1098.                     }
  1099.                 }
  1100.             }
  1101.  
  1102.             /// <summary>
  1103.             /// Creates a RasterizerState object from the FX description.
  1104.             /// </summary>
  1105.             public void UpdateRasterizerState()
  1106.             {
  1107.                 if (Assignments == null || Assignments.Length == 0)
  1108.                     return;
  1109.                 var rasterizerState = new RasterizerState();
  1110.                 GraphicsResourceType = EffectParameterType.RasterizerState; // Defaults are the same than strict fx_5_0 files
  1111.                 GraphicsResource = rasterizerState;
  1112.  
  1113.                 foreach (var assignment in Assignments)
  1114.                 {
  1115.                     switch (assignment.LeftHandSideValue.Type)
  1116.                     {
  1117.                         case LeftHandSideValueType.FillMode:
  1118.                             rasterizerState.FillMode = (FillMode)((int)assignment.ConstantValue);
  1119.                             break;
  1120.                         case LeftHandSideValueType.CullMode:
  1121.                             rasterizerState.CullMode = (CullMode)((int)assignment.ConstantValue);
  1122.                             break;
  1123.                         case LeftHandSideValueType.FrontCC:
  1124.                             rasterizerState.FrontFaceCounterClockwise = (bool)assignment.ConstantValue;
  1125.                             break;
  1126.                         case LeftHandSideValueType.DepthBias:
  1127.                             rasterizerState.DepthBias = ((int)assignment.ConstantValue);
  1128.                             break;
  1129.                         case LeftHandSideValueType.DepthBiasClamp:
  1130.                             rasterizerState.DepthBiasClamp = ((float)assignment.ConstantValue);
  1131.                             break;
  1132.                         case LeftHandSideValueType.SlopeScaledDepthBias:
  1133.                             rasterizerState.SlopeScaleDepthBias = ((float)assignment.ConstantValue);
  1134.                             break;
  1135.                         case LeftHandSideValueType.DepthClipEnable:
  1136.                             rasterizerState.DepthClipEnable = ((bool)assignment.ConstantValue);
  1137.                             break;
  1138.                         case LeftHandSideValueType.ScissorEnable:
  1139.                             rasterizerState.ScissorTestEnable = ((bool)assignment.ConstantValue);
  1140.                             break;
  1141.                         case LeftHandSideValueType.MultisampleEnable:
  1142.                             rasterizerState.MultiSampleAntiAlias = ((bool)assignment.ConstantValue);
  1143.                             break;
  1144.                         case LeftHandSideValueType.AntialiasedLineEnable:
  1145.                             rasterizerState.MultiSampleAntiAliasLine = ((bool)assignment.ConstantValue);
  1146.                             break;
  1147.                     }
  1148.                 }
  1149.  
  1150.             }
  1151.  
  1152.             /// <summary>
  1153.             /// Creates a DepthStencilState state object from the FX description.
  1154.             /// </summary>
  1155.             public void UpdateDepthStencilState()
  1156.             {
  1157.                 if (Assignments == null || Assignments.Length == 0)
  1158.                     return;
  1159.  
  1160.                 var depthStencilState = new DepthStencilState();
  1161.                 GraphicsResourceType = EffectParameterType.DepthStencilState; // Defaults are the same than strict fx_5_0 files
  1162.                 GraphicsResource = depthStencilState;
  1163.  
  1164.                 foreach (var assignment in Assignments)
  1165.                 {
  1166.                     switch (assignment.LeftHandSideValue.Type)
  1167.                     {
  1168.                         case LeftHandSideValueType.DepthEnable:
  1169.                             depthStencilState.DepthBufferEnable = ((bool)assignment.ConstantValue);
  1170.                             break;
  1171.                         case LeftHandSideValueType.DepthWriteMask:
  1172.                             depthStencilState.DepthBufferWriteEnable = ((int) assignment.ConstantValue) != 0;
  1173.                             break;
  1174.                         case LeftHandSideValueType.DepthFunc:
  1175.                             depthStencilState.DepthBufferFunction = (CompareFunction)((int)assignment.ConstantValue);
  1176.                             break;
  1177.                         case LeftHandSideValueType.StencilEnable:
  1178.                             depthStencilState.StencilEnable = ((bool)assignment.ConstantValue);
  1179.                             break;
  1180.                         case LeftHandSideValueType.StencilReadMask:
  1181.                             depthStencilState.StencilMask = ((int)assignment.ConstantValue);
  1182.                             break;
  1183.                         case LeftHandSideValueType.StencilWriteMask:
  1184.                             depthStencilState.StencilWriteMask = ((int)assignment.ConstantValue);
  1185.                             break;
  1186.                         case LeftHandSideValueType.FrontFaceStencilFailOp:
  1187.                             depthStencilState.StencilFail = (StencilOperation)((int)assignment.ConstantValue);
  1188.                             break;
  1189.                         case LeftHandSideValueType.FrontFaceStencilDepthFailOp:
  1190.                             depthStencilState.StencilDepthBufferFail = (StencilOperation)((int)assignment.ConstantValue);
  1191.                             break;
  1192.                         case LeftHandSideValueType.FrontFaceStencilPassOp:
  1193.                             depthStencilState.StencilPass = (StencilOperation)((int)assignment.ConstantValue);
  1194.                             break;
  1195.                         case LeftHandSideValueType.FrontFaceStencilFunc:
  1196.                             depthStencilState.StencilFunction = (CompareFunction)((int)assignment.ConstantValue);
  1197.                             break;
  1198.                         case LeftHandSideValueType.BackFaceStencilFailOp:
  1199.                             depthStencilState.CounterClockwiseStencilFail = (StencilOperation)((int)assignment.ConstantValue);
  1200.                             break;
  1201.                         case LeftHandSideValueType.BackFaceStencilDepthFailOp:
  1202.                             depthStencilState.CounterClockwiseStencilFail = (StencilOperation)((int)assignment.ConstantValue);
  1203.                             break;
  1204.                         case LeftHandSideValueType.BackFaceStencilPassOp:
  1205.                             depthStencilState.CounterClockwiseStencilFail = (StencilOperation)((int)assignment.ConstantValue);
  1206.                             break;
  1207.                         case LeftHandSideValueType.BackFaceStencilFunc:
  1208.                             depthStencilState.CounterClockwiseStencilFunction = (CompareFunction)((int)assignment.ConstantValue);
  1209.                             break;
  1210.                     }
  1211.                 }
  1212.             }
  1213.  
  1214.             /// <summary>
  1215.             /// Creates a SamplerState state object from the FX description.
  1216.             /// </summary>
  1217.             public void UpdateSamplerState()
  1218.             {
  1219.                 if (Assignments == null || Assignments.Length == 0)
  1220.                     return;
  1221.                 var samplerState = new SamplerState();
  1222.                 GraphicsResourceType = EffectParameterType.SamplerState;
  1223.                 GraphicsResource = samplerState;
  1224.  
  1225.                 // Defaults are slightly different here
  1226.                 samplerState.AddressU = TextureAddressMode.Clamp;
  1227.                 samplerState.AddressV = TextureAddressMode.Clamp;
  1228.                 samplerState.AddressW = TextureAddressMode.Clamp;
  1229.  
  1230.                 foreach (var assignment in Assignments)
  1231.                 {
  1232.                     switch (assignment.LeftHandSideValue.Type)
  1233.                     {
  1234.                         case LeftHandSideValueType.Filter:
  1235.                             samplerState.Filter = (TextureFilter)((int)assignment.ConstantValue);
  1236.                             break;
  1237.                         case LeftHandSideValueType.AddressU:
  1238.                             samplerState.AddressU = (TextureAddressMode) ((int) assignment.ConstantValue);
  1239.                             break;
  1240.                         case LeftHandSideValueType.AddressV:
  1241.                             samplerState.AddressV = (TextureAddressMode) ((int) assignment.ConstantValue);
  1242.                             break;
  1243.                         case LeftHandSideValueType.AddressW:
  1244.                             samplerState.AddressW = (TextureAddressMode) ((int) assignment.ConstantValue);
  1245.                             break;
  1246.                         case LeftHandSideValueType.MipLODBias:
  1247.                             samplerState.MipMapLevelOfDetailBias = ((float)assignment.ConstantValue);
  1248.                             break;
  1249.                         case LeftHandSideValueType.MaxAnisotropy:
  1250.                             samplerState.MaxAnisotropy = ((int)assignment.ConstantValue);
  1251.                             break;
  1252.                         case LeftHandSideValueType.ComparisonFunc:
  1253.                             samplerState.CompareFunction = (CompareFunction)((int)assignment.ConstantValue);
  1254.                             break;
  1255.                         case LeftHandSideValueType.BorderColor:
  1256.                             var values = (object[])assignment.ConstantValue;
  1257.                             samplerState.BorderColor = new Color4((float) values[3], (float) values[0], (float) values[1], (float) values[2]);
  1258.                             break;
  1259.                         case LeftHandSideValueType.MinLOD:
  1260.                             samplerState.MinMipLevel = ((float)assignment.ConstantValue);
  1261.                             break;
  1262.                         case LeftHandSideValueType.MaxLOD:
  1263.                             samplerState.MaxMipLevel = ((float)assignment.ConstantValue);
  1264.                             break;
  1265.                     }
  1266.                 }
  1267.             }
  1268.         }
  1269.  
  1270.         /// <summary>
  1271.         /// Interface Variable
  1272.         /// </summary>
  1273.         class CInterfaceVariable : BinaryStruct<BinaryInterfaceVariable>
  1274.         {
  1275.             public string Name;
  1276.             public CType Type;
  1277.             public CAnnotation[] Annotations;
  1278.         }
  1279.  
  1280.         /// <summary>
  1281.         /// Fx Group
  1282.         /// </summary>
  1283.         class CFxGroup : BinaryStruct<BinaryGroup>
  1284.         {
  1285.             public string Name;
  1286.             public CAnnotation[] Annotations;
  1287.             public CTechnique[] Techniques;
  1288.         }
  1289.  
  1290.         /// <summary>
  1291.         /// Technique
  1292.         /// </summary>
  1293.         class CTechnique : BinaryStruct<BinaryTechnique>
  1294.         {
  1295.             public string Name;
  1296.             public CAnnotation[] Annotations;
  1297.             public CPass[] Passes;
  1298.         }
  1299.  
  1300.         /// <summary>
  1301.         /// Pass
  1302.         /// </summary>
  1303.         class CPass : BinaryStruct<BinaryPass>
  1304.         {
  1305.             public string Name;
  1306.             public CAnnotation[] Annotations;
  1307.             public CAssignment[] Assignments;
  1308.         }
  1309.  
  1310.         /// <summary>
  1311.         /// Assignment
  1312.         /// </summary>
  1313.         class CAssignment : BinaryStruct<BinaryAssignment>
  1314.         {
  1315.             public LeftHandSideValue LeftHandSideValue;
  1316.  
  1317.             public int Index;
  1318.             public int IndexMax;
  1319.  
  1320.             // Fx4 shaders
  1321.             public CShaderBytecode ByteCode;
  1322.             public string StreamOutputDeclarationString;
  1323.  
  1324.             // Fx5 shaders
  1325.             public CShaderDataFx5 InlineShader5;
  1326.  
  1327.             public bool IsDepthStencilBlock;
  1328.             public bool IsRasterizerBlock;
  1329.             public bool IsBlendBlock;
  1330.  
  1331.             /// <summary>
  1332.             /// Variable
  1333.             /// </summary>
  1334.             public CObjectVariable Variable;
  1335.  
  1336.             // Constant value
  1337.             public object ConstantValue;
  1338.         }
  1339.  
  1340.         /// <summary>
  1341.         /// ShaderBytecode
  1342.         /// </summary>
  1343.         class CShaderBytecode
  1344.         {
  1345.             public int Size;
  1346.             public IntPtr Pointer;
  1347.         }
  1348.  
  1349.         /// <summary>
  1350.         /// ShaderData Fx5
  1351.         /// </summary>
  1352.         class CShaderDataFx5 : BinaryStruct<BinaryShaderDataFx5>
  1353.         {
  1354.             public CShaderBytecode Bytecode; // from OffsetShader
  1355.             public string[] StreamOutputDeclarationString; // Offset to StreamOutput decl strings
  1356.             public int RasterizedStream; // Which stream is used for rasterization
  1357.         }
  1358.  
  1359.         /// <summary>
  1360.         /// GeometryShaderStreamOutputInitializer
  1361.         /// </summary>
  1362.         class CGeometryShaderStreamOutputInitializer : BinaryStruct<BinaryGeometryShaderStreamOutputInitializer>
  1363.         {
  1364.             public CShaderBytecode ByteCode;
  1365.             public string StreamOutputDeclarationString;
  1366.         }
  1367.  
  1368.         #endregion
  1369.  
  1370.         //////////////////////////////////////////////////////////////////////////
  1371.         #region Native Structures
  1372.         //////////////////////////////////////////////////////////////////////////
  1373.  
  1374.         internal enum VersionTag : uint
  1375.         {
  1376.             Fx40 = 0xFEFF1001,      // fx_4_0
  1377.             Fx41 = 0xFEFF1011,      // fx_4_1
  1378.             Fx50 = 0xFEFF2001,      // fx_5_0
  1379.         }
  1380.  
  1381.  
  1382.         // Enumeration of the possible left-hand side values of an assignment,
  1383.         // divided up categorically by the type of block they may appear in
  1384.         internal enum LeftHandSideValueType
  1385.         {
  1386.             Invalid,
  1387.  
  1388.             // Pass block assignment types
  1389.  
  1390.             PixelShaderBlock, // SBlock *pValue points to the block to apply
  1391.             VertexShaderBlock,
  1392.             GeometryShaderBlock,
  1393.             RenderTargetView,
  1394.             DepthStencilView,
  1395.  
  1396.             RasterizerBlock,
  1397.             DepthStencilBlock,
  1398.             BlendBlock,
  1399.  
  1400.             GenerateMips, // This is really a call to D3D::GenerateMips
  1401.  
  1402.             // Various SAssignment.Value.*
  1403.  
  1404.             DS_StencilRef, // SAssignment.Value.pdValue
  1405.             B_BlendFactor, // D3D10_BLEND_CONFIG.BlendFactor, points to a float4
  1406.             B_SampleMask, // D3D10_BLEND_CONFIG.SampleMask
  1407.  
  1408.             GeometryShaderSO,
  1409.             // When setting SO assignments, GeometryShaderSO precedes the actual GeometryShader assn
  1410.  
  1411.             ComputeShaderBlock,
  1412.             HullShaderBlock,
  1413.             DomainShaderBlock,
  1414.  
  1415.             // Rasterizer
  1416.  
  1417.             FillMode = 0x20000,
  1418.             CullMode,
  1419.             FrontCC,
  1420.             DepthBias,
  1421.             DepthBiasClamp,
  1422.             SlopeScaledDepthBias,
  1423.             DepthClipEnable,
  1424.             ScissorEnable,
  1425.             MultisampleEnable,
  1426.             AntialiasedLineEnable,
  1427.  
  1428.             // Sampler
  1429.  
  1430.             Filter = 0x30000,
  1431.             AddressU,
  1432.             AddressV,
  1433.             AddressW,
  1434.             MipLODBias,
  1435.             MaxAnisotropy,
  1436.             ComparisonFunc,
  1437.             BorderColor,
  1438.             MinLOD,
  1439.             MaxLOD,
  1440.             Texture,
  1441.  
  1442.             // DepthStencil
  1443.  
  1444.             DepthEnable = 0x40000,
  1445.             DepthWriteMask,
  1446.             DepthFunc,
  1447.             StencilEnable,
  1448.             StencilReadMask,
  1449.             StencilWriteMask,
  1450.             FrontFaceStencilFailOp,
  1451.             FrontFaceStencilDepthFailOp,
  1452.             FrontFaceStencilPassOp,
  1453.             FrontFaceStencilFunc,
  1454.             BackFaceStencilFailOp,
  1455.             BackFaceStencilDepthFailOp,
  1456.             BackFaceStencilPassOp,
  1457.             BackFaceStencilFunc,
  1458.  
  1459.             // BlendState
  1460.  
  1461.             AlphaToCoverage = 0x50000,
  1462.             BlendEnable,
  1463.             SrcBlend,
  1464.             DestBlend,
  1465.             BlendOp,
  1466.             SrcBlendAlpha,
  1467.             DestBlendAlpha,
  1468.             BlendOpAlpha,
  1469.             RenderTargetWriteMask,
  1470.         }
  1471.  
  1472.  
  1473.         internal enum BlockType
  1474.         {
  1475.             Invalid,
  1476.             DepthStencil,
  1477.             Blend,
  1478.             Rasterizer,
  1479.             Sampler,
  1480.             Pass
  1481.         }
  1482.  
  1483.         internal enum VariableType
  1484.         {
  1485.             Invalid,
  1486.             Numeric,
  1487.             Object,
  1488.             Struct,
  1489.             Interface,
  1490.         }
  1491.  
  1492.         internal enum ScalarType
  1493.         {
  1494.             Invalid,
  1495.             Float,
  1496.             Int,
  1497.             UInt,
  1498.             Bool,
  1499.             Count
  1500.         }
  1501.  
  1502.         internal enum NumericLayout
  1503.         {
  1504.             Invalid,
  1505.             Scalar,
  1506.             Vector,
  1507.             Matrix,
  1508.             Count
  1509.         }
  1510.  
  1511.         internal enum ObjectType
  1512.         {
  1513.             Invalid,
  1514.             String,
  1515.             Blend,
  1516.             DepthStencil,
  1517.             Rasterizer,
  1518.             PixelShader,
  1519.             VertexShader,
  1520.             GeometryShader, // Regular geometry shader
  1521.             GeometryShaderSO, // Geometry shader with a attached StreamOut decl
  1522.             Texture,
  1523.             Texture1D,
  1524.             Texture1DArray,
  1525.             Texture2D,
  1526.             Texture2DArray,
  1527.             Texture2DMS,
  1528.             Texture2DMSArray,
  1529.             Texture3D,
  1530.             TextureCube,
  1531.             ConstantBuffer,
  1532.             RenderTargetView,
  1533.             DepthStencilView,
  1534.             Sampler,
  1535.             Buffer,
  1536.             TextureCubeArray,
  1537.             Count,
  1538.             PixelShader5,
  1539.             VertexShader5,
  1540.             GeometryShader5,
  1541.             ComputeShader5,
  1542.             HullShader5,
  1543.             DomainShader5,
  1544.             RWTexture1D,
  1545.             RWTexture1DArray,
  1546.             RWTexture2D,
  1547.             RWTexture2DArray,
  1548.             RWTexture3D,
  1549.             RWBuffer,
  1550.             ByteAddressBuffer,
  1551.             RWByteAddressBuffer,
  1552.             StructuredBuffer,
  1553.             RWStructuredBuffer,
  1554.             RWStructuredBufferAlloc,
  1555.             RWStructuredBufferConsume,
  1556.             AppendStructuredBuffer,
  1557.             ConsumeStructuredBuffer,
  1558.         }
  1559.  
  1560.         // Effect file format structures /////////////////////////////////////////////
  1561.         // File format:
  1562.         //   File Header (BinaryHeader Header)
  1563.         //   Unstructured data block (BYTE[Header.cbUnstructured))
  1564.         //   Structured data block
  1565.         //     ConstantBuffer (BinaryContantBuffer CB) * Header.Effect.ConstantBufferCount
  1566.         //       uint  NumAnnotations
  1567.         //       Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  1568.         //       Variable data (BinaryNumericVariable Var) * (CB.VariableCount)
  1569.         //         uint  NumAnnotations
  1570.         //         Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  1571.         //     Object variables (BinaryObjectVariable Var) * (Header.ObjectVariableCount) *this structure is variable sized
  1572.         //       uint  NumAnnotations
  1573.         //       Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  1574.         //     Interface variables (BinaryInterfaceVariable Var) * (Header.InterfaceVariableCount) *this structure is variable sized
  1575.         //       uint  NumAnnotations
  1576.         //       Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  1577.         //     Groups (BinaryGroup Group) * Header.GroupCount
  1578.         //       uint  NumAnnotations
  1579.         //       Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  1580.         //       Techniques (BinaryTechnique Technique) * Group.TechniqueCount
  1581.         //         uint  NumAnnotations
  1582.         //         Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  1583.         //         Pass (SBinaryPass Pass) * Technique.PassCount
  1584.         //           uint  NumAnnotations
  1585.         //           Annotation data (BinaryAnnotation) * (NumAnnotations) *this structure is variable sized
  1586.         //           Pass assignments (BinaryAssignment) * Pass.AssignmentCount
  1587.  
  1588.         [StructLayout(LayoutKind.Sequential)]
  1589.         internal struct BinaryHeader
  1590.         {
  1591.             internal struct SVarCounts
  1592.             {
  1593.                 public uint ConstantBufferCount;
  1594.                 public uint NumericVariableCount;
  1595.                 public uint ObjectVariableCount;
  1596.             } ;
  1597.  
  1598.             public VersionTag Tag; // should be equal to c_EffectFileTag
  1599.             // this is used to identify ASCII vs Binary files
  1600.  
  1601.             public SVarCounts Effect;
  1602.             public SVarCounts Pool;
  1603.  
  1604.             public uint TechniqueCount;
  1605.             public uint cbUnstructured;
  1606.  
  1607.             public uint StringCount;
  1608.             public uint ShaderResourceCount;
  1609.  
  1610.             public uint DepthStencilBlockCount;
  1611.             public uint BlendStateBlockCount;
  1612.             public uint RasterizerStateBlockCount;
  1613.             public uint SamplerCount;
  1614.             public uint RenderTargetViewCount;
  1615.             public uint DepthStencilViewCount;
  1616.  
  1617.             public uint TotalShaderCount;
  1618.  
  1619.             public uint InlineShaderCount;
  1620.             // of the aforementioned shaders, the number that are defined inline within pass blocks
  1621.         }
  1622.  
  1623.         [StructLayout(LayoutKind.Sequential)]
  1624.         internal struct BinaryHeader11
  1625.         {
  1626.             public BinaryHeader Header;
  1627.             public uint GroupCount;
  1628.             public uint UnorderedAccessViewCount;
  1629.             public uint InterfaceVariableCount;
  1630.             public uint InterfaceVariableElementCount;
  1631.             public uint ClassInstanceElementCount;
  1632.         }
  1633.  
  1634.         // Constant buffer definition
  1635.         [StructLayout(LayoutKind.Sequential)]
  1636.         internal struct BinaryContantBuffer
  1637.         {
  1638.             // flags
  1639.             public const uint c_IsTBuffer = (1 << 0);
  1640.             public const uint c_IsSingle = (1 << 1);
  1641.  
  1642.             public uint OffsetName; // Offset to constant buffer name
  1643.             public uint Size; // Size, in bytes
  1644.             public uint Flags;
  1645.             public uint VariableCount; // # of variables inside this buffer
  1646.  
  1647.             public uint ExplicitBindPoint;
  1648.             // Defined if the effect file specifies a bind point using the register keyword
  1649.  
  1650.             // otherwise, -1
  1651.         }
  1652.  
  1653.         [StructLayout(LayoutKind.Sequential)]
  1654.         internal struct BinaryAnnotation
  1655.         {
  1656.             public uint OffsetName; // Offset to variable name
  1657.             public uint OffsetType; // Offset to type information (BinaryType)
  1658.  
  1659.             // For numeric annotations:
  1660.             // uint  OffsetDefaultValue;     // Offset to default initializer value
  1661.             //
  1662.             // For string annotations:
  1663.             // uint  oStringOffsets[ElementCount]; // ElementCount comes from the type data at OffsetType
  1664.         } ;
  1665.  
  1666.         [StructLayout(LayoutKind.Sequential)]
  1667.         internal struct BinaryNumericVariable
  1668.         {
  1669.             public uint OffsetName; // Offset to variable name
  1670.             public uint OffsetType; // Offset to type information (BinaryType)
  1671.             public uint OffsetSemantic; // Offset to semantic information
  1672.             public uint Offset; // Offset in parent constant buffer
  1673.             public uint OffsetDefaultValue; // Offset to default initializer value
  1674.             public uint Flags; // Explicit bind point
  1675.         } ;
  1676.  
  1677.         [StructLayout(LayoutKind.Sequential)]
  1678.         internal struct BinaryInterfaceVariable
  1679.         {
  1680.             public uint OffsetName; // Offset to variable name
  1681.             public uint OffsetType; // Offset to type information (BinaryType)
  1682.             public uint OffsetDefaultValue; // Offset to default initializer array (BinaryInterfaceInitializer[ElementCount])
  1683.             public uint Flags;
  1684.         } ;
  1685.  
  1686.         [StructLayout(LayoutKind.Sequential)]
  1687.         internal struct BinaryInterfaceInitializer
  1688.         {
  1689.             public uint OffsetInstanceName;
  1690.             public uint ArrayIndex;
  1691.         } ;
  1692.  
  1693.         [StructLayout(LayoutKind.Sequential)]
  1694.         internal struct BinaryObjectVariable
  1695.         {
  1696.             public uint OffsetName; // Offset to variable name
  1697.             public uint OffsetType; // Offset to type information (BinaryType)
  1698.             public uint OffsetSemantic; // Offset to semantic information
  1699.             public uint ExplicitBindPoint; // Used when a variable has been explicitly bound (register(XX)). -1 if not
  1700.  
  1701.             // Initializer data:
  1702.             //
  1703.             // The type structure pointed to by OffsetType gives you ElementCount,
  1704.             // VarType (must be Object), and ObjectType
  1705.             //
  1706.             // For ObjectType == Blend, DepthStencil, Rasterizer, Sampler
  1707.             // struct
  1708.             // {
  1709.             //   uint  AssignmentCount;
  1710.             //   BinaryAssignment Assignments[AssignmentCount];
  1711.             // } Blocks[ElementCount]
  1712.             //
  1713.             // For ObjectType == Texture*, Buffer
  1714.             // <nothing>
  1715.             //
  1716.             // For ObjectType == *Shader, String
  1717.             // uint  OffsetData[ElementCount]; // offsets to a shader data block or a NULL-terminated string
  1718.             //
  1719.             // For ObjectType == GeometryShaderSO
  1720.             //   BinaryGeometryShaderStreamOutputInitializer[ElementCount]
  1721.             //
  1722.             // For ObjectType == *Shader5
  1723.             //   BinaryShaderDataFx5[ElementCount]
  1724.         }
  1725.  
  1726.         [StructLayout(LayoutKind.Sequential)]
  1727.         internal struct BinaryGeometryShaderStreamOutputInitializer
  1728.         {
  1729.             public uint OffsetShader; // Offset to shader bytecode data block
  1730.             public uint OffsetStreamOutputDeclaration; // Offset to StreamOutput decl string
  1731.         }
  1732.  
  1733.         [StructLayout(LayoutKind.Sequential)]
  1734.         internal struct BinaryShaderDataFx5
  1735.         {
  1736.             public uint OffsetShader; // Offset to shader bytecode data block
  1737.             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
  1738.             public uint[] OffsetStreamOutputDeclarationString; // Offset to StreamOutput decl strings
  1739.             public uint StreamOutputDeclarationCount; // Count of valid oSODecls entries.
  1740.             public uint RasterizedStream; // Which stream is used for rasterization
  1741.             public uint InterfaceBindingCount; // Count of interface bindings.
  1742.             public uint OffsetInterfaceBindings; // Offset to BinaryInterfaceInitializer[InterfaceBindingCount].
  1743.         }
  1744.  
  1745.         [StructLayout(LayoutKind.Sequential)]
  1746.         internal struct BinaryType
  1747.         {
  1748.             public uint OffsetTypeName; // Offset to friendly type name ("float4", "VS_OUTPUT")
  1749.             public VariableType VarType; // Numeric, Object, or Struct
  1750.             public uint ElementCount; // # of array elements (0 for non-arrays)
  1751.             public uint TotalSize; // Size in bytes; not necessarily Stride * ElementCount for arrays
  1752.             // because of possible gap left in final register
  1753.             public uint Stride; // If an array, this is the spacing between elements.
  1754.             // For unpacked arrays, always divisible by 16-bytes (1 register).
  1755.             // No support for packed arrays    
  1756.             public uint PackedSize; // Size, in bytes, of this data typed when fully packed
  1757.  
  1758.             [StructLayout(LayoutKind.Sequential)]
  1759.             internal struct BinaryMember
  1760.             {
  1761.                 public uint OffsetName; // Offset to structure member name ("m_pFoo")
  1762.                 public uint OffsetSemantic; // Offset to semantic ("POSITION0")
  1763.                 public uint Offset; // Offset, in bytes, relative to start of parent structure
  1764.                 public uint OffsetType; // Offset to member's type descriptor
  1765.             } ;
  1766.  
  1767.             // the data that follows depends on the VarType:
  1768.             // Numeric: SType::SNumericType
  1769.             // Object:  ObjectType
  1770.             // Struct:  
  1771.             //   struct
  1772.             //   {
  1773.             //        uint              cMembers;
  1774.             //        SBinaryMembers    Members[cMembers];
  1775.             //   } MemberInfo
  1776.             //   struct
  1777.             //   {
  1778.             //        uint              oBaseClassType;  // Offset to type information (BinaryType)
  1779.             //        uint              InterfaceCount;
  1780.             //        uint              oInterfaceTypes[InterfaceCount];
  1781.             //   } BinaryTypeInheritance
  1782.             // Interface: (nothing)
  1783.         }
  1784.  
  1785.         [StructLayout(LayoutKind.Sequential)]
  1786.         internal struct BinaryNumericType
  1787.         {
  1788.             //ENumericLayout  NumericLayout   : 3;    // scalar (1x1), vector (1xN), matrix (NxN)
  1789.             //EScalarType     ScalarType      : 5;    // float32, int32, int8, etc.
  1790.             //uint            Rows            : 3;    // 1 <= Rows <= 4
  1791.             //uint            Columns         : 3;    // 1 <= Columns <= 4
  1792.             //uint            IsColumnMajor   : 1;    // applies only to matrices
  1793.             //uint            IsPackedArray   : 1;    // if this is an array, indicates whether elements should be greedily packed
  1794.             public byte PackedValue1;
  1795.             public byte PackedValue2;
  1796.         }
  1797.  
  1798.         [StructLayout(LayoutKind.Sequential)]
  1799.         internal struct BinaryTypeInheritance
  1800.         {
  1801.             public uint OffsetBaseClass; // Offset to base class type info or 0 if no base class.
  1802.             public uint InterfaceCount;
  1803.  
  1804.             // Followed by uint[InterfaceCount] with offsets to the type
  1805.             // info of each interface.
  1806.         }
  1807.  
  1808.         [StructLayout(LayoutKind.Sequential)]
  1809.         internal struct BinaryGroup
  1810.         {
  1811.             public uint OffsetName;
  1812.             public uint TechniqueCount;
  1813.         }
  1814.  
  1815.         [StructLayout(LayoutKind.Sequential)]
  1816.         internal struct BinaryTechnique
  1817.         {
  1818.             public uint OffsetName;
  1819.             public uint PassCount;
  1820.         }
  1821.  
  1822.         [StructLayout(LayoutKind.Sequential)]
  1823.         internal struct BinaryPass
  1824.         {
  1825.             public uint OffsetName;
  1826.             public uint AssignmentCount;
  1827.         }
  1828.  
  1829.         internal enum CompilerAssignmentType
  1830.         {
  1831.             Invalid, // Assignment-specific data (always in the unstructured blob)
  1832.             Constant, // -N SConstant structures
  1833.             Variable, // -NULL terminated string with variable name ("foo")
  1834.             ConstIndex, // -ConstantIndex structure
  1835.             VariableIndex, // -VariableIndex structure
  1836.             ExpressionIndex, // -IndexedObjectExpression structure
  1837.             Expression, // -Data block containing FXLVM code
  1838.             InlineShader, // -Data block containing shader
  1839.             InlineShader5, // -Data block containing shader with extended 5.0 data (BinaryShaderDataFx5)
  1840.         }
  1841.  
  1842.         [StructLayout(LayoutKind.Sequential)]
  1843.         internal struct BinaryAssignment
  1844.         {
  1845.             public uint StateIndex; // index into g_lvGeneral
  1846.             public uint Index; // the particular index to assign to (see g_lvGeneral to find the # of valid indices)
  1847.             public CompilerAssignmentType AssignmentType;
  1848.             public uint OffsetInitializer; // Offset of assignment-specific data
  1849.  
  1850.             //struct SConstantAssignment
  1851.             //{
  1852.             //    uint  NumConstants;         // number of constants to follow
  1853.             //    SBinaryConstant Constants[NumConstants];
  1854.             //};
  1855.  
  1856.             [StructLayout(LayoutKind.Sequential)]
  1857.             internal struct ConstantIndex
  1858.             {
  1859.                 public uint OffsetArrayName;
  1860.                 public uint Index;
  1861.             }
  1862.  
  1863.             [StructLayout(LayoutKind.Sequential)]
  1864.             internal struct VariableIndex
  1865.             {
  1866.                 public uint OffsetArrayName;
  1867.                 public uint OffsetIndexVariableName;
  1868.             }
  1869.  
  1870.             [StructLayout(LayoutKind.Sequential)]
  1871.             internal struct IndexedObjectExpression
  1872.             {
  1873.                 public uint OffsetArrayName;
  1874.                 public uint OffsetCode;
  1875.             }
  1876.  
  1877.             [StructLayout(LayoutKind.Sequential)]
  1878.             internal struct InlineShader
  1879.             {
  1880.                 public uint OffsetShader;
  1881.                 public uint OffsetStreamOutputDeclaration;
  1882.             }
  1883.  
  1884.             //struct SExpression or InlineShader
  1885.             //{
  1886.             //    uint  DataSize;
  1887.             //    BYTE Data[DataSize];
  1888.             //}
  1889.         }
  1890.  
  1891.         [StructLayout(LayoutKind.Explicit)]
  1892.         internal struct BinaryConstant
  1893.         {
  1894.             [FieldOffset(0)]
  1895.             public ScalarType Type;
  1896.  
  1897.             [FieldOffset(4)]
  1898.             public bool BooleanValue;
  1899.  
  1900.             [FieldOffset(4)]
  1901.             public int IntegerValue;
  1902.  
  1903.             [FieldOffset(4)]
  1904.             public float FloatValue;
  1905.         }
  1906.  
  1907.         internal class LeftHandSideValue
  1908.         {
  1909.             public LeftHandSideValue(LeftHandSideValueType type, BlockType blockType, ShaderVariableType shaderType, int columnCount, int indexMax, bool vectorScalar)
  1910.             {
  1911.                 Type = type;
  1912.                 BlockType = blockType;
  1913.                 ShaderType = shaderType;
  1914.                 ColumnCount = columnCount;
  1915.                 IndexMax = indexMax;
  1916.                 VectorScalar = vectorScalar;
  1917.             }
  1918.  
  1919.             public LeftHandSideValueType Type { get; set; }
  1920.             public BlockType BlockType { get; set; }
  1921.             public ShaderVariableType ShaderType { get; set; }
  1922.             public int ColumnCount { get; set; }
  1923.             public int IndexMax { get; set; }
  1924.             public bool VectorScalar { get; set; }
  1925.         }
  1926.  
  1927.         private static readonly LeftHandSideValue[] LeftHandSideValues = new LeftHandSideValue[]
  1928.                                                               {
  1929.                                     new LeftHandSideValue(LeftHandSideValueType.RasterizerBlock, BlockType.Pass, ShaderVariableType.Rasterizer, 1, 1, false),
  1930.                                     new LeftHandSideValue(LeftHandSideValueType.DepthStencilBlock, BlockType.Pass, ShaderVariableType.Depthstencil, 1, 1, false),
  1931.                                     new LeftHandSideValue(LeftHandSideValueType.BlendBlock, BlockType.Pass, ShaderVariableType.Blend, 1, 1, false),
  1932.                                     new LeftHandSideValue(LeftHandSideValueType.RenderTargetView, BlockType.Pass, ShaderVariableType.Rendertargetview, 1, 8, false),
  1933.                                     new LeftHandSideValue(LeftHandSideValueType.DepthStencilView, BlockType.Pass, ShaderVariableType.Depthstencilview, 1, 8, false),
  1934.                                     new LeftHandSideValue(LeftHandSideValueType.GenerateMips, BlockType.Pass, ShaderVariableType.Texture, 1, 1, false),
  1935.                                     new LeftHandSideValue(LeftHandSideValueType.VertexShaderBlock, BlockType.Pass, ShaderVariableType.Vertexshader, 1, 1, false),
  1936.                                     new LeftHandSideValue(LeftHandSideValueType.PixelShaderBlock, BlockType.Pass, ShaderVariableType.Pixelshader, 1, 1, false),
  1937.                                     new LeftHandSideValue(LeftHandSideValueType.GeometryShaderBlock, BlockType.Pass, ShaderVariableType.Geometryshader, 1, 1, false),
  1938.                                     new LeftHandSideValue(LeftHandSideValueType.DS_StencilRef, BlockType.Pass, ShaderVariableType.UInt, 1, 1, false),
  1939.                                     new LeftHandSideValue(LeftHandSideValueType.B_BlendFactor, BlockType.Pass, ShaderVariableType.Float, 4, 1, false),
  1940.                                     new LeftHandSideValue(LeftHandSideValueType.B_SampleMask, BlockType.Pass, ShaderVariableType.UInt, 1, 1, false),
  1941.                                     new LeftHandSideValue(LeftHandSideValueType.FillMode, BlockType.Rasterizer, ShaderVariableType.UInt, 1, 1, false),
  1942.                                     new LeftHandSideValue(LeftHandSideValueType.CullMode, BlockType.Rasterizer, ShaderVariableType.UInt, 1, 1, false),
  1943.                                     new LeftHandSideValue(LeftHandSideValueType.FrontCC, BlockType.Rasterizer, ShaderVariableType.Bool, 1, 1, false),
  1944.                                     new LeftHandSideValue(LeftHandSideValueType.DepthBias, BlockType.Rasterizer, ShaderVariableType.UInt, 1, 1, false),
  1945.                                     new LeftHandSideValue(LeftHandSideValueType.DepthBiasClamp, BlockType.Rasterizer, ShaderVariableType.Float, 1, 1, false),
  1946.                                     new LeftHandSideValue(LeftHandSideValueType.SlopeScaledDepthBias, BlockType.Rasterizer, ShaderVariableType.Float, 1, 1, false),
  1947.                                     new LeftHandSideValue(LeftHandSideValueType.DepthClipEnable, BlockType.Rasterizer, ShaderVariableType.Bool, 1, 1, false),
  1948.                                     new LeftHandSideValue(LeftHandSideValueType.ScissorEnable, BlockType.Rasterizer, ShaderVariableType.Bool, 1, 1, false),
  1949.                                     new LeftHandSideValue(LeftHandSideValueType.MultisampleEnable, BlockType.Rasterizer, ShaderVariableType.Bool, 1, 1, false),
  1950.                                     new LeftHandSideValue(LeftHandSideValueType.AntialiasedLineEnable, BlockType.Rasterizer, ShaderVariableType.Bool, 1, 1, false),
  1951.                                     new LeftHandSideValue(LeftHandSideValueType.DepthEnable, BlockType.DepthStencil, ShaderVariableType.Bool, 1, 1, false),
  1952.                                     new LeftHandSideValue(LeftHandSideValueType.DepthWriteMask, BlockType.DepthStencil, ShaderVariableType.UInt, 1, 1, false),
  1953.                                     new LeftHandSideValue(LeftHandSideValueType.DepthFunc, BlockType.DepthStencil, ShaderVariableType.UInt, 1, 1, false),
  1954.                                     new LeftHandSideValue(LeftHandSideValueType.StencilEnable, BlockType.DepthStencil, ShaderVariableType.Bool, 1, 1, false),
  1955.                                     new LeftHandSideValue(LeftHandSideValueType.StencilReadMask, BlockType.DepthStencil, ShaderVariableType.UInt8, 1, 1, false),
  1956.                                     new LeftHandSideValue(LeftHandSideValueType.StencilWriteMask, BlockType.DepthStencil, ShaderVariableType.UInt8, 1, 1, false),
  1957.                                     new LeftHandSideValue(LeftHandSideValueType.FrontFaceStencilFailOp, BlockType.DepthStencil, ShaderVariableType.UInt, 1, 1, false),
  1958.                                     new LeftHandSideValue(LeftHandSideValueType.FrontFaceStencilDepthFailOp, BlockType.DepthStencil, ShaderVariableType.UInt, 1, 1, false),
  1959.                                     new LeftHandSideValue(LeftHandSideValueType.FrontFaceStencilPassOp, BlockType.DepthStencil, ShaderVariableType.UInt, 1, 1, false),
  1960.                                     new LeftHandSideValue(LeftHandSideValueType.FrontFaceStencilFunc, BlockType.DepthStencil, ShaderVariableType.UInt, 1, 1, false),
  1961.                                     new LeftHandSideValue(LeftHandSideValueType.BackFaceStencilFailOp, BlockType.DepthStencil, ShaderVariableType.UInt, 1, 1, false),
  1962.                                     new LeftHandSideValue(LeftHandSideValueType.BackFaceStencilDepthFailOp, BlockType.DepthStencil, ShaderVariableType.UInt, 1, 1, false),
  1963.                                     new LeftHandSideValue(LeftHandSideValueType.BackFaceStencilPassOp, BlockType.DepthStencil, ShaderVariableType.UInt, 1, 1, false),
  1964.                                     new LeftHandSideValue(LeftHandSideValueType.BackFaceStencilFunc, BlockType.DepthStencil, ShaderVariableType.UInt, 1, 1, false),
  1965.                                     new LeftHandSideValue(LeftHandSideValueType.AlphaToCoverage, BlockType.Blend, ShaderVariableType.Bool, 1, 1, false),
  1966.                                     new LeftHandSideValue(LeftHandSideValueType.BlendEnable, BlockType.Blend, ShaderVariableType.Bool, 1, 8, false),
  1967.                                     new LeftHandSideValue(LeftHandSideValueType.SrcBlend, BlockType.Blend, ShaderVariableType.UInt, 1, 8, true),
  1968.                                     new LeftHandSideValue(LeftHandSideValueType.DestBlend, BlockType.Blend, ShaderVariableType.UInt, 1, 8, true),
  1969.                                     new LeftHandSideValue(LeftHandSideValueType.BlendOp, BlockType.Blend, ShaderVariableType.UInt, 1, 8, true),
  1970.                                     new LeftHandSideValue(LeftHandSideValueType.SrcBlendAlpha, BlockType.Blend, ShaderVariableType.UInt, 1, 8, true),
  1971.                                     new LeftHandSideValue(LeftHandSideValueType.DestBlendAlpha, BlockType.Blend, ShaderVariableType.UInt, 1, 8, true),
  1972.                                     new LeftHandSideValue(LeftHandSideValueType.BlendOpAlpha, BlockType.Blend, ShaderVariableType.UInt, 1, 8, true),
  1973.                                     new LeftHandSideValue(LeftHandSideValueType.RenderTargetWriteMask, BlockType.Blend, ShaderVariableType.UInt8, 1, 8, false),
  1974.                                     new LeftHandSideValue(LeftHandSideValueType.Filter, BlockType.Sampler, ShaderVariableType.UInt, 1, 1, false),
  1975.                                     new LeftHandSideValue(LeftHandSideValueType.AddressU, BlockType.Sampler, ShaderVariableType.UInt, 1, 1, false),
  1976.                                     new LeftHandSideValue(LeftHandSideValueType.AddressV, BlockType.Sampler, ShaderVariableType.UInt, 1, 1, false),
  1977.                                     new LeftHandSideValue(LeftHandSideValueType.AddressW, BlockType.Sampler, ShaderVariableType.UInt, 1, 1, false),
  1978.                                     new LeftHandSideValue(LeftHandSideValueType.MipLODBias, BlockType.Sampler, ShaderVariableType.Float, 1, 1, false),
  1979.                                     new LeftHandSideValue(LeftHandSideValueType.MaxAnisotropy, BlockType.Sampler, ShaderVariableType.UInt, 1, 1, false),
  1980.                                     new LeftHandSideValue(LeftHandSideValueType.ComparisonFunc, BlockType.Sampler, ShaderVariableType.UInt, 1, 1, false),
  1981.                                     new LeftHandSideValue(LeftHandSideValueType.BorderColor, BlockType.Sampler, ShaderVariableType.Float, 4, 1, false),
  1982.                                     new LeftHandSideValue(LeftHandSideValueType.MinLOD, BlockType.Sampler, ShaderVariableType.Float, 1, 1, false),
  1983.                                     new LeftHandSideValue(LeftHandSideValueType.MaxLOD, BlockType.Sampler, ShaderVariableType.Float, 1, 1, false),
  1984.                                     new LeftHandSideValue(LeftHandSideValueType.Texture, BlockType.Sampler, ShaderVariableType.Texture, 1, 1, false),
  1985.                                     new LeftHandSideValue(LeftHandSideValueType.HullShaderBlock, BlockType.Pass, ShaderVariableType.Hullshader, 1, 1, false),
  1986.                                     new LeftHandSideValue(LeftHandSideValueType.DomainShaderBlock, BlockType.Pass, ShaderVariableType.Domainshader, 1, 1, false),
  1987.                                     new LeftHandSideValue(LeftHandSideValueType.ComputeShaderBlock, BlockType.Pass, ShaderVariableType.Computeshader, 1, 1, false),
  1988.                                                               };
  1989.  
  1990.         #endregion
  1991.     }
  1992. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement