示例#1
0
        /// <summary>
        /// Split instructions into seperate phases.
        /// </summary>
        /// <param name="programChunk"></param>
        static void ParseShaderChunk(IrShader shader, ShaderProgramChunk programChunk)
        {
            Func <OpcodeToken, int, bool> NotSplitToken = (OpcodeToken token, int index) =>
                                                          index == 0 ||
                                                          token.Header.OpcodeType != OpcodeType.HsForkPhase &&
                                                          token.Header.OpcodeType != OpcodeType.HsJoinPhase &&
                                                          token.Header.OpcodeType != OpcodeType.Label;
            int i = 0;

            while (i < programChunk.Tokens.Count)
            {
                var tokens = programChunk.Tokens.Skip(i).TakeWhile(NotSplitToken).ToList();
                if (i == 0)
                {
                    var type = programChunk.Version.ProgramType.GetPassType();
                    var pass = new IrPass(tokens, programChunk.Version.ProgramType.ToString(), type);
                    InstructionParser.ParseTokens(pass, tokens);
                    pass.InputSignature  = shader.Signatures.First(s => s.SignatureType == IrSignatureType.Input);
                    pass.OutputSignature = shader.Signatures.First(s => s.SignatureType == IrSignatureType.Output);
                    shader.Passes.Add(pass);
                }
                else if (tokens[0].Header.OpcodeType == OpcodeType.Label)
                {
                    var index = (tokens[0] as InstructionToken).Operands[0].Indices[0].Value;
                    var pass  = new IrPass($"Label{index}", IrPass.PassType.FunctionBody);
                    InstructionParser.ParseTokens(pass, tokens);
                    shader.Passes.Add(pass);
                }
                else if (tokens[0].Header.OpcodeType == OpcodeType.HsForkPhase)
                {
                    var index = shader.Passes.Select(p => p.Type == IrPass.PassType.HullShaderForkPhase).Count();
                    var pass  = new IrPass($"HullForkPhase{index}", IrPass.PassType.HullShaderForkPhase);
                    InstructionParser.ParseTokens(pass, tokens);
                    shader.Passes.Add(pass);
                }
                else
                {
                    var index = shader.Passes.Select(p => p.Type == IrPass.PassType.HullShaderJoinPhase).Count();
                    var pass  = new IrPass(tokens, $"HullJoinPhase{index}", IrPass.PassType.HullShaderJoinPhase);
                    InstructionParser.ParseTokens(pass, tokens);
                    shader.Passes.Add(pass);
                }
                i += tokens.Count;
            }
            shader.InterfaceManger?.Parse(shader, programChunk.Container);
            if (programChunk.Version.ProgramType == ProgramType.HullShader)
            {
                string patchConstantPassName = "HullPatchConstant";
                shader.Passes.Add(new IrPass("HullPatchConstant", IrPass.PassType.HullShaderPatchConstantPhase));
                var ctrlPointPass = shader.Passes.First(p => p.Type == IrPass.PassType.HullShaderControlPointPhase);
                ctrlPointPass.Attributes.Add(IrAttribute.Create("patchconstantfunc", patchConstantPassName));
            }
        }
示例#2
0
        public static BytecodeChunk ParseChunk(BytecodeReader chunkReader, BytecodeContainer container)
        {
            // Type of chunk this is.
            uint fourCc = chunkReader.ReadUInt32();

            // Total length of the chunk in bytes.
            uint chunkSize = chunkReader.ReadUInt32();

            ChunkType chunkType;

            if (KnownChunkTypes.ContainsKey(fourCc))
            {
                chunkType = KnownChunkTypes[fourCc];
            }
            else
            {
                System.Diagnostics.Debug.Assert(false, "Chunk type '" + fourCc.ToFourCcString() + "' is not yet supported.");
                System.Diagnostics.Debug.WriteLine("Chunk type '" + fourCc.ToFourCcString() + "' is not yet supported.");
                return(null);
            }

            var           chunkContentReader = chunkReader.CopyAtCurrentPosition((int)chunkSize);
            BytecodeChunk chunk;

            switch (chunkType)
            {
            case ChunkType.Ifce:
                chunk = InterfacesChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Isgn:
            case ChunkType.Osgn:
            case ChunkType.Osg5:
            case ChunkType.Pcsg:
            case ChunkType.Isg1:
            case ChunkType.Osg1:
                chunk = InputOutputSignatureChunk.Parse(chunkContentReader, chunkType,
                                                        container.Version.ProgramType);
                break;

            case ChunkType.Rdef:
                chunk = ResourceDefinitionChunk.Parse(chunkContentReader);
                break;

            case ChunkType.Sdbg:
            case ChunkType.Spdb:
                chunk = DebuggingChunk.Parse(chunkContentReader, chunkType, chunkSize);
                break;

            case ChunkType.Sfi0:
                chunk = Sfi0Chunk.Parse(chunkContentReader, container.Version, chunkSize);
                break;

            case ChunkType.Shdr:
            case ChunkType.Shex:
                chunk = ShaderProgramChunk.Parse(chunkContentReader);
                break;

            case ChunkType.Stat:
                chunk = StatisticsChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Xnas:
            case ChunkType.Xnap:
            case ChunkType.Aon9:
                chunk = Level9ShaderChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Priv:
                chunk = PrivateChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Rts0:
                chunk = RootSignatureChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Libf:
                chunk = LibfChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Libh:
                chunk = LibHeaderChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Lfs0:
                chunk = LibraryParameterSignatureChunk.Parse(chunkContentReader, chunkSize);
                break;

            default:
                throw new ParseException("Invalid chunk type: " + chunkType);
            }

            chunk.Container = container;
            chunk.FourCc    = fourCc;
            chunk.ChunkSize = chunkSize;
            chunk.ChunkType = chunkType;

            return(chunk);
        }
示例#3
0
        public static RequiredRegisters FromShader(ShaderProgramChunk shader)
        {
            var result = new RequiredRegisters();

            foreach (var declarationToken in shader.DeclarationTokens)
            {
                OperandIndex[] indices = (declarationToken.Operand != null)
                                        ? declarationToken.Operand.Indices
                                        : new OperandIndex[0];
                var indexDimension = (declarationToken.Operand != null)
                                        ? declarationToken.Operand.IndexDimension
                                        : OperandIndexDimension._0D;
                switch (declarationToken.Header.OpcodeType)
                {
                case OpcodeType.DclInput:
                case OpcodeType.DclInputPs:
                case OpcodeType.DclInputPsSgv:
                case OpcodeType.DclInputPsSiv:
                case OpcodeType.DclInputSgv:
                case OpcodeType.DclInputSiv:
                    switch (indexDimension)
                    {
                    case OperandIndexDimension._2D:
                        result.NumPrimitives = (int)indices[0].Value;
                        result.Inputs        = Math.Max(result.Inputs, (int)indices[1].Value + 1);
                        break;

                    case OperandIndexDimension._1D:
                        result.NumPrimitives = 1;
                        result.Inputs        = (int)indices[0].Value + 1;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    break;

                case OpcodeType.DclOutput:
                case OpcodeType.DclOutputSgv:
                case OpcodeType.DclOutputSiv:
                    result.Outputs = (int)indices[0].Value + 1;
                    break;

                case OpcodeType.DclResource:
                    result.Resources.Add(((ResourceDeclarationToken)declarationToken).ResourceDimension);
                    break;

                case OpcodeType.DclSampler:
                    result.Samplers = (int)indices[0].Value + 1;
                    break;

                case OpcodeType.DclConstantBuffer:
                    while (result.ConstantBuffers.Count < (int)indices[0].Value + 1)
                    {
                        result.ConstantBuffers.Add(0);
                    }
                    result.ConstantBuffers[(int)indices[0].Value] = (int)indices[1].Value;
                    break;

                case OpcodeType.DclIndexableTemp:
                    while (result.IndexableTemps.Count < (int)indices[0].Value + 1)
                    {
                        result.IndexableTemps.Add(0);
                    }
                    result.IndexableTemps[(int)indices[0].Value] = (int)indices[1].Value + 1;
                    break;

                case OpcodeType.DclTemps:
                    result.Temps = (int)((TempRegisterDeclarationToken)declarationToken).TempCount;
                    break;
                }
            }

            return(result);
        }