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 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 List <Number> ReadParameterValue(this DebugParameter parameter, DebugBytecodeReader valueReader)
        {
            var result = new List <Number>();

            if (parameter.ParameterClass == ParameterClass.Object)
            {
                var defaultValueCount = parameter.GetSize() / 4;
                var data = valueReader.ReadBytes("ParameterValue", (int)defaultValueCount * 4);
                result.Add(new Number(data));
            }
            else
            {
                var defaultValueCount = parameter.GetSize() / 4;
                var data = valueReader.ReadBytes("ParameterValue", (int)defaultValueCount * 4);
                for (int i = 0; i < defaultValueCount; i++)
                {
                    result.Add(Number.FromByteArray(data, i * 4));
                }
            }
            return(result);
        }
Exemple #4
0
        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);
        }
        public static DebugEffectInterfaceInitializer Parse(DebugBytecodeReader reader, DebugBytecodeReader initializerReader)
        {
            var nameOffset = initializerReader.ReadUInt32("NameOffset");
            var index      = initializerReader.ReadUInt32("Index");
            var nameReader = reader.CopyAtOffset("NameReader", initializerReader, (int)nameOffset);
            var name       = nameReader.ReadString("Name");

            return(new DebugEffectInterfaceInitializer()
            {
                Name = name,
                Index = index
            });
        }
        public new static DebugEffectInlineShaderAssignment Parse(DebugBytecodeReader reader, DebugBytecodeReader assignmentReader)
        {
            var result       = new DebugEffectInlineShaderAssignment();
            var shaderOffset = result.ShaderOffset = assignmentReader.ReadUInt32("ShaderOffset");
            var SODeclOffset = result.SODeclOffset = assignmentReader.ReadUInt32("DODeclOffset");
            var shaderReader = reader.CopyAtOffset("ShaderReader", assignmentReader, (int)shaderOffset);
            var shaderSize   = shaderReader.ReadUInt32("ShaderSize");

            if (shaderSize != 0)
            {
                result.Shader = BytecodeContainer.Parse(shaderReader.ReadBytes("Shader", (int)shaderSize));
            }
            var SODeclReader = reader.CopyAtOffset("SODeclReader", assignmentReader, (int)SODeclOffset);

            result.SODecl = SODeclReader.ReadString("SODecl");
            return(result);
        }
        public new static DebugEffectExpressionIndexAssignment Parse(DebugBytecodeReader reader, DebugBytecodeReader assignmentReader)
        {
            var result          = new DebugEffectExpressionIndexAssignment();
            var arrayNameOffset = result.ArrayNameOffset = assignmentReader.ReadUInt32("ArrayNameOffset");
            var arrayNameReader = reader.CopyAtOffset("ArrayNameReader", assignmentReader, (int)arrayNameOffset);

            result.ArrayName = arrayNameReader.ReadString("ArrayName");

            var shaderOffset = result.ShaderOffset = assignmentReader.ReadUInt32("ShaderOffset");
            var shaderReader = reader.CopyAtOffset("ShaderReader", assignmentReader, (int)shaderOffset);
            var shaderSize   = result.ShaderSize = shaderReader.ReadUInt32("ShaderSize");

            if (shaderSize != 0)
            {
                result.Shader = DebugBytecodeContainer.Parse(shaderReader.CopyAtCurrentPosition("ExpressionIndexReader", shaderReader));
            }
            return(result);
        }
        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++)
            {
                result.Parameters.Add(DebugSignatureParameterDescription.Parse(reader, chunkReader, chunkType, elementSize,
                                                                               programType));
            }

            return(result);
        }
        public static DebugResourceDefinitionChunk Parse(DebugBytecodeReader reader)
        {
            var headerReader = reader.CopyAtCurrentPosition("RDefHeader", reader);

            uint constantBufferCount   = headerReader.ReadUInt32("constantBufferCount");
            uint constantBufferOffset  = headerReader.ReadUInt32("constantBufferOffset");
            uint resourceBindingCount  = headerReader.ReadUInt32("resourceBindingCount");
            uint resourceBindingOffset = headerReader.ReadUInt32("resourceBindingOffset");
            var  target = DebugShaderVersion.ParseRdef(headerReader);
            var  flags  = headerReader.ReadEnum32 <ShaderFlags>("flags");

            var creatorOffset = headerReader.ReadUInt32("creatorOffset");
            var creatorReader = reader.CopyAtOffset("CreatorString", headerReader, (int)creatorOffset);
            var creator       = creatorReader.ReadString("creator");

            var result = new DebugResourceDefinitionChunk
            {
                Target  = target,
                Flags   = flags,
                Creator = creator
            };

            if (target.MajorVersion == 5 || target.ProgramType == ProgramType.LibraryShader)
            {
                var isVersion5_1 = target.MajorVersion == 5 && target.MinorVersion == 1;
                if (isVersion5_1)
                {
                    var unknown0 = headerReader.ReadUInt32("unkRdefHeader");
                }
                else
                {
                    string rd11 = headerReader.ReadUInt32("rd11").ToFourCcString();
                    if (rd11 != "RD11")
                    {
                        throw new ParseException("Expected RD11.");
                    }
                }

                var unkStride1            = headerReader.ReadUInt32("unkStride1");      // TODO
                var constantBufferStride  = headerReader.ReadUInt32("constantBufferStride");
                var resourceBindingStride = headerReader.ReadUInt32("resourceBindingStride");
                //Shader Variable Stride?
                var unkStride2 = headerReader.ReadUInt32("unkStride2");
                var unkStride3 = headerReader.ReadUInt32("unkStride3");
                //Shader Type Member Stride?
                var unkStride4 = headerReader.ReadUInt32("unkStride4");

                Debug.Assert(unkStride1 == 60, $"unkStride1 is {unkStride1}");
                Debug.Assert(constantBufferStride == 24, $"constantBufferStride is {constantBufferStride}");
                Debug.Assert(resourceBindingStride == CalculateResourceBindingStride(target),
                             $"resourceBindingStride is {resourceBindingStride}");
                Debug.Assert(unkStride2 == 40, $"unkStride2 is {unkStride2}");
                Debug.Assert(unkStride3 == 36, $"unkStride3 is {unkStride3}");
                Debug.Assert(unkStride4 == 12, $"unkStride4 is {unkStride4}");

                result.InterfaceSlotCount = headerReader.ReadUInt32("InterfaceSlotCount");
            }

            var resourceBindingReader = reader.CopyAtOffset("ResourceBindings", headerReader, (int)resourceBindingOffset);

            for (int i = 0; i < resourceBindingCount; i++)
            {
                result.ResourceBindings.Add(DebugResourceBinding.Parse(reader, resourceBindingReader, target));
            }

            var constantBufferReader = reader.CopyAtOffset("ContantBuffers", headerReader, (int)constantBufferOffset);

            constantBufferReader.Indent++;
            for (int i = 0; i < constantBufferCount; i++)
            {
                result.ConstantBuffers.Add(DebugConstantBuffer.Parse(reader, constantBufferReader, result.Target));
            }

            return(result);
        }
        public new static DebugEffectVariableAssignment Parse(DebugBytecodeReader reader, DebugBytecodeReader assignmentReader)
        {
            var result = new DebugEffectVariableAssignment();

            result.Value = assignmentReader.ReadString("Value");
            return(result);
        }
        public static DebugGeometryShaderOutputPrimitiveTopologyDeclarationToken Parse(DebugBytecodeReader reader)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("PriomitiveTopology", token0.DecodeValue <PrimitiveTopology>(11, 17));
            return(new DebugGeometryShaderOutputPrimitiveTopologyDeclarationToken
            {
                PrimitiveTopology = token0.DecodeValue <PrimitiveTopology>(11, 17)
            });
        }
Exemple #12
0
        public new static DebugEffectExpressionAssignment Parse(DebugBytecodeReader reader, DebugBytecodeReader assignmentReader)
        {
            var result     = new DebugEffectExpressionAssignment();
            var shaderSize = assignmentReader.ReadUInt32("ShaderSize");

            if (shaderSize != 0)
            {
                result.Shader = DebugBytecodeContainer.Parse(assignmentReader.CopyAtCurrentPosition("ExpressionReader", assignmentReader));
            }
            return(result);
        }
Exemple #13
0
        public static DebugDeclarationToken Parse(DebugBytecodeReader reader, OpcodeType opcodeType, DebugShaderVersion version)
        {
            switch (opcodeType)
            {
            case OpcodeType.DclGlobalFlags:
                return(DebugGlobalFlagsDeclarationToken.Parse(reader));

            case OpcodeType.DclResource:
                return(DebugResourceDeclarationToken.Parse(reader, version));

            case OpcodeType.DclSampler:
                return(DebugSamplerDeclarationToken.Parse(reader, version));

            case OpcodeType.DclInput:
            case OpcodeType.DclInputSgv:
            case OpcodeType.DclInputSiv:
            case OpcodeType.DclInputPs:
            case OpcodeType.DclInputPsSgv:
            case OpcodeType.DclInputPsSiv:
                return(DebugInputRegisterDeclarationToken.Parse(reader));

            case OpcodeType.DclOutput:
            case OpcodeType.DclOutputSgv:
            case OpcodeType.DclOutputSiv:
                return(DebugOutputRegisterDeclarationToken.Parse(reader));

            case OpcodeType.DclIndexRange:
                return(DebugIndexingRangeDeclarationToken.Parse(reader));

            case OpcodeType.DclTemps:
                return(DebugTempRegisterDeclarationToken.Parse(reader));

            case OpcodeType.DclIndexableTemp:
                return(DebugIndexableTempRegisterDeclarationToken.Parse(reader));

            case OpcodeType.DclConstantBuffer:
                return(DebugConstantBufferDeclarationToken.Parse(reader, version));

            case OpcodeType.DclGsInputPrimitive:
                return(DebugGeometryShaderInputPrimitiveDeclarationToken.Parse(reader));

            case OpcodeType.DclGsOutputPrimitiveTopology:
                return(DebugGeometryShaderOutputPrimitiveTopologyDeclarationToken.Parse(reader));

            case OpcodeType.DclMaxOutputVertexCount:
                return(DebugGeometryShaderMaxOutputVertexCountDeclarationToken.Parse(reader));

            case OpcodeType.DclGsInstanceCount:
                return(DebugGeometryShaderInstanceCountDeclarationToken.Parse(reader));

            case OpcodeType.DclInputControlPointCount:
            case OpcodeType.DclOutputControlPointCount:
                return(DebugControlPointCountDeclarationToken.Parse(reader));

            case OpcodeType.DclTessDomain:
                return(DebugTessellatorDomainDeclarationToken.Parse(reader));

            case OpcodeType.DclTessPartitioning:
                return(DebugTessellatorPartitioningDeclarationToken.Parse(reader));

            case OpcodeType.DclTessOutputPrimitive:
                return(DebugTessellatorOutputPrimitiveDeclarationToken.Parse(reader));

            case OpcodeType.DclHsMaxTessFactor:
                return(DebugHullShaderMaxTessFactorDeclarationToken.Parse(reader));

            case OpcodeType.DclHsForkPhaseInstanceCount:
                return(DebugHullShaderForkPhaseInstanceCountDeclarationToken.Parse(reader));

            case OpcodeType.DclFunctionBody:
                return(DebugFunctionBodyDeclarationToken.Parse(reader));

            case OpcodeType.DclFunctionTable:
                return(DebugFunctionTableDeclarationToken.Parse(reader));

            case OpcodeType.DclInterface:
                return(DebugInterfaceDeclarationToken.Parse(reader));

            case OpcodeType.DclThreadGroup:
                return(DebugThreadGroupDeclarationToken.Parse(reader));

            case OpcodeType.DclUnorderedAccessViewTyped:
                return(DebugTypedUnorderedAccessViewDeclarationToken.Parse(reader, version));

            case OpcodeType.DclUnorderedAccessViewRaw:
                return(DebugRawUnorderedAccessViewDeclarationToken.Parse(reader, version));

            case OpcodeType.DclUnorderedAccessViewStructured:
                return(DebugStructuredUnorderedAccessViewDeclarationToken.Parse(reader, version));

            case OpcodeType.DclThreadGroupSharedMemoryRaw:
                return(DebugRawThreadGroupSharedMemoryDeclarationToken.Parse(reader));

            case OpcodeType.DclThreadGroupSharedMemoryStructured:
                return(DebugStructuredThreadGroupSharedMemoryDeclarationToken.Parse(reader));

            case OpcodeType.DclResourceRaw:
                return(DebugRawShaderResourceViewDeclarationToken.Parse(reader, version));

            case OpcodeType.DclResourceStructured:
                return(DebugStructuredShaderResourceViewDeclarationToken.Parse(reader, version));

            case OpcodeType.DclStream:
                return(DebugStreamDeclarationToken.Parse(reader));

            default:
                throw new ParseException("OpcodeType '" + opcodeType + "' is not supported.");
            }
        }
Exemple #14
0
        public static DebugShaderType Parse(DebugBytecodeReader reader, DebugBytecodeReader typeReader, DebugShaderVersion target,
                                            int indent, bool isFirst, uint parentOffset)
        {
            var result = new DebugShaderType(indent, isFirst)
            {
                VariableClass = typeReader.ReadEnum16 <ShaderVariableClass>("VariableClass"),
                VariableType  = typeReader.ReadEnum16 <ShaderVariableType>("VariableType"),
                Rows          = typeReader.ReadUInt16("Rows"),
                Columns       = typeReader.ReadUInt16("Columns"),
                ElementCount  = typeReader.ReadUInt16("ElementCount")
            };

            var memberCount  = typeReader.ReadUInt16("memberCount");
            var memberOffset = typeReader.ReadUInt32("memberOffset");

            if (target.MajorVersion >= 5)
            {
                var subTypeOffset = typeReader.ReadInt32("subTypeOffset");                 // Guessing
                if (subTypeOffset != 0)
                {
                    var parentInterfaceReader = reader.CopyAtOffset("subtypeReader", typeReader, (int)subTypeOffset);
                    result.SubType = DebugShaderType.Parse(reader, parentInterfaceReader, target,
                                                           indent + 4, true, parentOffset);
                }

                var baseClassOffset = typeReader.ReadUInt32("baseClassOffset");
                if (baseClassOffset != 0)
                {
                    var baseClassReader = reader.CopyAtOffset("baseClassReader", typeReader, (int)baseClassOffset);
                    result.BaseClass = DebugShaderType.Parse(reader, baseClassReader, target,
                                                             indent + 4, true, parentOffset);
                }

                result.NumberOfInterfaces = typeReader.ReadUInt32("NumberOfInterfaces");

                var interfaceSectionOffset = typeReader.ReadUInt32("InterfaceSectionOffset");
                if (interfaceSectionOffset != 0)
                {
                    var interfaceSectionReader = reader.CopyAtOffset("interfaceSectionReader", typeReader, (int)interfaceSectionOffset);
                    for (int i = 0; i < result.NumberOfInterfaces; i++)
                    {
                        var interfaceTypeOffset = interfaceSectionReader.ReadUInt32($"UnkInterface{i}");
                        var interfaceReader     = reader.CopyAtOffset($"InterfaceReader {i}", typeReader, (int)interfaceTypeOffset);
                        result.Interfaces.Add(DebugShaderType.Parse(reader, interfaceReader,
                                                                    target, indent + 4, i == 0, parentOffset));
                    }
                }

                var parentNameOffset = typeReader.ReadUInt32("parentNameOffset");
                if (parentNameOffset > 0)
                {
                    var parentNameReader = reader.CopyAtOffset("parentNameOffset", typeReader, (int)parentNameOffset);
                    result.BaseTypeName = parentNameReader.ReadString("BaseTypeName");
                }
            }

            if (memberCount > 0)
            {
                var memberReader = reader.CopyAtOffset("memberReader", typeReader, (int)memberOffset);
                for (int i = 0; i < memberCount; i++)
                {
                    memberReader.AddIndent($"Member {i}");
                    result.Members.Add(DebugShaderTypeMember.Parse(reader, memberReader, target, indent + 4, i == 0,
                                                                   parentOffset));
                    memberReader.RemoveIndent();
                }
            }

            if (target.ProgramType == ProgramType.LibraryShader && target.MajorVersion == 4)
            {
                var unk1           = typeReader.ReadUInt32("Unk1");
                var unk2           = typeReader.ReadUInt32("Unk2");
                var unk3           = typeReader.ReadUInt32("Unk3");
                var unk4           = typeReader.ReadUInt32("Unk4");
                var typeNameOffset = typeReader.ReadUInt32("typeNameoffset");
                var typeNameReader = reader.CopyAtOffset("TypeNameReader", typeReader, (int)typeNameOffset);
                typeNameReader.ReadString("TypeName");
                Debug.Assert(unk1 == 0, $"ShaderType.Unk1={unk1}");
                Debug.Assert(unk2 == 0, $"ShaderType.Unk2={unk2}");
                Debug.Assert(unk3 == 0, $"ShaderType.Unk3={unk3}");
                Debug.Assert(unk4 == 0, $"ShaderType.Unk4={unk4}");
            }

            return(result);
        }
Exemple #15
0
        public static DebugOperand Parse(DebugBytecodeReader reader, OpcodeType parentType)
        {
            uint token0 = reader.ReadUInt32("operandToken");

            if (token0 == 0)
            {
                return(null);
            }
            var member  = reader.LocalMembers.Last();
            var operand = new DebugOperand(parentType);

            var numComponents = token0.DecodeValue <OperandNumComponents>(0, 1);

            reader.AddNote("numComponents", numComponents);
            switch (numComponents)
            {
            case OperandNumComponents.Zero:
            {
                operand.NumComponents = 0;
                break;
            }

            case OperandNumComponents.One:
            {
                operand.NumComponents = 1;
                break;
            }

            case OperandNumComponents.Four:
            {
                operand.NumComponents = 4;
                operand.SelectionMode = token0.DecodeValue <Operand4ComponentSelectionMode>(2, 3);
                member.AddNote("SelectionMode", operand.SelectionMode);
                switch (operand.SelectionMode)
                {
                case Operand4ComponentSelectionMode.Mask:
                {
                    operand.ComponentMask = token0.DecodeValue <ComponentMask>(4, 7);
                    member.AddNote("ComponentMask", operand.ComponentMask);
                    break;
                }

                case Operand4ComponentSelectionMode.Swizzle:
                {
                    var swizzle = token0.DecodeValue(4, 11);
                    Func <uint, byte, Operand4ComponentName> swizzleDecoder = (s, i) =>
                                                                              (Operand4ComponentName)((s >> (i * 2)) & 3);
                    operand.Swizzles[0] = swizzleDecoder(swizzle, 0);
                    operand.Swizzles[1] = swizzleDecoder(swizzle, 1);
                    operand.Swizzles[2] = swizzleDecoder(swizzle, 2);
                    operand.Swizzles[3] = swizzleDecoder(swizzle, 3);
                    member.AddNote("Swizzles[0]", operand.Swizzles[0]);
                    member.AddNote("Swizzles[1]", operand.Swizzles[1]);
                    member.AddNote("Swizzles[2]", operand.Swizzles[2]);
                    member.AddNote("Swizzles[3]", operand.Swizzles[3]);
                    break;
                }

                case Operand4ComponentSelectionMode.Select1:
                {
                    var swizzle = token0.DecodeValue <Operand4ComponentName>(4, 5);
                    operand.Swizzles[0] = operand.Swizzles[1] = operand.Swizzles[2] = operand.Swizzles[3] = swizzle;
                    member.AddNote("Swizzles[0]", operand.Swizzles[0]);
                    member.AddNote("Swizzles[1]", operand.Swizzles[1]);
                    member.AddNote("Swizzles[2]", operand.Swizzles[2]);
                    member.AddNote("Swizzles[3]", operand.Swizzles[3]);
                    break;
                }

                default:
                {
                    throw new ParseException("Unrecognized selection method: " + operand.SelectionMode);
                }
                }
                break;
            }

            case OperandNumComponents.N:
            {
                throw new ParseException("OperandNumComponents.N is not currently supported.");
            }
            }

            operand.OperandType = token0.DecodeValue <OperandType>(12, 19);
            member.AddNote("OperandType", operand.OperandType);
            operand.IndexDimension = token0.DecodeValue <OperandIndexDimension>(20, 21);
            member.AddNote("IndexDimension", operand.IndexDimension);

            operand.IsExtended = token0.DecodeValue(31, 31) == 1;
            member.AddNote("IsExtended", operand.IsExtended);
            if (operand.IsExtended)
            {
                ReadExtendedOperand(operand, reader);
            }

            Func <uint, byte, OperandIndexRepresentation> indexRepresentationDecoder = (t, i) =>
                                                                                       (OperandIndexRepresentation)t.DecodeValue((byte)(22 + (i * 3)), (byte)(22 + (i * 3) + 2));

            for (byte i = 0; i < (byte)operand.IndexDimension; i++)
            {
                operand.Indices[i] = new DebugOperandIndex();

                var indexRepresentation = indexRepresentationDecoder(token0, i);
                operand.Indices[i].Representation = indexRepresentation;
                member.AddNote($"Indices[{i}].Representation", operand.Indices[i].Representation);
                switch (indexRepresentation)
                {
                case OperandIndexRepresentation.Immediate32:
                    operand.Indices[i].Value = reader.ReadUInt32($"Indices[{i}].Value");
                    break;

                case OperandIndexRepresentation.Immediate64:
                    operand.Indices[i].Value = reader.ReadUInt64($"Indices[{i}].Value");
                    goto default;

                case OperandIndexRepresentation.Relative:
                    operand.Indices[i].Register = Parse(reader, parentType);
                    break;

                case OperandIndexRepresentation.Immediate32PlusRelative:
                    operand.Indices[i].Value = reader.ReadUInt32($"Indices[{i}].Value");
                    goto case OperandIndexRepresentation.Relative;

                case OperandIndexRepresentation.Immediate64PlusRelative:
                    operand.Indices[i].Value = reader.ReadUInt64($"Indices[{i}].Value");
                    goto case OperandIndexRepresentation.Relative;

                default:
                    throw new ParseException("Unrecognised index representation: " + indexRepresentation);
                }
            }

            var numberType = parentType.GetNumberType();

            switch (operand.OperandType)
            {
            case OperandType.Immediate32:
            {
                var immediateValues = new DebugNumber4();
                for (var i = 0; i < operand.NumComponents; i++)
                {
                    immediateValues.SetNumber(i, DebugNumber.Parse(reader));
                }
                operand.ImmediateValues = immediateValues;
                break;
            }

            case OperandType.Immediate64:
            {
                var immediateValues = new DebugNumber4();
                for (var i = 0; i < operand.NumComponents; i++)
                {
                    immediateValues.SetDouble(i, reader.ReadDouble($"ImmediateValues[{i}]"));
                }
                operand.ImmediateValues = immediateValues;
                break;
            }
            }
            return(operand);
        }
Exemple #16
0
        public static DebugEffectChunk Parse(DebugBytecodeReader reader, uint size)
        {
            var headerReader = reader.CopyAtCurrentPosition("Header", reader);
            var result       = new DebugEffectChunk();

            result.Size = size;
            var header     = result.Header = DebugEffectHeader.Parse(headerReader);
            var bodyOffset = header.Version.MajorVersion < 5 ?
                             0x4C : 0x60;
            var footerOffset = (int)(result.Header.FooterOffset + bodyOffset);
            var bodyReader   = reader.CopyAtOffset("Body", reader, (int)bodyOffset);
            var dummyReader  = bodyReader.CopyAtCurrentPosition("DummyReader", bodyReader);

            dummyReader.ReadUInt32("Zero");
            var footerReader = reader.CopyAtOffset("Footer", reader, footerOffset);
            var version      = header.Version;

            for (int i = 0; i < header.ConstantBuffers; i++)
            {
                footerReader.AddIndent($"ConstantBuffer {i}");
                result.LocalBuffers.Add(DebugEffectBuffer.Parse(bodyReader, footerReader, version, false));
                footerReader.RemoveIndent();
            }
            for (int i = 0; i < header.ObjectCount; i++)
            {
                footerReader.AddIndent($"Variable {i}");
                result.LocalVariables.Add(DebugEffectObjectVariable.Parse(bodyReader, footerReader, version, false));
                footerReader.RemoveIndent();
            }
            for (int i = 0; i < header.SharedConstantBuffers; i++)
            {
                footerReader.AddIndent($"SharedConstantBuffer {i}");
                result.SharedBuffers.Add(DebugEffectBuffer.Parse(bodyReader, footerReader, version, true));
                footerReader.RemoveIndent();
            }
            for (int i = 0; i < header.SharedObjectCount; i++)
            {
                footerReader.AddIndent($"SharedVariable {i}");
                result.SharedVariables.Add(DebugEffectObjectVariable.Parse(bodyReader, footerReader, version, true));
                footerReader.RemoveIndent();
            }
            if (header.Version.MajorVersion >= 5)
            {
                for (int i = 0; i < header.InterfaceVariableCount; i++)
                {
                    footerReader.AddIndent($"Interface {i}");
                    result.InterfaceVariables.Add(DebugEffectInterfaceVariable.Parse(bodyReader, footerReader, version));
                    footerReader.RemoveIndent();
                }
                for (int i = 0; i < header.GroupCount; i++)
                {
                    footerReader.AddIndent($"Group {i}");
                    result.Groups.Add(DebugEffectGroup.Parse(bodyReader, footerReader, header.Version));
                    footerReader.RemoveIndent();
                }
            }
            else
            {
                for (int i = 0; i < header.Techniques; i++)
                {
                    footerReader.AddIndent($"Technique {i}");
                    result.Techniques.Add(DebugEffectTechnique.Parse(bodyReader, footerReader, header.Version));
                    footerReader.RemoveIndent();
                }
            }

            return(result);
        }
        public static DebugUnknown1Mapping Parse(DebugBytecodeReader reader)
        {
            var result = new DebugUnknown1Mapping();

            return(result);
        }
        public new static DebugEffectConstantAssignment Parse(DebugBytecodeReader reader, DebugBytecodeReader assignmentReader)
        {
            var result          = new DebugEffectConstantAssignment();
            var assignmentCount = assignmentReader.ReadUInt32("AssignmentCount");

            for (int i = 0; i < assignmentCount; i++)
            {
                result.Types.Add((EffectScalarType)assignmentReader.ReadUInt32($"Type{i}"));
                result.Values.Add(DebugNumber.Parse(assignmentReader));
            }
            return(result);
        }
        public static DebugLevel9ShaderChunk Parse(DebugBytecodeReader chunkContentReader, uint chunkSize)
        {
            var  result     = new DebugLevel9ShaderChunk();
            uint chunkSize2 = chunkContentReader.ReadUInt32("chunkSize2");

            result.Version = DebugShaderVersion.ParseAon9(chunkContentReader);
            uint shaderSize                   = chunkContentReader.ReadUInt32("shaderSize");
            var  shaderOffset                 = chunkContentReader.ReadUInt32("shaderOffset");
            var  cbMappingCount               = chunkContentReader.ReadUInt16("cbMappingCount");
            var  cbMappingOffset              = chunkContentReader.ReadUInt16("cbMappingOffset");
            var  loopRegisterMappingCount     = chunkContentReader.ReadUInt16("loopRegisterMappingCount");
            var  loopRegisterMappingOffset    = chunkContentReader.ReadUInt16("loopRegisterMappingOffset");
            var  unk0MappingCount             = chunkContentReader.ReadUInt16("unk0MappingCount");
            var  unk0MappingOffset            = chunkContentReader.ReadUInt16("unk0MappingOffset");
            var  samplerMappingCount          = chunkContentReader.ReadUInt16("samplerMappingCount");
            var  samplerMappingOffset         = chunkContentReader.ReadUInt16("samplerMappingOffset");
            var  runtimeConstantMappingCount  = chunkContentReader.ReadUInt16("runtimeConstantMappingCount");
            var  runtimeConstantMappingOffset = chunkContentReader.ReadUInt16("runtimeConstantMappingOffset");

            if (cbMappingCount > 0)
            {
                var mappingReader = chunkContentReader.CopyAtOffset("mappingReader", chunkContentReader, cbMappingOffset);
                for (int i = 0; i < cbMappingCount; i++)
                {
                    result.ConstantBufferMappings.Add(DebugConstantBufferMapping.Parse(mappingReader));
                }
            }
            if (loopRegisterMappingCount > 0)
            {
                var mappingReader = chunkContentReader.CopyAtOffset("mappingReader", chunkContentReader, loopRegisterMappingOffset);
                for (int i = 0; i < loopRegisterMappingCount; i++)
                {
                    result.LoopRegisterMappings.Add(DebugLoopRegisterMapping.Parse(mappingReader));
                }
            }
            if (unk0MappingCount > 0)
            {
                var mappingReader = chunkContentReader.CopyAtOffset("mappingReader", chunkContentReader, unk0MappingOffset);
                for (int i = 0; i < unk0MappingCount; i++)
                {
                    result.Unknown0Mappings.Add(DebugUnknown1Mapping.Parse(mappingReader));
                }
            }
            if (samplerMappingCount > 0)
            {
                var mappingReader = chunkContentReader.CopyAtOffset("mappingReader", chunkContentReader, samplerMappingOffset);
                for (int i = 0; i < samplerMappingCount; i++)
                {
                    result.SamplerMappings.Add(DebugSamplerMapping.Parse(mappingReader));
                }
                // FXC dissassembly sorts sampler mappings
                result.SamplerMappings = result.SamplerMappings
                                         .OrderBy(s => s.TargetSampler)
                                         .ToList();
            }
            if (runtimeConstantMappingCount > 0)
            {
                var mappingReader = chunkContentReader.CopyAtOffset("mappingReader", chunkContentReader, runtimeConstantMappingOffset);
                for (int i = 0; i < runtimeConstantMappingCount; i++)
                {
                    result.RuntimeConstantMappings.Add(DebugRuntimeConstantMapping.Parse(mappingReader));
                }
            }
            var shaderChunkReader = chunkContentReader.CopyAtOffset("shaderChunkReader", chunkContentReader, (int)shaderOffset);
            var byteCode          = shaderChunkReader.ReadBytes("bytecode", (int)shaderSize);

            return(result);
        }
        public new static DebugEffectInlineShader5Assignment Parse(DebugBytecodeReader reader, DebugBytecodeReader variableReader)
        {
            var result       = new DebugEffectInlineShader5Assignment();
            var shaderOffset = result.ShaderOffset = variableReader.ReadUInt32("ShaderOffset");

            result.SODeclsOffset[0] = variableReader.ReadUInt32("SODeclsOffset0");
            result.SODeclsOffset[1] = variableReader.ReadUInt32("SODeclsOffset1");
            result.SODeclsOffset[2] = variableReader.ReadUInt32("SODeclsOffset2");
            result.SODeclsOffset[3] = variableReader.ReadUInt32("SODeclsOffset3");
            var SoDeclsCount = result.SODeclsCount = variableReader.ReadUInt32("SODeclsCount");

            result.RasterizedStream = variableReader.ReadUInt32("RasterizedStream");
            var interfaceBindingCount  = result.InterfaceBindingCount = variableReader.ReadUInt32("InterfaceBindingCount");
            var interfaceBindingOffset = result.InterfaceBindingOffset = variableReader.ReadUInt32("InterfaceBindinfOffset");
            var shaderReader           = reader.CopyAtOffset("ShaderReader", variableReader, (int)shaderOffset);
            var shaderSize             = shaderReader.ReadUInt32("ShaderSize");

            if (shaderSize != 0)
            {
                result.Shader = BytecodeContainer.Parse(shaderReader.ReadBytes("Shader", (int)shaderSize));
            }
            for (int i = 0; i < 4; i++)
            {
                var offset = result.SODeclsOffset[i];
                if (offset != 0)
                {
                    var soDeclReader = reader.CopyAtOffset("SODeclReader", variableReader, (int)offset);
                    result.SODecls.Add(soDeclReader.ReadString($"SODecl{i}"));
                }
            }
            var interfaceReader = reader.CopyAtOffset("InterfaceReader", variableReader, (int)interfaceBindingOffset);

            for (int i = 0; i < interfaceBindingCount; i++)
            {
                result.InterfaceBindings.Add(DebugEffectInterfaceInitializer.Parse(reader, interfaceReader));
            }
            return(result);
        }
Exemple #21
0
        static void Main(string[] args)
        {
            var options = new Options();

            for (int i = 0; i < args.Length; i++)
            {
                switch (args[i])
                {
                case "-O":
                    if (args.Length <= i + 1)
                    {
                        Console.Error.WriteLine("No output path specified");
                        return;
                    }
                    options.DestPath = args[i + 1];
                    i += 1;
                    break;

                case "-a":
                    options.Mode = DecompileMode.Dissassemble;
                    break;

                case "-d":
                    options.Mode = DecompileMode.Debug;
                    break;

                case "-h":
                    options.Mode = DecompileMode.DebugHtml;
                    break;

                default:
                    options.SourcePath = args[i];
                    break;
                }
            }
            if (string.IsNullOrEmpty(options.SourcePath))
            {
                Console.Error.WriteLine("No source path specified");
                Environment.Exit(1);
            }

            byte[] data = null;
            try
            {
                data = File.ReadAllBytes(options.SourcePath);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("Error reading source");
                Console.Error.WriteLine(ex);
                Environment.Exit(1);
            }
            var programType = GetProgramType(data);

            using (var sw = GetStream(options))
            {
                if (programType == ProgramType.Unknown)
                {
                    Console.Error.WriteLine($"Unable to identify shader object format");
                    Environment.Exit(1);
                }
                else if (programType == ProgramType.DXBC)
                {
                    if (options.Mode == DecompileMode.Dissassemble)
                    {
                        var container = new BytecodeContainer(data);
                        sw.Write(container.ToString());
                    }
                    else if (options.Mode == DecompileMode.Decompile)
                    {
                        var hlsl = HLSLDecompiler.Decompile(data);
                        sw.Write(hlsl);
                    }
                    else if (options.Mode == DecompileMode.Debug)
                    {
                        sw.WriteLine(string.Join(" ", args));
                        var shaderBytecode = DebugBytecodeContainer.Parse(data);
                        var result         = shaderBytecode.Dump();
                        sw.Write(result);
                    }
                    else if (options.Mode == DecompileMode.DebugHtml)
                    {
                        var shaderBytecode = DebugBytecodeContainer.Parse(data);
                        var result         = shaderBytecode.DumpHTML();
                        sw.Write(result);
                    }
                }
                else if (programType == ProgramType.DX9)
                {
                    if (options.Mode == DecompileMode.Dissassemble)
                    {
                        var disasm = DXDecompiler.DX9Shader.AsmWriter.Disassemble(data);
                        sw.Write(disasm);
                    }
                    else if (options.Mode == DecompileMode.Decompile)
                    {
                        var hlsl = DXDecompiler.DX9Shader.HlslWriter.Decompile(data);
                        sw.Write(hlsl);
                    }
                    else if (options.Mode == DecompileMode.Debug)
                    {
                        sw.WriteLine(string.Join(" ", args));
                        var shaderType = (DXDecompiler.DX9Shader.ShaderType)BitConverter.ToUInt16(data, 2);
                        if (shaderType == DXDecompiler.DX9Shader.ShaderType.Effect)
                        {
                            var    reader = new DebugBytecodeReader(data, 0, data.Length);
                            string error  = "";
                            try
                            {
                                reader.ReadByte("minorVersion");
                                reader.ReadByte("majorVersion");
                                reader.ReadUInt16("shaderType");
                                DebugEffectChunk.Parse(reader, (uint)(data.Length - 4));
                            }
                            catch (Exception ex)
                            {
                                error = ex.ToString();
                            }
                            var dump = reader.DumpStructure();
                            if (!string.IsNullOrEmpty(error))
                            {
                                dump += "\n" + error;
                            }
                            sw.Write(dump);
                        }
                        else
                        {
                            var    reader = new DebugBytecodeReader(data, 0, data.Length);
                            string error  = "";
                            try
                            {
                                DebugShaderModel.Parse(reader);
                            }
                            catch (Exception ex)
                            {
                                error = ex.ToString();
                            }
                            var dump = reader.DumpStructure();
                            if (!string.IsNullOrEmpty(error))
                            {
                                dump += "\n" + error;
                            }
                            sw.Write(dump);
                        }
                    }
                    else if (options.Mode == DecompileMode.DebugHtml)
                    {
                        var shaderType = (DXDecompiler.DX9Shader.ShaderType)BitConverter.ToUInt16(data, 2);
                        if (shaderType == DXDecompiler.DX9Shader.ShaderType.Effect)
                        {
                            var    reader = new DebugBytecodeReader(data, 0, data.Length);
                            string error  = "";
                            try
                            {
                                reader.ReadByte("minorVersion");
                                reader.ReadByte("majorVersion");
                                reader.ReadUInt16("shaderType");
                                DebugEffectChunk.Parse(reader, (uint)(data.Length - 4));
                            }
                            catch (Exception ex)
                            {
                                error = ex.ToString();
                            }
                            var dump = reader.DumpHtml();
                            if (!string.IsNullOrEmpty(error))
                            {
                                dump += "\n" + error;
                            }
                            sw.Write(dump);
                        }
                        else
                        {
                            var    reader = new DebugBytecodeReader(data, 0, data.Length);
                            string error  = "";
                            try
                            {
                                DebugShaderModel.Parse(reader);
                            }
                            catch (Exception ex)
                            {
                                error = ex.ToString();
                            }
                            var dump = reader.DumpHtml();
                            if (!string.IsNullOrEmpty(error))
                            {
                                dump += "\n" + error;
                            }
                            sw.Write(dump);
                        }
                    }
                }
            }
        }
Exemple #22
0
        public static DebugEffectObjectVariable Parse(DebugBytecodeReader reader, DebugBytecodeReader variableReader,
                                                      DebugShaderVersion version, bool isShared = false)
        {
            var result     = new DebugEffectObjectVariable();
            var nameOffset = result.NameOffset = variableReader.ReadUInt32("NameOffset");
            var nameReader = reader.CopyAtOffset("NameReader", variableReader, (int)nameOffset);

            result.Name       = nameReader.ReadString("Name");
            result.TypeOffset = variableReader.ReadUInt32("TypeOffset");
            var typeReader = reader.CopyAtOffset("TypeReader", variableReader, (int)result.TypeOffset);

            result.Type = DebugEffectType.Parse(reader, typeReader, version);
            var semanticOffset = result.SemanticOffset = variableReader.ReadUInt32("SemanticOffset");

            if (semanticOffset != 0)
            {
                var semanticReader = reader.CopyAtOffset("SemanticReader", variableReader, (int)semanticOffset);
                result.Semantic = semanticReader.ReadString("Semantic");
            }
            else
            {
                result.Semantic = "";
            }
            result.BufferOffset = variableReader.ReadUInt32("BufferOffset");
            if (isShared)
            {
                return(result);
            }
            // Initializer data
            if (result.Type.ObjectType == EffectObjectType.String)
            {
                for (int i = 0; i < result.ElementCount; i++)
                {
                    var stringValueOffset = variableReader.ReadUInt32($"StringValueOffset{i}");
                    var stringValueReader = reader.CopyAtOffset($"StringValueReader{i}", variableReader, (int)stringValueOffset);
                    result.Strings.Add(stringValueReader.ReadString($"StringValue{i}"));
                }
            }
            if (IfHasAssignments(result.Type))
            {
                for (int i = 0; i < result.ElementCount; i++)
                {
                    var assignmentCount = variableReader.ReadUInt32($"AssignmentCount{i}");
                    var assignments     = new List <DebugEffectAssignment>();
                    result.Assignments.Add(assignments);
                    for (int j = 0; j < assignmentCount; j++)
                    {
                        variableReader.AddIndent($"Assignment {i}");
                        assignments.Add(DebugEffectAssignment.Parse(reader, variableReader));
                        variableReader.RemoveIndent();
                    }
                }
            }
            if (result.Type.ObjectType == EffectObjectType.GeometryShaderWithStream)
            {
                for (int i = 0; i < result.ElementCount; i++)
                {
                    variableReader.AddIndent($"GSSOInitializer {i}");
                    result.GSSOInitializers.Add(DebugEffectGSSOInitializer.Parse(reader, variableReader));
                    variableReader.RemoveIndent();
                }
            }
            else if (IsShader5(result.Type))
            {
                for (int i = 0; i < result.ElementCount; i++)
                {
                    variableReader.AddIndent($"ShaderData5 {i}");
                    result.ShaderData5.Add(DebugEffectShaderData5.Parse(reader, variableReader));
                    variableReader.RemoveIndent();
                }
            }
            else if (IsShader(result.Type))
            {
                for (int i = 0; i < result.ElementCount; i++)
                {
                    variableReader.AddIndent($"ShaderData {i}");
                    result.ShaderData.Add(DebugEffectShaderData.Parse(reader, variableReader));
                    variableReader.RemoveIndent();
                }
            }
            result.AnnotationCount = variableReader.ReadUInt32("AnnotationCount");
            for (int i = 0; i < result.AnnotationCount; i++)
            {
                variableReader.AddIndent($"Annotation {i}");
                result.Annotations.Add(DebugEffectAnnotation.Parse(reader, variableReader, version));
                variableReader.RemoveIndent();
            }
            return(result);
        }
        public static DebugInstructionToken Parse(DebugBytecodeReader reader, DebugOpcodeHeader header)
        {
            var instructionToken = new DebugInstructionToken();

            // Advance to next token.
            var instructionEnd = reader.CurrentPosition + (header.Length * sizeof(uint));
            var token0         = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);

            if (header.OpcodeType == OpcodeType.Sync)
            {
                instructionToken.SyncFlags = token0.DecodeValue <SyncFlags>(11, 14);
                reader.AddNote("SyncFlags", instructionToken.SyncFlags);
            }
            else
            {
                instructionToken.ResInfoReturnType = token0.DecodeValue <ResInfoReturnType>(11, 12);
                instructionToken.Saturate          = (token0.DecodeValue(13, 13) == 1);
                instructionToken.TestBoolean       = token0.DecodeValue <InstructionTestBoolean>(18, 18);
                instructionToken.PreciseValueMask  = token0.DecodeValue <ComponentMask>(19, 22);
                reader.AddNote("ResInfoReturnType", instructionToken.ResInfoReturnType);
                reader.AddNote("Saturate", instructionToken.Saturate);
                reader.AddNote("TestBoolean", instructionToken.TestBoolean);
                reader.AddNote("PreciseValueMask", instructionToken.PreciseValueMask);
            }

            bool extended = header.IsExtended;

            while (extended)
            {
                uint extendedToken = reader.ReadUInt32("extendedToken");
                var  extendedType  = extendedToken.DecodeValue <InstructionTokenExtendedType>(0, 5);
                reader.AddNote("extendedType", extendedType);
                instructionToken.ExtendedTypes.Add(extendedType);
                extended = (extendedToken.DecodeValue(31, 31) == 1);
                reader.AddNote("extended", extended);

                switch (extendedType)
                {
                case InstructionTokenExtendedType.SampleControls:
                    instructionToken.SampleOffsets[0] = extendedToken.DecodeSigned4BitValue(09, 12);
                    instructionToken.SampleOffsets[1] = extendedToken.DecodeSigned4BitValue(13, 16);
                    instructionToken.SampleOffsets[2] = extendedToken.DecodeSigned4BitValue(17, 20);
                    reader.AddNote("SampleOffsets[0]", instructionToken.SampleOffsets[0]);
                    reader.AddNote("SampleOffsets[1]", instructionToken.SampleOffsets[1]);
                    reader.AddNote("SampleOffsets[2]", instructionToken.SampleOffsets[2]);
                    break;

                case InstructionTokenExtendedType.ResourceDim:
                    instructionToken.ResourceTarget = extendedToken.DecodeValue <ResourceDimension>(6, 10);
                    instructionToken.ResourceStride = extendedToken.DecodeValue <ushort>(11, 22);
                    reader.AddNote("ResourceTarget", instructionToken.ResourceTarget);
                    reader.AddNote("ResourceStride", instructionToken.ResourceStride);
                    break;

                case InstructionTokenExtendedType.ResourceReturnType:
                    instructionToken.ResourceReturnTypes[0] = extendedToken.DecodeValue <ResourceReturnType>(06, 09);
                    instructionToken.ResourceReturnTypes[1] = extendedToken.DecodeValue <ResourceReturnType>(10, 13);
                    instructionToken.ResourceReturnTypes[2] = extendedToken.DecodeValue <ResourceReturnType>(14, 17);
                    instructionToken.ResourceReturnTypes[3] = extendedToken.DecodeValue <ResourceReturnType>(18, 21);
                    reader.AddNote("ResourceReturnTypes[0]", instructionToken.ResourceReturnTypes[0]);
                    reader.AddNote("ResourceReturnTypes[1]", instructionToken.ResourceReturnTypes[1]);
                    reader.AddNote("ResourceReturnTypes[2]", instructionToken.ResourceReturnTypes[2]);
                    reader.AddNote("ResourceReturnTypes[3]", instructionToken.ResourceReturnTypes[3]);
                    break;

                default:
                    throw new ParseException("Unrecognised extended type: " + extendedType);
                }
            }

            if (header.OpcodeType == OpcodeType.InterfaceCall)
            {
                instructionToken.FunctionIndex = reader.ReadUInt32("FunctionIndex");
            }

            while (reader.CurrentPosition < instructionEnd)
            {
                reader.AddIndent($"Operand{instructionToken.Operands.Count}");
                var operand = DebugOperand.Parse(reader, header.OpcodeType);
                if (operand != null)
                {
                    instructionToken.Operands.Add(operand);
                }
                reader.RemoveIndent();
            }
            return(instructionToken);
        }
        public new static DebugEffectVariableIndexAssignment Parse(DebugBytecodeReader reader, DebugBytecodeReader assignmentReader)
        {
            var result          = new DebugEffectVariableIndexAssignment();
            var arrayNameOffset = result.ArrayNameOffset = assignmentReader.ReadUInt32("ArrayNameOffset");
            var arrayNameReader = reader.CopyAtOffset("ArrayNameReader", assignmentReader, (int)arrayNameOffset);

            result.ArrayName = arrayNameReader.ReadString("ArrayName");
            var variableNameOffset = result.VariableNameOffset = assignmentReader.ReadUInt32("VariableNameOffset");
            var variableNameReader = reader.CopyAtOffset("VariableNameReader", assignmentReader, (int)variableNameOffset);

            result.VariableName = variableNameReader.ReadString("VariableName");
            return(result);
        }
        internal static DebugEffectInterfaceVariable Parse(DebugBytecodeReader reader, DebugBytecodeReader variableReader, DebugShaderVersion version)
        {
            var result     = new DebugEffectInterfaceVariable();
            var nameOffset = result.NameOffset = variableReader.ReadUInt32("NameOffset");
            var nameReader = reader.CopyAtOffset("NameReader", variableReader, (int)nameOffset);

            result.Name = nameReader.ReadString("Name");
            var typeOffset = result.TypeOffset = variableReader.ReadUInt32("TypeOffset");
            var typeReader = reader.CopyAtOffset("TypeReader", variableReader, (int)typeOffset);

            result.Type = DebugEffectType.Parse(reader, typeReader, version);
            //Pointer to InterfaceInitializer
            result.DefaultValueOffset = variableReader.ReadUInt32("DefaultValueOffset");
            var initializerReader  = reader.CopyAtOffset("InitializerReader", variableReader, (int)result.DefaultValueOffset);
            var instanceNameOffset = result.InstanceNameOffset = initializerReader.ReadUInt32("InstanceNameOffset");
            var instanceNameReader = reader.CopyAtOffset("InstanceNameReader", variableReader, (int)instanceNameOffset);

            result.InstanceName    = instanceNameReader.ReadString("InstanceName");
            result.Flags           = variableReader.ReadUInt32("Flags");
            result.AnnotationCount = variableReader.ReadUInt32("AnnotationCount");
            for (int i = 0; i < result.AnnotationCount; i++)
            {
                variableReader.AddIndent($"Annotation {i}");
                result.Annotations.Add(DebugEffectAnnotation.Parse(reader, variableReader, version));
                variableReader.RemoveIndent();
            }

            return(result);
        }