public static DebugLibraryParameterDescription Parse(DebugBytecodeReader reader, DebugBytecodeReader paramReader) { var nameOffset = paramReader.ReadUInt32("NameOffset"); var semanticNameOffset = paramReader.ReadUInt32("SemanticNameOffset"); var result = new DebugLibraryParameterDescription() { VariableType = paramReader.ReadEnum32 <ShaderVariableType>("VariableType"), VariableClass = paramReader.ReadEnum32 <ShaderVariableClass>("VariableClass"), Rows = paramReader.ReadUInt32("Rows"), Column = paramReader.ReadUInt32("Column"), InterpolationMode = paramReader.ReadEnum32 <InterpolationMode>("InterpolationMode"), Flags = paramReader.ReadEnum32 <ParameterFlags>("Flags"), FirstInRegister = paramReader.ReadUInt32("FirstInRegister"), FirstInComponent = paramReader.ReadUInt32("FirstInComponent"), FirstOutRegister = paramReader.ReadUInt32("FirstOutRegister"), FirstOutComponent = paramReader.ReadUInt32("FirstOutComponent"), }; var nameReader = reader.CopyAtOffset("NameReader", paramReader, (int)nameOffset); result.Name = nameReader.ReadString("Name"); if (semanticNameOffset != 0) { var semanticNameReader = reader.CopyAtOffset("SemanticNameReader", paramReader, (int)semanticNameOffset); result.SemanticName = semanticNameReader.ReadString("SemanticName"); } else { result.SemanticName = ""; } return(result); }
public static DebugStateBlob Parse(DebugBytecodeReader reader, DebugBytecodeReader blobReader) { var result = new DebugStateBlob(); result.TechniqueIndex = blobReader.ReadUInt32("TechniqueIndex"); result.PassIndex = blobReader.ReadUInt32("PassIndex"); result.SamplerStateIndex = blobReader.ReadUInt32("SamplerStateIndex"); result.AssignmentIndex = blobReader.ReadUInt32("AssignmentIndex"); result.BlobType = blobReader.ReadEnum32 <StateBlobType>("BlobType"); if (result.BlobType == StateBlobType.Shader) { result.ShaderSize = blobReader.ReadUInt32("BlobSize"); var startPosition = blobReader._reader.BaseStream.Position; var shaderReader = blobReader.CopyAtCurrentPosition("ShaderReader", blobReader); result.Shader = DebugShaderModel.Parse(shaderReader); blobReader._reader.BaseStream.Position = startPosition + result.ShaderSize; } if (result.BlobType == StateBlobType.Variable) { result.VariableName = blobReader.TryReadString("VariableName"); } else if (result.BlobType == StateBlobType.IndexShader) { result.ShaderSize = blobReader.ReadUInt32("BlobSize"); var startPosition = blobReader._reader.BaseStream.Position; var variableSize = blobReader.ReadUInt32("VariableNameSize"); var variableData = blobReader.ReadBytes("VariableData", (int)variableSize); result.VariableName = Encoding.UTF8.GetString(variableData, 0, variableData.Length - 1); var shaderReader = blobReader.CopyAtCurrentPosition("ShaderReader", blobReader); result.Shader = DebugShaderModel.Parse(shaderReader); blobReader._reader.BaseStream.Position = startPosition + result.ShaderSize; } return(result); }
public static DebugShaderMessageDeclarationToken Parse(DebugBytecodeReader reader) { var token0 = reader.ReadUInt32("token0"); DebugOpcodeHeader.AddNotes(reader, token0); var member = reader.LocalMembers.Last(); var length = reader.ReadUInt32("length") - 2; var result = new DebugShaderMessageDeclarationToken { DeclarationLength = length, InfoQueueMessageID = reader.ReadUInt32("InfoQueueMessageID"), MessageFormat = reader.ReadEnum32 <ShaderMessageFormat>("MessageFormat"), NumCharacters = reader.ReadUInt32("NumCharacters"), NumOperands = reader.ReadUInt32("NumOperands"), OperandsLength = reader.ReadUInt32("OperandsLength") }; for (int i = 0; i < result.NumOperands; i++) { result.Operands.Add(DebugOperand.Parse(reader, OpcodeType.CustomData)); } result.Format = reader.ReadString("Format"); // String is padded to a multiple of DWORDs. uint remainingBytes = (4 - ((result.NumCharacters + 1) % 4)) % 4; reader.ReadBytes("StringPadding", (int)remainingBytes); return(result); }
internal static DebugShaderVariable Parse(DebugBytecodeReader reader, DebugBytecodeReader variableReader, DebugShaderVersion target, bool isFirst) { uint nameOffset = variableReader.ReadUInt32("nameOffset"); var nameReader = reader.CopyAtOffset("nameReader", variableReader, (int)nameOffset); var name = nameReader.ReadString("name"); var startOffset = variableReader.ReadUInt32("startOffset"); uint size = variableReader.ReadUInt32("size"); var flags = variableReader.ReadEnum32 <ShaderVariableFlags>("flags"); var typeOffset = variableReader.ReadUInt32("typeOffset"); var typeReader = reader.CopyAtOffset("typeReader", variableReader, (int)typeOffset); var shaderType = DebugShaderType.Parse(reader, typeReader, target, 2, isFirst, startOffset); var defaultValueOffset = variableReader.ReadUInt32("defaultValueOffset"); List <Number> defaultValue = null; if (defaultValueOffset != 0) { defaultValue = new List <Number>(); var defaultValueReader = reader.CopyAtOffset("defaultValueReader", variableReader, (int)defaultValueOffset); if (size % 4 != 0) { throw new ParseException("Can only deal with 4-byte default values at the moment."); } for (int i = 0; i < size; i += 4) { defaultValue.Add(new Number(defaultValueReader.ReadBytes($"defaultValue{i}", 4))); } } var result = new DebugShaderVariable { DefaultValue = defaultValue, Member = new DebugShaderTypeMember(0) { Name = name, Offset = startOffset, Type = shaderType }, BaseType = name, Size = size, Flags = flags }; if (target.MajorVersion >= 5 || target.ProgramType == ProgramType.LibraryShader) { result.StartTexture = variableReader.ReadInt32("startTexture"); result.TextureSize = variableReader.ReadInt32("textureSize"); result.StartSampler = variableReader.ReadInt32("startSampler"); result.SamplerSize = variableReader.ReadInt32("samplerSize"); } return(result); }
public static DebugParameter Parse(DebugBytecodeReader reader, DebugBytecodeReader variableReader) { var result = new DebugParameter(); result.ParameterType = variableReader.ReadEnum32 <ParameterType>("ParameterType"); result.ParameterClass = variableReader.ReadEnum32 <ParameterClass>("ParameterClass"); result.NameOffset = variableReader.ReadUInt32("NameOffset"); var nameReader = reader.CopyAtOffset("NameReader", variableReader, (int)result.NameOffset); result.Name = nameReader.TryReadString("Name"); result.SemanticOffset = variableReader.ReadUInt32("SemanticOffset"); var semanticReader = reader.CopyAtOffset("SemanticReader", variableReader, (int)result.SemanticOffset); result.Semantic = semanticReader.TryReadString("Semantic"); if (result.ParameterClass == ParameterClass.Scalar || result.ParameterClass == ParameterClass.Vector || result.ParameterClass == ParameterClass.MatrixRows || result.ParameterClass == ParameterClass.MatrixColumns) { result.Elements = variableReader.ReadUInt32("ElementCount"); result.Rows = variableReader.ReadUInt32("Rows"); result.Columns = variableReader.ReadUInt32("Columns"); } if (result.ParameterClass == ParameterClass.Struct) { result.Elements = variableReader.ReadUInt32("ElementCount"); result.StructMemberCount = variableReader.ReadUInt32("StructMemberCount"); for (int i = 0; i < result.StructMemberCount; i++) { result.StructMembers.Add(DebugParameter.Parse(reader, variableReader)); } } if (result.ParameterClass == ParameterClass.Object) { result.Elements = variableReader.ReadUInt32("Elements"); } return(result); }
public static DebugSfi0Chunk Parse(DebugBytecodeReader reader, DebugShaderVersion version, uint chunkSize) { var result = new DebugSfi0Chunk(); var flags = reader.ReadEnum32 <ShaderRequiresFlags>("flags"); result.Flags = flags; result._version = version; var unknown = reader.ReadUInt32("Sfi0Unknown0"); return(result); }
public static DebugAssignment Parse(DebugBytecodeReader reader, DebugBytecodeReader assignmentReader) { var result = new DebugAssignment(); result.Type = assignmentReader.ReadEnum32 <StateType>("Type"); result.ArrayIndex = assignmentReader.ReadUInt32("ArrayIndex"); result.TypeOffset = assignmentReader.ReadUInt32("TypeOffset"); result.ValueOffset = assignmentReader.ReadUInt32("ValueOffset"); var variableReader = reader.CopyAtOffset("AssignmentTypeReader", assignmentReader, (int)result.TypeOffset); result.Parameter = DebugParameter.Parse(reader, variableReader); var valueReader = reader.CopyAtOffset("ValueReader", assignmentReader, (int)result.ValueOffset); result.Value = result.Parameter.ReadParameterValue(valueReader); return(result); }
public static DebugFxlcOperand Parse(DebugBytecodeReader reader, uint componentCount) { var result = new DebugFxlcOperand() { ComponentCount = componentCount, IsArray = reader.ReadUInt32("IsArray"), OpType = reader.ReadEnum32 <FxlcOperandType>("OpType"), OpIndex = reader.ReadUInt32("OpIndex"), }; Debug.Assert(Enum.IsDefined(typeof(FxlcOperandType), result.OpType), $"Unexpected FxlcOperandType OpType {result.OpType}"); if (result.IsArray == 1) { result.ArrayType = (FxlcOperandType)reader.ReadUInt32("ArrayType"); result.ArrayIndex = reader.ReadUInt32("ArrayIndex"); Debug.Assert(Enum.IsDefined(typeof(FxlcOperandType), result.ArrayType), $"Unexpected FxlcOperandType ArrayType {result.ArrayType}"); } return(result); }
public static DebugBytecodeChunk Parse(DebugBytecodeReader reader, uint chunkSize) { var size = chunkSize / sizeof(uint); var magic = reader.PeekUInt32Ahead(8); if (magic == "DXIL".ToFourCc()) { return(Dxil.DebugDxilReflectionChunk.Parse(reader, chunkSize)); } var result = new DebugStatisticsChunk { InstructionCount = reader.ReadUInt32("InstructionCount"), TempRegisterCount = reader.ReadUInt32("TempRegisterCount"), DefineCount = reader.ReadUInt32("DefineCount"), DeclarationCount = reader.ReadUInt32("DeclarationCount"), FloatInstructionCount = reader.ReadUInt32("FloatInstructionCount"), IntInstructionCount = reader.ReadUInt32("IntInstructionCount"), UIntInstructionCount = reader.ReadUInt32("UIntInstructionCount"), StaticFlowControlCount = reader.ReadUInt32("StaticFlowControlCount"), DynamicFlowControlCount = reader.ReadUInt32("DynamicFlowControlCount"), MacroInstructionCount = reader.ReadUInt32("MacroInstructionCount"), // Guessed TempArrayCount = reader.ReadUInt32("TempArrayCount"), ArrayInstructionCount = reader.ReadUInt32("ArrayInstructionCount"), CutInstructionCount = reader.ReadUInt32("CutInstructionCount"), EmitInstructionCount = reader.ReadUInt32("EmitInstructionCount"), TextureNormalInstructions = reader.ReadUInt32("TextureNormalInstructions"), TextureLoadInstructions = reader.ReadUInt32("TextureLoadInstructions"), TextureCompInstructions = reader.ReadUInt32("TextureCompInstructions"), TextureBiasInstructions = reader.ReadUInt32("TextureBiasInstructions"), TextureGradientInstructions = reader.ReadUInt32("TextureGradientInstructions"), MovInstructionCount = reader.ReadUInt32("MovInstructionCount"), MovCInstructionCount = reader.ReadUInt32("MovCInstructionCount"), ConversionInstructionCount = reader.ReadUInt32("ConversionInstructionCount") }; //TODO var unknown0 = reader.ReadUInt32("StatisticsChunkUnknown0"); result.InputPrimitive = (Primitive)reader.ReadUInt32("InputPrimitive"); result.GeometryShaderOutputTopology = reader.ReadEnum32 <PrimitiveTopology>("GeometryShaderOutputTopology"); result.GeometryShaderMaxOutputVertexCount = reader.ReadUInt32("GeometryShaderMaxOutputVertexCount"); var unknown1 = reader.ReadUInt32("StatisticsChunkUnknown1"); //if (unknown1 == 0 || unknown1 == 1 || unknown1 == 3) throw new System.Exception($"unknown1 is {unknown1}"); //TODO: CheckAccessFullyMapped textures have large unknown1 //Texture_Texture2D, Texture_Texture2DArray, Texture_TextureCube, Texture_TextureCubeArray var unknown2 = reader.ReadUInt32("StatisticsChunkUnknown2"); //if (unknown2 != 0 && unknown2 != 2) throw new System.Exception($"unknown2 is {unknown2}"); result.IsSampleFrequencyShader = (reader.ReadUInt32("IsSampleFrequencyShader") == 1); // DX10 stat size if (size == 29) { return(result); } result.GeometryShaderInstanceCount = reader.ReadUInt32("GeometryShaderInstanceCount"); result.ControlPoints = reader.ReadUInt32("ControlPoints"); result.HullShaderOutputPrimitive = reader.ReadEnum32 <TessellatorOutputPrimitive>("HullShaderOutputPrimitive"); result.HullShaderPartitioning = reader.ReadEnum32 <TessellatorPartitioning>("HullShaderPartitioning"); result.TessellatorDomain = reader.ReadEnum32 <TessellatorDomain>("TessellatorDomain"); result.BarrierInstructions = reader.ReadUInt32("BarrierInstructions"); result.InterlockedInstructions = reader.ReadUInt32("InterlockedInstructions"); result.TextureStoreInstructions = reader.ReadUInt32("TextureStoreInstructions"); // DX11 stat size. if (size == 37) { return(result); } throw new ParseException("Unhandled stat size: " + chunkSize); }
public static DebugEffectType Parse(DebugBytecodeReader reader, DebugBytecodeReader typeReader, DebugShaderVersion version) { var result = new DebugEffectType(); var typeNameOffset = result.TypeNameOffset = typeReader.ReadUInt32("TypeNameOffset"); var nameReader = reader.CopyAtOffset("NameReader", typeReader, (int)typeNameOffset); result.TypeName = nameReader.ReadString("TypeName"); result.EffectVariableType = typeReader.ReadEnum32 <EffectVariableType>("EffectVariableType"); result.ElementCount = typeReader.ReadUInt32("ElementCount"); result.UnpackedSize = typeReader.ReadUInt32("UnpackedSize"); result.Stride = typeReader.ReadUInt32("Stride"); result.PackedSize = typeReader.ReadUInt32("PackedSize"); if (result.EffectVariableType == EffectVariableType.Numeric) { var type = result.PackedType = typeReader.ReadUInt32("PackedType"); var numericType = result.NumericType = EffectNumericType.Parse(type); switch (numericType.NumericLayout) { case EffectNumericLayout.Scalar: result.VariableClass = ShaderVariableClass.Scalar; break; case EffectNumericLayout.Vector: result.VariableClass = ShaderVariableClass.Vector; break; case EffectNumericLayout.Matrix: result.VariableClass = type.DecodeValue(14, 14) == 1 ? ShaderVariableClass.MatrixColumns : ShaderVariableClass.MatrixRows; break; } switch (numericType.ScalarType) { case EffectScalarType.Float: result.ObjectType = EffectObjectType.Float; break; case EffectScalarType.Int: result.ObjectType = EffectObjectType.Int; break; case EffectScalarType.UInt: result.ObjectType = EffectObjectType.UInt; break; case EffectScalarType.Bool: result.ObjectType = EffectObjectType.Bool; break; } } else if (result.EffectVariableType == EffectVariableType.Object) { var type = result.PackedType = typeReader.ReadUInt32("PackedType"); result.VariableClass = ShaderVariableClass.Object; result.ObjectType = (EffectObjectType)type; } else if (result.EffectVariableType == EffectVariableType.Struct) { result.ObjectType = EffectObjectType.Void; result.VariableClass = ShaderVariableClass.Struct; result.MemberCount = typeReader.ReadUInt32("MemberCount"); for (int i = 0; i < result.MemberCount; i++) { typeReader.AddIndent($"Member {i}"); result.Members.Add(DebugEffectMember.Parse(reader, typeReader, version)); typeReader.RemoveIndent(); } if (version.MajorVersion == 5) { result.BaseClassType = typeReader.ReadUInt32("BaseClassType"); result.InterfaceCount = typeReader.ReadUInt32("InterfaceCount"); for (int i = 0; i < result.InterfaceCount; i++) { var interfaceOffset = typeReader.ReadUInt32($"InterfaceOffset{i}"); var interfaceReader = reader.CopyAtOffset($"Interface{i}", typeReader, (int)interfaceOffset); result.InterfaceTypes.Add(DebugEffectType.Parse(reader, interfaceReader, version)); } } } else if (result.EffectVariableType == EffectVariableType.Interface) { result.VariableClass = ShaderVariableClass.InterfaceClass; result.ObjectType = EffectObjectType.Interface; } return(result); }
public static DebugSignatureParameterDescription Parse(DebugBytecodeReader reader, DebugBytecodeReader parameterReader, ChunkType chunkType, SignatureElementSize size, ProgramType programType) { uint stream = 0; if (size == SignatureElementSize._7 || size == SignatureElementSize._8) { stream = parameterReader.ReadUInt32("Stream"); } uint nameOffset = parameterReader.ReadUInt32("NameOffset"); var nameReader = reader.CopyAtOffset("NameReader", parameterReader, (int)nameOffset); var result = new DebugSignatureParameterDescription { SemanticName = nameReader.ReadString("SemanticName"), SemanticIndex = parameterReader.ReadUInt32("SemanticIndex"), SystemValueType = parameterReader.ReadEnum32 <Name>("SystemValueType"), ComponentType = parameterReader.ReadEnum32 <RegisterComponentType>("ComponentType"), Register = parameterReader.ReadUInt32("Register"), Stream = stream, }; result.Mask = parameterReader.ReadEnum8 <ComponentMask>("Mask"); result.ReadWriteMask = parameterReader.ReadEnum8 <ComponentMask>("ReadWriteMask"); parameterReader.ReadUInt16("MaskPadding"); if (size == SignatureElementSize._8) { MinPrecision minPrecision = parameterReader.ReadEnum32 <MinPrecision>("MinPrecision"); result.MinPrecision = minPrecision; } // This is my guesswork, but it works so far... if (chunkType == ChunkType.Osg5 || chunkType == ChunkType.Osgn || chunkType == ChunkType.Osg1 || (chunkType == ChunkType.Pcsg && programType == ProgramType.HullShader)) { result.ReadWriteMask = (ComponentMask)(ComponentMask.All - result.ReadWriteMask); } // Vertex and pixel shaders need special handling for SystemValueType in the output signature. if ((programType == ProgramType.PixelShader || programType == ProgramType.VertexShader) && (chunkType == ChunkType.Osg5 || chunkType == ChunkType.Osgn || chunkType == ChunkType.Osg1)) { if (result.Register == 0xffffffff) { switch (result.SemanticName.ToUpper()) { case "SV_DEPTH": result.SystemValueType = Name.Depth; break; case "SV_COVERAGE": result.SystemValueType = Name.Coverage; break; case "SV_DEPTHGREATEREQUAL": result.SystemValueType = Name.DepthGreaterEqual; break; case "SV_DEPTHLESSEQUAL": result.SystemValueType = Name.DepthLessEqual; break; case "SV_STENCILREF": result.SystemValueType = Name.StencilRef; break; } } else if (programType == ProgramType.PixelShader) { result.SystemValueType = Name.Target; } } return(result); }