public static ShaderProgramChunk Parse(BytecodeReader reader) { var program = new ShaderProgramChunk { Version = ShaderVersion.ParseShex(reader), // Length Token (LenTok) // Always follows VerTok // [31:00] Unsigned integer count of number of DWORDs in program code, including version and length tokens. // So the minimum value is 0x00000002 (if an empty program is ever valid). Length = reader.ReadUInt32() }; while (!reader.EndOfBuffer) { // Opcode Format (OpcodeToken0) // // [10:00] D3D10_SB_OPCODE_TYPE // if( [10:00] == D3D10_SB_OPCODE_CUSTOMDATA ) // { // Token starts a custom-data block. See "Custom-Data Block Format". // } // else // standard opcode token // { // [23:11] Opcode-Specific Controls // [30:24] Instruction length in DWORDs including the opcode token. // [31] 0 normally. 1 if extended operand definition, meaning next DWORD // contains extended opcode token. // } var opcodeHeaderReader = reader.CopyAtCurrentPosition(); var opcodeToken0 = opcodeHeaderReader.ReadUInt32(); var opcodeHeader = new OpcodeHeader { OpcodeType = opcodeToken0.DecodeValue <OpcodeType>(0, 10), Length = opcodeToken0.DecodeValue(24, 30), IsExtended = (opcodeToken0.DecodeValue(31, 31) == 1) }; OpcodeToken opcodeToken; if (opcodeHeader.OpcodeType == OpcodeType.CustomData) { opcodeToken = CustomDataToken.Parse(reader, opcodeToken0); } else if (opcodeHeader.OpcodeType.IsDeclaration()) { opcodeToken = DeclarationToken.Parse(reader, opcodeHeader.OpcodeType); } else // Not custom data or declaration, so must be instruction. { opcodeToken = InstructionToken.Parse(reader, opcodeHeader); } opcodeToken.Header = opcodeHeader; program.Tokens.Add(opcodeToken); } program.LinkControlFlowInstructions(); return(program); }
public static ShaderProgramChunk Parse(BytecodeReader reader) { var program = new ShaderProgramChunk { Version = ShaderVersion.ParseShex(reader), // Length Token (LenTok) // Always follows VerTok // [31:00] Unsigned integer count of number of DWORDs in program code, including version and length tokens. // So the minimum value is 0x00000002 (if an empty program is ever valid). Length = reader.ReadUInt32() }; while (!reader.EndOfBuffer) { // Opcode Format (OpcodeToken0) // // [10:00] D3D10_SB_OPCODE_TYPE // if( [10:00] == D3D10_SB_OPCODE_CUSTOMDATA ) // { // Token starts a custom-data block. See "Custom-Data Block Format". // } // else // standard opcode token // { // [23:11] Opcode-Specific Controls // [30:24] Instruction length in DWORDs including the opcode token. // [31] 0 normally. 1 if extended operand definition, meaning next DWORD // contains extended opcode token. // } var opcodeHeaderReader = reader.CopyAtCurrentPosition(); var opcodeToken0 = opcodeHeaderReader.ReadUInt32(); var opcodeHeader = new OpcodeHeader { OpcodeType = opcodeToken0.DecodeValue<OpcodeType>(0, 10), Length = opcodeToken0.DecodeValue(24, 30), IsExtended = (opcodeToken0.DecodeValue(31, 31) == 1) }; OpcodeToken opcodeToken; if (opcodeHeader.OpcodeType == OpcodeType.CustomData) { opcodeToken = CustomDataToken.Parse(reader, opcodeToken0); } else if (opcodeHeader.OpcodeType.IsDeclaration()) { opcodeToken = DeclarationToken.Parse(reader, opcodeHeader.OpcodeType); } else // Not custom data or declaration, so must be instruction. { opcodeToken = InstructionToken.Parse(reader, opcodeHeader); } opcodeToken.Header = opcodeHeader; program.Tokens.Add(opcodeToken); } program.LinkControlFlowInstructions(); return program; }
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; }