internal void Write(EndianWriter writer)
        {
            foreach (VariableHeader header in m_variableHeaders)
            {
                WriteVariableHeader(writer, header);
            }
            foreach (Variable variable in m_variables)
            {
                writer.WriteStringZeroTerm(variable.Name);
                WriteShaderType(writer, variable.ShaderType);

                foreach (ShaderTypeMember member in variable.ShaderType.Members)
                {
                    uint nameOffset = m_variableNameLookup[member.Name];
                    writer.Write(nameOffset);
                    uint memberOffset = m_typeLookup[member.ShaderType];
                    writer.Write(memberOffset);
                    writer.Write(member.Index);
                }
                foreach (ShaderTypeMember member in variable.ShaderType.Members)
                {
                    writer.WriteStringZeroTerm(member.Name);
                    WriteShaderType(writer, member.ShaderType);
                }
            }
        }
Esempio n. 2
0
        internal void Write(EndianWriter writer)
        {
            foreach (var header in variableHeaders)
            {
                WriteVariableHeader(writer, header);
            }
            foreach (var variable in variables)
            {
                writer.WriteStringZeroTerm(variable.Name);
                WriteShaderType(writer, variable.ShaderType);

                foreach (var member in variable.ShaderType.members)
                {
                    var nameOffset = variableNameLookup[member.Name];
                    writer.Write(nameOffset);
                    var memberOffset = typeLookup[member.ShaderType];
                    writer.Write(memberOffset);
                    writer.Write(member.Index);
                }
                foreach (var member in variable.ShaderType.members)
                {
                    writer.WriteStringZeroTerm(member.Name);
                    WriteShaderType(writer, member.ShaderType);
                }
            }
        }
        public void Write(EndianWriter writer)
        {
            writer.Write(Encoding.ASCII.GetBytes("RDEF"));
            writer.Write(m_chunkSize);
            writer.Write(m_constantBuffers.Count);
            writer.Write(m_constantBufferOffset);
            writer.Write(m_resourceBindings.Count);
            writer.Write(m_resourceBindingOffset);
            byte minorVersion = 0;

            writer.Write(minorVersion);
            writer.Write(m_majorVersion);
            writer.Write((ushort)m_programType);
            var flags = ShaderFlags.NoPreshader;

            writer.Write((uint)flags);
            writer.Write(m_creatorStringOffset);
            if (m_majorVersion >= 5)
            {
                //rd11
                writer.Write(Encoding.ASCII.GetBytes("RD11"));
                //unknown1
                writer.Write((uint)60);
                //unknown2
                writer.Write((uint)24);
                //unknown3
                writer.Write((uint)32);
                //unknown4
                writer.Write((uint)40);
                //unknown5
                writer.Write((uint)36);
                //unknown6
                writer.Write((uint)12);
                //InterfaceSlotCount
                writer.Write((uint)0);
            }
            m_resourceBindings.Write(writer);
            m_constantBuffers.Write(writer);
            writer.WriteStringZeroTerm(m_creatorString);
        }
Esempio n. 4
0
        internal void Write(EndianWriter writer)
        {
            uint bindPoint = 0;

            foreach (var bufferParam in shaderSubprogram.BufferParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(nameLookup[bufferParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Structured);
                //Resource return type
                writer.Write((uint)ResourceReturnType.Mixed);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Buffer);
                //Number of samples
                writer.Write((uint)56);                 //TODO: Check this
                //Bind point
                writer.Write((uint)bufferParam.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }
            bindPoint = 0;
            foreach (var textureParam in shaderSubprogram.TextureParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(nameLookup[textureParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Sampler);
                //Resource return type
                writer.Write((uint)ResourceReturnType.NotApplicable);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Unknown);
                //Number of samples
                writer.Write((uint)0);
                //Bind point
                writer.Write((uint)textureParam.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }
            bindPoint = 0;
            foreach (var textureParam in shaderSubprogram.TextureParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(nameLookup[textureParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Texture);
                //Resource return type
                writer.Write((uint)ResourceReturnType.NotApplicable);
                //Resource view dimension
                writer.Write((uint)textureParam.Dim);
                //Number of samples
                writer.Write(uint.MaxValue);
                //Bind point
                writer.Write((uint)textureParam.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }
            bindPoint = 0;
            foreach (var constantBuffer in shaderSubprogram.ConstantBufferBindings)
            {
                //Resource bindings
                //nameOffset
                writer.Write(nameLookup[constantBuffer.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.CBuffer);
                //Resource return type
                writer.Write((uint)ResourceReturnType.NotApplicable);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Unknown);
                //Number of samples
                writer.Write((uint)0);
                //Bind point
                writer.Write((uint)constantBuffer.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }

            foreach (var bufferParam in shaderSubprogram.BufferParameters)
            {
                writer.WriteStringZeroTerm(bufferParam.Name);
            }
            foreach (var textureParam in shaderSubprogram.TextureParameters)
            {
                writer.WriteStringZeroTerm(textureParam.Name);
            }
            foreach (var constantBuffer in shaderSubprogram.ConstantBufferBindings)
            {
                writer.WriteStringZeroTerm(constantBuffer.Name);
            }
        }
Esempio n. 5
0
        internal void Write(EndianWriter writer)
        {
            uint bindPoint = 0;

            foreach (BufferBinding bufferParam in m_shaderSubprogram.BufferParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(m_nameLookup[bufferParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Structured);
                //Resource return type
                writer.Write((uint)ResourceReturnType.Mixed);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Buffer);
                //Number of samples
                writer.Write((uint)56);                 //TODO: Check this
                //Bind point
                writer.Write((uint)bufferParam.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }
            //Unity doesn't give us a good way of reconstructing the sampler header,
            //this is probably wrong but good enough
            bindPoint = 0;
            foreach (TextureParameter textureParam in m_shaderSubprogram.TextureParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(m_nameLookup[textureParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Sampler);
                //Resource return type
                writer.Write((uint)ResourceReturnType.NotApplicable);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Unknown);
                //Number of samples
                writer.Write((uint)0);
                //Bind point
                writer.Write((uint)textureParam.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }
            bindPoint = 0;
            foreach (TextureParameter textureParam in m_shaderSubprogram.TextureParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(m_nameLookup[textureParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Texture);
                //Resource return type
                writer.Write((uint)ResourceReturnType.Float);
                //Resource view dimension
                writer.Write((uint)GetTextureDimension(textureParam));
                //Number of samples
                writer.Write(uint.MaxValue);
                //Bind point
                writer.Write((uint)textureParam.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.TextureComponents);
            }
            bindPoint = 0;
            foreach (BufferBinding constantBuffer in m_shaderSubprogram.ConstantBufferBindings)
            {
                //Resource bindings
                //nameOffset
                writer.Write(m_nameLookup[constantBuffer.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.CBuffer);
                //Resource return type
                writer.Write((uint)ResourceReturnType.NotApplicable);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Unknown);
                //Number of samples
                writer.Write((uint)0);
                //Bind point
                writer.Write((uint)constantBuffer.Index);
                bindPoint += 1;
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }

            foreach (BufferBinding bufferParam in m_shaderSubprogram.BufferParameters)
            {
                writer.WriteStringZeroTerm(bufferParam.Name);
            }
            foreach (TextureParameter textureParam in m_shaderSubprogram.TextureParameters)
            {
                writer.WriteStringZeroTerm(textureParam.Name);
            }
            foreach (BufferBinding constantBuffer in m_shaderSubprogram.ConstantBufferBindings)
            {
                writer.WriteStringZeroTerm(constantBuffer.Name);
            }
        }
Esempio n. 6
0
        internal void Write(EndianWriter writer)
        {
            foreach (BufferBinding bufferParam in m_shaderSubprogram.BufferParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(m_nameLookup[bufferParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Structured);
                //Resource return type
                writer.Write((uint)ResourceReturnType.Mixed);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Buffer);
                //Number of samples
                writer.Write((uint)56);                 //TODO: Check this
                //Bind point
                writer.Write((uint)bufferParam.Index);
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }
            foreach (Sampler sampler in m_Samplers)
            {
                //Resource bindings
                //nameOffset
                writer.Write(m_nameLookup[sampler.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Sampler);
                //Resource return type
                writer.Write((uint)ResourceReturnType.NotApplicable);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Unknown);
                //Number of samples
                writer.Write((uint)0);
                //Bind point
                writer.Write((uint)sampler.BindPoint);
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                ShaderInputFlags samplerFlags = sampler.IsComparisonSampler ?
                                                ShaderInputFlags.ComparisonSampler : ShaderInputFlags.None;
                writer.Write((uint)samplerFlags);
            }
            foreach (TextureParameter textureParam in m_shaderSubprogram.TextureParameters)
            {
                //Resource bindings
                //nameOffset
                writer.Write(m_nameLookup[textureParam.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.Texture);
                //Resource return type
                writer.Write((uint)ResourceReturnType.Float);
                //Resource view dimension
                writer.Write((uint)GetTextureDimension(textureParam));
                //Number of samples
                writer.Write(uint.MaxValue);
                //Bind point
                writer.Write((uint)textureParam.Index);
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.TextureComponents);
            }
            foreach (BufferBinding constantBuffer in m_shaderSubprogram.ConstantBufferBindings)
            {
                //Resource bindings
                //nameOffset
                writer.Write(m_nameLookup[constantBuffer.Name]);
                //shader input type
                writer.Write((uint)ShaderInputType.CBuffer);
                //Resource return type
                writer.Write((uint)ResourceReturnType.NotApplicable);
                //Resource view dimension
                writer.Write((uint)ShaderResourceViewDimension.Unknown);
                //Number of samples
                writer.Write((uint)0);
                //Bind point
                writer.Write((uint)constantBuffer.Index);
                //Bind count
                writer.Write((uint)1);
                //Shader input flags
                writer.Write((uint)ShaderInputFlags.None);
            }

            foreach (BufferBinding bufferParam in m_shaderSubprogram.BufferParameters)
            {
                writer.WriteStringZeroTerm(bufferParam.Name);
            }
            foreach (TextureParameter textureParam in m_shaderSubprogram.TextureParameters)
            {
                writer.WriteStringZeroTerm(textureParam.Name);
            }
            foreach (Sampler sampler in m_Samplers)
            {
                writer.WriteStringZeroTerm(sampler.Name);
            }
            foreach (BufferBinding constantBuffer in m_shaderSubprogram.ConstantBufferBindings)
            {
                writer.WriteStringZeroTerm(constantBuffer.Name);
            }
        }
        /* Chunk Format
            * byte[4]  ?
            * uint     ?
            * start:                           
            * uint     constantBufferCount     
            * uint     constantBufferOffset    from start
            * uint     resourceBindingCount    
            * uint     resourceBindingOffset   from start
            * uint     target                  
            * uint     flags                   
            * uint     creatorOffset           
            * A[n]     ResourceBindings        size n*8
            * A[n]     ResourceBindingNames    size variable
            * A[n]     ConstantBuffers         
            * strz     createrName             from start
            */
        static byte[] ResourceChunk(ShaderSubProgram shaderSubprogram, uint chunkoffset)
        {
            var memoryStream = new MemoryStream();
            using (var writer = new EndianWriter(memoryStream))
            {
                Dictionary<string, uint> NameLookup = new Dictionary<string, uint>();
                var majorVersion = GetMajorVersion(shaderSubprogram.ProgramType);
                uint startOffset = 0;
                uint headerOffset = majorVersion >= 5 ? (uint)60 : (uint)28;
                uint resourceBindingOffset = startOffset + headerOffset;
                byte[] resourceBindingData = ResourceBindings(shaderSubprogram, resourceBindingOffset, NameLookup);
                uint contantDataOffset = startOffset + headerOffset + (uint)resourceBindingData.Length;
                byte[] contantBufferData = ConstantBuffers(shaderSubprogram, contantDataOffset, NameLookup);
                uint createrStringOffset = contantDataOffset + (uint)contantBufferData.Length;
                string creatorString = "uTinyRipper";

                writer.Write(Encoding.ASCII.GetBytes("RDEF"));
                //Length of chunk
                uint chunkLength = headerOffset + (uint)resourceBindingData.Length + (uint)contantBufferData.Length + (uint)creatorString.Length + 1;
                writer.Write(chunkLength);
                //ConstantBufferCount
                uint contantBufferCount = (uint)shaderSubprogram.ConstantBuffers.Count;
                writer.Write(contantBufferCount);
                //ContantBufferOffset
                writer.Write(contantDataOffset);
                //ResourceBindingCount
                uint resourceBindingCount = GetResourceBindingCount(shaderSubprogram);
                writer.Write(resourceBindingCount);
                //ResourceBindingOffset
                writer.Write(resourceBindingOffset);
                //MinorVersionNumber
                writer.Write((byte)0);
                //MajorVersionNumber
                writer.Write((byte)majorVersion);
                //ProgramType
                writer.Write((ushort)GetDXProgramType(shaderSubprogram.ProgramType));
                //Flags
                writer.Write((uint)ShaderFlags.NoPreshader);
                //creatorOffset
                writer.Write(createrStringOffset);

                if (majorVersion >= 5)
                {
                    //rd11
                    writer.Write(Encoding.ASCII.GetBytes("RD11"));
                    //unknown1
                    writer.Write((uint)60);
                    //unknown2
                    writer.Write((uint)24);
                    //unknown3
                    writer.Write((uint)32);
                    //unknown4
                    writer.Write((uint)40);
                    //unknown5
                    writer.Write((uint)36);
                    //unknown6
                    writer.Write((uint)12);
                    //InterfaceSlotCount
                    writer.Write((uint)0);
                }
                writer.Write(resourceBindingData);
                writer.Write(contantBufferData);
                //Creatorstring
                writer.WriteStringZeroTerm(creatorString);
                return memoryStream.ToArray();
            }
        }
        /* Variable Format
            * uint nameOffset      location of variable name
            * uint startOffset     offset of variable in memory
            * uint size            size of type in memory
            * uint flags
            * uint typeOffset
            * uint defaultValueOffset
            * if sm >= 5
            * uint StartTexture
            * uint TextureSize
            * uint StartSampler
            * uint SamplerSize
            * 
            * Type Format
            * short VariableClass
            * short VariableType
            * short Rows
            * short Columns
            * short ElementCount
            * short memberCount
            * uint memberOffset
            */
        static byte[] BufferVariables(ConstantBuffer constantBuffer, uint contantBufferOffset, List<Variable> variables, int majorVersion)
        {
            var memoryStream = new MemoryStream();
            using (var writer = new EndianWriter(memoryStream))
            {
                var typeLookup = new Dictionary<ShaderType, uint>();
                uint variableSize = majorVersion >= 5 ? (uint)40 : (uint)24;
                uint variableCount = (uint)variables.Count;
                uint dataOffset = contantBufferOffset + variableCount * variableSize;
                uint startOffset = 0;
                var seenTypes = new HashSet<ShaderType>();
                void WriteVariable(Variable variable)
                {
                    //name offset
                    writer.Write(dataOffset);
                    dataOffset += (uint)variable.Name.Length + 1;
                    //startOffset
                    writer.Write(startOffset);
                    startOffset += variable.ShaderType.Size();
                    //Size
                    writer.Write(variable.ShaderType.Size());
                    //flags
                    writer.Write((uint)ShaderVariableFlags.Used); //Unity only packs used variables as far as I can tell

                    var typeOffset = dataOffset;
                    if (typeLookup.ContainsKey(variable.ShaderType))
                    {
                        typeOffset = typeLookup[variable.ShaderType];
                    }
                    else
                    {
                        typeLookup[variable.ShaderType] = dataOffset;
                        dataOffset += variable.ShaderType.Length();
                    }
                    //type offset
                    writer.Write(typeOffset);
                    //default value offset
                    writer.Write((uint)0); //Not used
                    if(majorVersion >= 5)
                    {
                        //TODO
                        //StartTexture
                        writer.Write((uint)0);
                        //TextureSize
                        writer.Write((uint)0);
                        //StartSampler
                        writer.Write((uint)0);
                        //SamplerSize
                        writer.Write((uint)0);
                    }
                }
                void WriteVariableData(Variable variable)
                {
                    writer.WriteStringZeroTerm(variable.Name);
                    if (!seenTypes.Contains(variable.ShaderType))
                    {
                        seenTypes.Add(variable.ShaderType);
                        writer.Write((ushort)variable.ShaderType.ShaderVariableClass);
                        writer.Write((ushort)variable.ShaderType.ShaderVariableType);
                        writer.Write(variable.ShaderType.Rows);
                        writer.Write(variable.ShaderType.Columns);
                        writer.Write(variable.ShaderType.ElementCount);
                        writer.Write(variable.ShaderType.MemberCount);
                        writer.Write(variable.ShaderType.MemberOffset);
                        if(majorVersion >= 5)
                        {
                            if(variable.ShaderType.parentTypeOffset != 0 ||
                               variable.ShaderType.unknown2 != 0 ||
                               variable.ShaderType.unknown5 != 0 ||
                               variable.ShaderType.parentNameOffset != 0)
                            {
                                throw new Exception("Shader variable type has invalid value");
                            }
                            writer.Write(variable.ShaderType.parentTypeOffset);
                            writer.Write(variable.ShaderType.unknown2);
                            writer.Write(variable.ShaderType.unknown4);
                            writer.Write(variable.ShaderType.unknown5);
                            writer.Write(variable.ShaderType.parentNameOffset);
                        }
                    }
                }
                if (constantBuffer.StructParams != null && constantBuffer.StructParams.Count > 0)
                {
                    throw new Exception("Unexpected Struct Params");
                }
                foreach (var variable in variables)
                {
                    WriteVariable(variable);
                }

                foreach (var variable in variables)
                {
                    WriteVariableData(variable);
                }
                return memoryStream.ToArray();
            }
        }
        /* ResourceBindingFormat
            * Size n * 8
            * uint     nameOffset  from start
            * uint     Type
            * uint     ReturnType
            * uint     Dimension
            * uint     NumSamples
            * uint     BindPoint
            * uint     BindCount
            * uint     Flags
            */
        static byte[] ResourceBindings(ShaderSubProgram shaderSubprogram, uint resourceOffset, Dictionary<string, uint> nameLookup)
        {
            var memoryStream = new MemoryStream();
            using (var writer = new EndianWriter(memoryStream))
            {
                var constantBuffers = GetConstantBuffers(shaderSubprogram);
                var bindingCount = GetResourceBindingCount(shaderSubprogram);
                const uint bindingHeaderSize = 32;
                uint nameOffset = resourceOffset + bindingHeaderSize * (uint)bindingCount;
                //Build Name Lookup. TODO: Use name indices
                foreach (var bufferParam in shaderSubprogram.BufferParameters)
                {
                    nameLookup[bufferParam.Name] = nameOffset;
                    nameOffset += (uint)bufferParam.Name.Length + 1;
                }
                foreach (var textureParam in shaderSubprogram.TextureParameters)
                {
                    nameLookup[textureParam.Name] = nameOffset;
                    nameOffset += (uint)textureParam.Name.Length + 1;
                }
                foreach (var constantBuffer in constantBuffers)
                {
                    nameLookup[constantBuffer.Name] = nameOffset;
                    nameOffset += (uint)constantBuffer.Name.Length + 1;
                }

                uint bindPoint = 0;
                foreach (var bufferParam in shaderSubprogram.BufferParameters)
                {
                    //Resource bindings
                    //nameOffset
                    writer.Write(nameLookup[bufferParam.Name]);
                    //shader input type
                    writer.Write((uint)ShaderInputType.Structured);
                    //Resource return type
                    writer.Write((uint)ResourceReturnType.Mixed);
                    //Resource view dimension
                    writer.Write((uint)ShaderResourceViewDimension.Buffer);
                    //Number of samples
                    writer.Write((uint)56); //TODO: Check this
                    //Bind point
                    writer.Write(bindPoint);
                    bindPoint += 1;
                    //Bind count
                    writer.Write((uint)1);
                    //Shader input flags
                    writer.Write((uint)ShaderInputFlags.None);
                }
                bindPoint = 0;
                foreach (var textureParam in shaderSubprogram.TextureParameters)
                {
                    //Resource bindings
                    //nameOffset
                    writer.Write(nameLookup[textureParam.Name]);
                    //shader input type
                    writer.Write((uint)ShaderInputType.Sampler);
                    //Resource return type
                    writer.Write((uint)ResourceReturnType.NotApplicable);
                    //Resource view dimension
                    writer.Write((uint)ShaderResourceViewDimension.Unknown);
                    //Number of samples
                    writer.Write((uint)0);
                    //Bind point
                    writer.Write(bindPoint);
                    bindPoint += 1;
                    //Bind count
                    writer.Write((uint)1);
                    //Shader input flags
                    writer.Write((uint)ShaderInputFlags.None);
                }
                bindPoint = 0;
                foreach (var textureParam in shaderSubprogram.TextureParameters)
                {
                    //Resource bindings
                    //nameOffset
                    writer.Write(nameLookup[textureParam.Name]);
                    //shader input type
                    writer.Write((uint)ShaderInputType.Texture);
                    //Resource return type
                    writer.Write((uint)ResourceReturnType.NotApplicable);
                    //Resource view dimension
                    //TODO: look into this
                    var viewDimension = textureParam.Dim == 5 ? ShaderResourceViewDimension.Texture2DArray : ShaderResourceViewDimension.Unknown;
                    writer.Write((uint)viewDimension);
                    //Number of samples
                    writer.Write(uint.MaxValue);
                    //Bind point
                    writer.Write(bindPoint);
                    bindPoint += 1;
                    //Bind count
                    writer.Write((uint)1);
                    //Shader input flags
                    writer.Write((uint)ShaderInputFlags.None);
                }
                bindPoint = 0;
                foreach (var constantBuffer in constantBuffers)
                {
                    //Resource bindings
                    //nameOffset
                    writer.Write(nameLookup[constantBuffer.Name]);
                    //shader input type
                    writer.Write((uint)ShaderInputType.CBuffer);
                    //Resource return type
                    writer.Write((uint)ResourceReturnType.NotApplicable);
                    //Resource view dimension
                    writer.Write((uint)ShaderResourceViewDimension.Unknown);
                    //Number of samples
                    writer.Write((uint)0);
                    //Bind point
                    writer.Write(bindPoint);
                    bindPoint += 1;
                    //Bind count
                    writer.Write((uint)1);
                    //Shader input flags
                    writer.Write((uint)ShaderInputFlags.None);
                }
                foreach (var textureParam in shaderSubprogram.TextureParameters)
                {
                    writer.WriteStringZeroTerm(textureParam.Name);
                }
                foreach (var constantBuffer in constantBuffers)
                {
                    writer.WriteStringZeroTerm(constantBuffer.Name);
                }
                return memoryStream.ToArray();
            }
        }