public static DebugInputOutputSignatureChunk Parse(DebugBytecodeReader reader, ChunkType chunkType, ProgramType programType) { DebugInputOutputSignatureChunk result; switch (chunkType) { case ChunkType.Isgn: case ChunkType.Isg1: result = new DebugInputSignatureChunk(); break; case ChunkType.Osgn: case ChunkType.Osg1: case ChunkType.Osg5: result = new DebugOutputSignatureChunk(); break; case ChunkType.Pcsg: result = new DebugPatchConstantSignatureChunk(); break; default: throw new ArgumentOutOfRangeException("chunkType", "Unrecognised chunk type: " + chunkType); } var chunkReader = reader.CopyAtCurrentPosition("ChunkReader", reader); var elementCount = chunkReader.ReadUInt32("ElementCount"); var uniqueKey = chunkReader.ReadUInt32("UniqueKey"); SignatureElementSize elementSize; switch (chunkType) { case ChunkType.Isgn: case ChunkType.Osgn: case ChunkType.Pcsg: elementSize = SignatureElementSize._6; break; case ChunkType.Osg5: elementSize = SignatureElementSize._7; break; case ChunkType.Osg1: case ChunkType.Isg1: elementSize = SignatureElementSize._8; break; default: throw new ArgumentOutOfRangeException("chunkType", "Unrecognised chunk type: " + chunkType); } for (int i = 0; i < elementCount; i++) { var indent = chunkReader.AddIndent($"{i}"); var parameter = DebugSignatureParameterDescription.Parse(reader, chunkReader, chunkType, elementSize, programType); result.Parameters.Add(parameter); chunkReader.RemoveIndent(); indent.Name += $": {parameter.SemanticName}"; } 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); }