public static void TestFloat(int value) { var floatValue = ToFloat(value); if (float.IsNaN(floatValue)) { return; } string shaderCode = string.Format(@" float4 main(): sv_target {{ return asfloat({0}); }}" , value); var compiledShader = ShaderBytecode.Compile(shaderCode, "main", "ps_5_0"); var shaderBytecode = compiledShader.Bytecode; var disassembly = shaderBytecode.Disassemble(); var bytecode = BytecodeContainer.Parse(shaderBytecode); var number = bytecode.Shader.InstructionTokens.First().Operands[1].ImmediateValues; StringAssert.Contains("Generated by Microsoft (R) HLSL Shader Compiler 10.1", disassembly); var expectedFloat = Regex.Match(disassembly, @"l\((.*?),").Groups[1].Value; var actualFloat = FormatFloat(floatValue); if (value != number.Int0) { Directory.CreateDirectory(OutputDir); File.WriteAllText($"{OutputDir}/FloatParserDissassembly.asm", disassembly); return; } Assert.AreEqual(value, number.Int0, "Parsed binary represention doesn't match input"); Assert.AreEqual(expectedFloat, actualFloat, $"String format doesn't match expected for {value} {DoubleConverter.ToExactString(floatValue, -1)}"); }
public static string Decompile(byte[] data) { BytecodeContainer container = new BytecodeContainer(data); HLSLDecompiler decompiler = new HLSLDecompiler(container); return(decompiler.Decompile()); }
public void Open(string path) { _path = path; _fileName = Path.GetFileName(path); _bytecodeContainer = BytecodeContainer.Parse(File.ReadAllBytes(path)); DisassembledCode = _bytecodeContainer.ToString(); }
public static void DumpFloat(int value, StringBuilder sb) { var floatValue = ToFloat(value); if (float.IsNaN(floatValue)) { return; } string shaderCode = string.Format(@" float4 main(): sv_target {{ return asfloat({0}); }}" , value); var compiledShader = ShaderBytecode.Compile(shaderCode, "main", "ps_5_0"); var shaderBytecode = compiledShader.Bytecode; var disassembly = shaderBytecode.Disassemble(); var bytecode = BytecodeContainer.Parse(shaderBytecode); var number = bytecode.Shader.InstructionTokens.First().Operands[1].ImmediateValues; StringAssert.Contains("Generated by Microsoft (R) HLSL Shader Compiler 10.1", disassembly); var expectedFloat = Regex.Match(disassembly, @"l\((.*?),").Groups[1].Value; var actualFloat = FormatFloat(floatValue); var fullFloat = DoubleConverter.ToExactString(floatValue, -1); var correct = expectedFloat == actualFloat; if (value != number.Int0) { return; } sb.AppendLine(string.Format("{0}\t{1, 50}\t{2, 50}\t{3}\t{4}", correct, expectedFloat, actualFloat, fullFloat, value)); }
public void CanExecutePixelShaderBasicHlsl(IShaderExecutor shaderExecutor) { // Arrange. VirtualMachine.ShaderExecutor = shaderExecutor; var vm = new VirtualMachine(BytecodeContainer.Parse(File.ReadAllBytes("Shaders/PS/BasicHLSL_PS.o")), 4); vm.SetRegister(0, OperandType.ConstantBuffer, new RegisterIndex(0, 0), new Number4 { Number0 = Number.FromUInt(1) // bTexture = true }); vm.SetRegister(0, OperandType.Input, new RegisterIndex(1), new Number4(0.5f, 0.5f, 1.5f, 1)); // COLOR0 vm.SetRegister(0, OperandType.Input, new RegisterIndex(2), new Number4(0, 0, 0, 0)); // TEXCOORD0 vm.SetTexture(new RegisterIndex(0), new FakeTexture(new Number4(0.8f, 0.6f, 0.4f, 1))); vm.SetSampler(new RegisterIndex(0), new SamplerState()); // Act. vm.Execute(); // Assert. var output0 = vm.GetRegister(0, OperandType.Output, new RegisterIndex(0)); Assert.That(output0.Number0.Float, Is.EqualTo(0.4f)); Assert.That(output0.Number1.Float, Is.EqualTo(0.3f)); Assert.That(output0.Number2.Float, Is.EqualTo(0.6f)); Assert.That(output0.Number3.Float, Is.EqualTo(1)); }
public void AsmMatchesFxc(string relPath) { var file = $"{ShaderDirectory}/{relPath}"; // Arrange. var asmFileText = string.Join(Environment.NewLine, File.ReadAllLines(file + ".asm").Select(x => x.Trim())); // Act. var bytecode = File.ReadAllBytes(file + ".o"); var container = BytecodeContainer.Parse(bytecode); var decompiledAsmText = container.ToString(); File.WriteAllText($"{file}.d.asm", decompiledAsmText); File.WriteAllText($"{file}.x", FileUtil.FormatReadable(bytecode)); decompiledAsmText = string.Join(Environment.NewLine, decompiledAsmText .Split(new[] { Environment.NewLine }, StringSplitOptions.None) .Select(x => x.Trim())); decompiledAsmText = TestUtils.NormalizeAssembly(decompiledAsmText); asmFileText = TestUtils.NormalizeAssembly(asmFileText); // Assert. if (container.Chunks.OfType <DebuggingChunk>().Any()) { Warn.If(true, "Debugging information is ignored during dissasembly"); } else { Assert.That(decompiledAsmText, Is.EqualTo(asmFileText)); } }
public VirtualMachine(BytecodeContainer bytecode, int numContexts) { if (bytecode.Shader.Version.ProgramType == ProgramType.PixelShader && numContexts % 4 != 0) throw new ArgumentOutOfRangeException("numContexts", "numContexts must be a multiple of 4 for pixel shaders."); _bytecode = bytecode; var instructionTokens = bytecode.Shader.Tokens.OfType<InstructionToken>().ToArray(); var branchingInstructions = ExplicitBranchingRewriter.Rewrite(instructionTokens); var controlFlowGraph = ControlFlowGraph.FromInstructions(branchingInstructions); _executableInstructions = ExecutableInstructionRewriter.Rewrite(controlFlowGraph).ToArray(); _requiredRegisters = RequiredRegisters.FromShader(bytecode.Shader); _executionContexts = new ExecutionContext[numContexts]; for (int i = 0; i < _executionContexts.Length; i++) _executionContexts[i] = new ExecutionContext(this, i, _requiredRegisters); ConstantBuffers = new Number4[_requiredRegisters.ConstantBuffers.Count][]; for (int i = 0; i < _requiredRegisters.ConstantBuffers.Count; i++) ConstantBuffers[i] = new Number4[_requiredRegisters.ConstantBuffers[i]]; TextureSamplers = new TextureSampler[_requiredRegisters.Resources.Count]; for (int i = 0; i < _requiredRegisters.Resources.Count; i++) TextureSamplers[i] = TextureSamplerFactory.Create(_requiredRegisters.Resources[i]); Textures = new ITexture[_requiredRegisters.Resources.Count]; Samplers = new SamplerState[_requiredRegisters.Samplers]; }
public static string Decompile(byte[] data) { var container = new BytecodeContainer(data); if (container.Chunks.OfType <LibfChunk>().Any()) { var sb = new StringBuilder(); foreach (var lib in container.Chunks.OfType <LibfChunk>()) { var libDecompiler = new DXDecompiler(lib.LibraryContainer); sb.AppendLine(libDecompiler.Decompile()); } return(sb.ToString()); } if (container.Chunks.OfType <EffectChunk>().Any()) { return(container.Chunks .OfType <EffectChunk>() .First() .ToString()); } var decompiler = new DXDecompiler(container); return(decompiler.Decompile()); }
/// <summary> /// Creates a new instance of the Shader class. /// </summary> /// <param name="shaderBytecode">Byte array containing the compiled shader bytecode.</param> public Shader(byte[] shaderBytecode) { var bytecodeContainer = new BytecodeContainer(shaderBytecode); var programType = bytecodeContainer.Shader.Version.ProgramType; switch (programType) { case ProgramType.GeometryShader: case ProgramType.HullShader: case ProgramType.DomainShader: case ProgramType.ComputeShader: throw new NotSupportedException(string.Format( "The '{0}' shader type is not yet supported.", bytecodeContainer.Shader.Version.ProgramType)); } _constantBuffers = bytecodeContainer.ResourceDefinition.ConstantBuffers; _resourceBindings = bytecodeContainer.ResourceDefinition.ResourceBindings; _inputSignature = bytecodeContainer.InputSignature; _inputSignatureSize = _inputSignature.Parameters.Sum(x => x.ByteCount); _outputSignature = bytecodeContainer.OutputSignature; _outputSignatureSize = _outputSignature.Parameters.Sum(x => x.ByteCount); var numContexts = (programType == ProgramType.PixelShader) ? 4 : 1; _virtualMachine = new VirtualMachine(bytecodeContainer, numContexts); }
public static void CompareEffect(BytecodeContainer container, byte[] effectBytecode, string testName) { var device = new Device( DriverType.Warp, DeviceCreationFlags.Debug, FeatureLevel.Level_10_1); Effect effectReflection = null; if (container == null) { effectReflection = new Effect(device, effectBytecode, EffectFlags.None); Warn.If(true, "Container is null"); return; } var chunk = container.Chunks.OfType <EffectChunk>().First(); if (chunk.IsChildEffect) { effectReflection = new Effect(device, effectBytecode, EffectFlags.None); //var effectPool = new EffectPool(device, effectBytecode, EffectFlags.None); //effectReflection = effectPool.AsEffect(); } else { effectReflection = new Effect(device, effectBytecode, EffectFlags.None); } EffectDescription desc = effectReflection.Description; var header = chunk.Header; //Assert.AreEqual((bool)desc.IsChildEffect, header.SharedConstantBuffers > 0); Assert.AreEqual(desc.ConstantBufferCount, header.ConstantBuffers); //Assert.AreEqual(desc.SharedConstantBufferCount, header.SharedConstantBuffers); Assert.AreEqual(desc.GlobalVariableCount, header.GlobalVariables + header.ObjectCount); //Assert.AreEqual(desc.SharedGlobalVariableCount, header.SharedGlobalVariables); Assert.AreEqual(desc.TechniqueCount, header.Techniques); var reflectionConstantBufferCount = GetBufferCount(effectReflection); Assert.AreEqual(reflectionConstantBufferCount, header.ConstantBuffers + header.SharedConstantBuffers); var reflectionVariableCount = GetVariableCount(effectReflection); Assert.AreEqual(reflectionVariableCount, header.ObjectCount + header.SharedObjectCount + header.GlobalVariables + header.SharedGlobalVariables); var variables = chunk.AllVariables.ToList(); var reflectionVariables = GetEffectVariables(effectReflection); var reflectionNames = reflectionVariables .Select(v => $"{v.Description.Name}, {v.TypeInfo.Description.Type}, {v.TypeInfo.Description.Class}") .ToList(); for (int i = 0; i < desc.GlobalVariableCount; i++) { CompareVariable(reflectionVariables[i], variables[i]); } var buffers = chunk.AllBuffers.ToList(); for (int i = 0; i < desc.ConstantBufferCount; i++) { var cb = effectReflection.GetConstantBufferByIndex(i); //CompareConstantBuffer(cb, buffers[i]); } }
public static BytecodeChunk Parse(BytecodeReader reader, uint chunkSize, BytecodeContainer container) { var result = new FxlcChunk(); var chunkReader = reader.CopyAtCurrentPosition(); result.Fxlc = FxlcBlock.Parse(chunkReader); return(result); }
private static void CompareLibrary(BytecodeContainer container, byte[] shaderBytecode) { var libReflection = new LibraryReflection(shaderBytecode); var libHeader = container.Chunks.OfType <LibHeaderChunk>().First(); var desc = libReflection.Description; Assert.AreEqual(desc.Creator, libHeader.CreatorString); Assert.AreEqual(desc.FunctionCount, libHeader.FunctionDescs.Count); Assert.AreEqual(desc.Flags, 0); }
public new static EffectExpressionAssignment Parse(BytecodeReader reader, BytecodeReader assignmentReader) { var result = new EffectExpressionAssignment(); var shaderSize = assignmentReader.ReadUInt32(); if (shaderSize != 0) { result.Shader = BytecodeContainer.Parse(assignmentReader.ReadBytes((int)shaderSize)); } return(result); }
public static void CompareEffect(BytecodeContainer container, byte[] effectBytecode, string testName) { var chunk = container.Chunks.OfType <Fx10.EffectChunk>().First(); if (chunk.Header.Techniques == 0) { return; } if (chunk.Header.Version.MinorVersion == 1) { Assert.Warn("Version fx_4_1 is not supported by SharpDX"); return; } if (chunk.IsChildEffect) { Assert.Warn("Child Effects are not supported by SharpDX"); return; } var device = new Device(DriverType.Warp, DeviceCreationFlags.Debug); var effectReflection = new Effect(device, effectBytecode, EffectFlags.None); EffectDescription desc = effectReflection.Description; var header = chunk.Header; Assert.AreEqual((bool)desc.IsChildEffect, header.SharedConstantBuffers > 0); Assert.AreEqual(desc.ConstantBufferCount, header.ConstantBuffers); Assert.AreEqual(desc.SharedConstantBufferCount, header.SharedConstantBuffers); Assert.AreEqual(desc.GlobalVariableCount, header.GlobalVariables + header.ObjectCount); Assert.AreEqual(desc.SharedGlobalVariableCount, header.SharedGlobalVariables); Assert.AreEqual(desc.TechniqueCount, header.Techniques); var variables = chunk.AllVariables.ToList(); var reflectionVariables = GetEffectVariables(effectReflection); var reflectionNames = reflectionVariables .Select(v => $"{v.Description.Name}, {v.TypeInfo.Description.Type}, {v.TypeInfo.Description.Class}") .ToList(); for (int i = 0; i < desc.GlobalVariableCount + desc.SharedGlobalVariableCount; i++) { CompareVariable(reflectionVariables[i], variables[i]); } var buffers = chunk.AllBuffers.ToList(); var reflectionBuffers = effectReflection.GetConstantBuffers(); for (int i = 0; i < desc.ConstantBufferCount + desc.SharedConstantBufferCount; i++) { CompareConstantBuffer(reflectionBuffers[i], buffers[i]); } var techniques = effectReflection.GetTechniques(); for (int i = 0; i < desc.TechniqueCount; i++) { CompareTechniques(techniques[i], chunk.Techniques[i]); } }
internal IEnumerable <FragmentQuad> Execute( IEnumerable <InputAssemblerPrimitiveOutput> inputs, PrimitiveTopology primitiveTopology, OutputSignatureChunk previousStageOutputSignature, BytecodeContainer pixelShader, int multiSampleCount) { // TODO: Allow selection of different viewport. var viewport = _viewports[0]; var outputInputBindings = ShaderOutputInputBindings.FromShaderSignatures( previousStageOutputSignature, pixelShader); var rasterizer = PrimitiveRasterizerFactory.CreateRasterizer( primitiveTopology, State.Description, multiSampleCount, outputInputBindings, ref viewport, FragmentFilter); foreach (var primitive in inputs) { // Frustum culling. if (ViewportCuller.ShouldCullTriangle(primitive.Vertices)) { continue; } // TODO: Clipping. // http://simonstechblog.blogspot.tw/2012/04/software-rasterizer-part-2.html#softwareRasterizerDemo // Perspective divide. for (int i = 0; i < primitive.Vertices.Length; i++) { PerspectiveDivide(ref primitive.Vertices[i].Position); } // Backface culling. if (State.Description.CullMode != CullMode.None && rasterizer.ShouldCull(primitive.Vertices)) { continue; } // Transform from clip space to screen space. for (int i = 0; i < primitive.Vertices.Length; i++) { viewport.MapClipSpaceToScreenSpace(ref primitive.Vertices[i].Position); } // Rasterize. foreach (var fragmentQuad in rasterizer.Rasterize(primitive)) { yield return(fragmentQuad); } } }
static void ParseLibrary(IrShader shader, BytecodeContainer container) { var libraryHeader = container.Chunks.OfType <LibHeaderChunk>().Single(); var libraryFunctions = container.Chunks.OfType <LibfChunk>().ToArray(); for (int i = 0; i < libraryFunctions.Length; i++) { var pass = new IrPass(libraryHeader.FunctionDescs[i].Name, IrPass.PassType.FunctionBody); InstructionParser.ParseTokens(pass, libraryFunctions[i].LibraryContainer.Shader.Tokens); shader.Passes.Add(pass); } }
public static DebugEffectShaderData Parse(DebugBytecodeReader reader, DebugBytecodeReader variableReader) { var result = new DebugEffectShaderData(); var shaderOffset = result.ShaderOffset = variableReader.ReadUInt32("ShaderOffset"); var bytecodeReader = reader.CopyAtOffset("BytecodeReader", variableReader, (int)shaderOffset); var shaderSize = bytecodeReader.ReadUInt32("ShaderSize"); if (shaderSize != 0) { result.Shader = BytecodeContainer.Parse(bytecodeReader.ReadBytes("Shader", (int)shaderSize)); } return(result); }
public static EffectShaderData Parse(BytecodeReader reader, BytecodeReader variableReader) { var result = new EffectShaderData(); var shaderOffset = variableReader.ReadUInt32(); var bytecodeReader = reader.CopyAtOffset((int)shaderOffset); var shaderSize = bytecodeReader.ReadUInt32(); if (shaderSize != 0) { result.Shader = BytecodeContainer.Parse(bytecodeReader.ReadBytes((int)shaderSize)); } return(result); }
public void PerformanceTest(IShaderExecutor shaderExecutor) { var bytecodeContainer = BytecodeContainer.Parse(File.ReadAllBytes("Shaders/VS/BasicHLSL_VS.o")); VirtualMachine.ShaderExecutor = shaderExecutor; var vm = new VirtualMachine(bytecodeContainer, 1); var globals = new BasicHlsl.ConstantBufferGlobals { WorldViewProjection = Matrix.LookAtRH(Vector3.UnitZ, Vector3.Zero, Vector3.UnitY) * Matrix.PerspectiveFovRH(MathUtil.PiOverFour, 1, 1, 10) }; var vertexInput = new VertexPositionNormalTexture { Position = new Vector4(3, 0, 2, 1), Normal = new Vector3(0, 1, 0), TextureCoordinate = new Vector2(0, 1) }; SetConstantBuffer(vm, 0, globals); vm.SetRegister(0, OperandType.ConstantBuffer, new RegisterIndex(1, 0), new Number4 { Number0 = Number.FromInt(3), // nNumLights = 3 Number1 = Number.FromInt(1) // bTexture = true }); vm.SetRegister(0, OperandType.Input, new RegisterIndex(0), vertexInput.Position.ToNumber4()); vm.SetRegister(0, OperandType.Input, new RegisterIndex(1), vertexInput.Normal.ToNumber4()); vm.SetRegister(0, OperandType.Input, new RegisterIndex(2), vertexInput.TextureCoordinate.ToNumber4()); // Prime the pump by executing shader once. vm.Execute(); var stopwatch = new Stopwatch(); stopwatch.Start(); const int iterations = 100000; for (var i = 0; i < iterations; i++) { vm.Execute(); } stopwatch.Stop(); Debug.WriteLine("Time: " + stopwatch.Elapsed); }
public void ParsedShaderOutputMatchesFxcOutput(string file) { // Arrange. var asmFileText = string.Join(Environment.NewLine, File.ReadAllLines(file + ".asm").Select(x => x.Trim())); // Act. var container = BytecodeContainer.Parse(File.ReadAllBytes(file + ".o")); var decompiledAsmText = string.Join(Environment.NewLine, container.ToString() .Split(new[] { Environment.NewLine }, StringSplitOptions.None) .Select(x => x.Trim())); // Assert. Assert.That(decompiledAsmText, Is.EqualTo(asmFileText)); }
public RegisterState(BytecodeContainer container) { Container = container; InitContantBuffers(); InitResources(); InitDeclarations(); if (Container.LibrarySignature != null) { InitLibraryParams(); } else { InitInputAndOutput(); } InitResourceBindings(); }
public void CanExecuteSimplePixelShader(IShaderExecutor shaderExecutor) { // Arrange. VirtualMachine.ShaderExecutor = shaderExecutor; var vm = new VirtualMachine(BytecodeContainer.Parse(File.ReadAllBytes("Shaders/PS/Simple.o")), 4); // Act. vm.Execute(); // Assert. var output0 = vm.GetRegister(0, OperandType.Output, new RegisterIndex(0)); Assert.That(output0.Number0.Float, Is.EqualTo(1.0f)); Assert.That(output0.Number1.Float, Is.EqualTo(0.5f)); Assert.That(output0.Number2.Float, Is.EqualTo(0.4f)); Assert.That(output0.Number3.Float, Is.EqualTo(1.0f)); }
internal static void WriteRootSignature(BytecodeContainer container, StringBuilder output, bool wrap = true) { var signature = container.Chunks .OfType <RootSignatureChunk>() .FirstOrDefault(); if (signature == null) { return; } var result = new RootSignature().RootSignatureToString(signature); result = Regex.Replace(result, @"^(\s*)([^\n\r]*)", @"$1""$2"" \", RegexOptions.Multiline); result = result.Substring(0, result.Length - 2); output.AppendLine(@"#define RS1 \"); output.AppendLine(result); }
public new static EffectInlineShaderAssignment Parse(BytecodeReader reader, BytecodeReader assignmentReader) { var result = new EffectInlineShaderAssignment(); var shaderOffset = assignmentReader.ReadUInt32(); var SODeclOffset = assignmentReader.ReadUInt32(); var shaderReader = reader.CopyAtOffset((int)shaderOffset); var shaderSize = shaderReader.ReadUInt32(); if (shaderSize != 0) { result.Shader = BytecodeContainer.Parse(shaderReader.ReadBytes((int)shaderSize)); } var SODeclReader = reader.CopyAtOffset((int)SODeclOffset); result.SODecl = SODeclReader.ReadString(); return(result); }
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 void CanExecuteVertexShaderBasicHlsl(IShaderExecutor shaderExecutor) { // Arrange. VirtualMachine.ShaderExecutor = shaderExecutor; var vm = new VirtualMachine(BytecodeContainer.Parse(File.ReadAllBytes("Shaders/VS/BasicHLSL_VS.o")), 1); var globals = new BasicHlsl.ConstantBufferGlobals { WorldViewProjection = Matrix.LookAtRH(Vector3.UnitZ, Vector3.Zero, Vector3.UnitY) * Matrix.PerspectiveFovRH(MathUtil.PiOverFour, 1, 1, 10), NumLights = 3 }; var vertexInput = new VertexPositionNormalTexture { Position = new Vector4(3, 0, 2, 1), Normal = new Vector3(0, 1, 0), TextureCoordinate = new Vector2(0, 1) }; var direct3DResult = Direct3DUtility.ExecuteVertexShader("Shaders/VS/BasicHLSL_VS.o", globals, vertexInput); SetConstantBuffer(vm, 0, globals); vm.SetConstantBufferRegisterValue(1, 0, new Number4 { Number0 = Number.FromInt(3), // nNumLights = 3 Number1 = Number.FromInt(1) // bTexture = true }); vm.SetInputRegisterValue(0, 0, 0, vertexInput.Position.ToNumber4()); vm.SetInputRegisterValue(0, 0, 1, vertexInput.Normal.ToNumber4()); vm.SetInputRegisterValue(0, 0, 2, vertexInput.TextureCoordinate.ToNumber4()); // Act. vm.Execute(); // Assert. var output0 = vm.GetOutputRegisterValue(0, 0); Assert.That(output0.Number0.Float, Is.EqualTo(direct3DResult.Position.X)); Assert.That(output0.Number1.Float, Is.EqualTo(direct3DResult.Position.Y)); Assert.That(output0.Number2.Float, Is.EqualTo(direct3DResult.Position.Z)); Assert.That(output0.Number3.Float, Is.EqualTo(direct3DResult.Position.W)); }
public new static EffectExpressionIndexAssignment Parse(BytecodeReader reader, BytecodeReader assignmentReader) { var result = new EffectExpressionIndexAssignment(); var arrayNameOffset = assignmentReader.ReadUInt32(); var arrayNameReader = reader.CopyAtOffset((int)arrayNameOffset); result.ArrayName = arrayNameReader.ReadString(); var shaderOffset = assignmentReader.ReadUInt32(); var shaderReader = reader.CopyAtOffset((int)shaderOffset); var shaderSize = shaderReader.ReadUInt32(); if (shaderSize != 0) { result.Shader = BytecodeContainer.Parse(shaderReader.ReadBytes((int)shaderSize)); } return(result); }
public Interfaces(BytecodeContainer container) { Container = container; List <OpcodeToken> currentBody = null; foreach (var token in container.Shader.Tokens) { switch (token.Header.OpcodeType) { case OpcodeType.DclFunctionBody: break; case OpcodeType.DclFunctionTable: { var dcl = token as FunctionTableDeclarationToken; FunctionTables[$"ft{dcl.Identifier}"] = dcl.FunctionBodyIndices .Select(i => $"fb{i}") .ToList(); break; } case OpcodeType.DclInterface: break; case OpcodeType.Label: { var inst = token as InstructionToken; var operand = inst.Operands[0]; currentBody = new List <OpcodeToken>(); currentBody.Add(token); FunctionBodies[operand.ToString()] = currentBody; break; } default: if (currentBody != null) { currentBody.Add(token); } break; } } //TODO: Merge Duplicate function bodies }
public void Parse(IrShader shader, BytecodeContainer container) { FunctionTables = new Dictionary <string, List <string> >(); foreach (var dcl in container.Shader.DeclarationTokens) { if (dcl is FunctionTableDeclarationToken ft) { FunctionTables[$"ft{ft.Identifier}"] = ft.FunctionBodyIndices .Select(i => $"fb{i}") .ToList(); } } var passes = shader.Passes .Where(p => p.Type == IrPass.PassType.FunctionBody) .ToDictionary(p => (p.Instructions.First().Token as InstructionToken).Operands.First().ToString()); foreach (var kv in passes) { AddLabelPass(kv.Value); } foreach (var type in Chunk.AvailableClassTypes) { var @class = new IrClass(); @class.Name = type.Name; var keys = FunctionTables[$"ft{type.ID}"]; foreach (var key in keys) { var pass = passes[key]; @class.Passes.Add(pass); } Classes.Add(@class); } var rdef = container.ResourceDefinition; var cbVariables = rdef.ConstantBuffers .Where(cb => cb.BufferType == ConstantBufferType.InterfacePointers) .Single() .Variables; foreach (var type in cbVariables) { var @interface = new IrInterface(); @interface.Name = GetInterfaceShaderTypeName(type.ShaderType); } }
public static EffectGSSOInitializer Parse(BytecodeReader reader, BytecodeReader variableReader) { var result = new EffectGSSOInitializer(); var shaderOffset = variableReader.ReadUInt32(); var SODeclOffset = variableReader.ReadUInt32(); var bytecodeReader = reader.CopyAtOffset((int)shaderOffset); var shaderSize = bytecodeReader.ReadUInt32(); if (shaderSize != 0) { result.Shader = BytecodeContainer.Parse(bytecodeReader.ReadBytes((int)shaderSize)); } var declReader = reader.CopyAtOffset((int)SODeclOffset); result.SODecl = declReader.ReadString(); return(result); }
public static DebugEffectGSSOInitializer Parse(DebugBytecodeReader reader, DebugBytecodeReader variableReader) { var result = new DebugEffectGSSOInitializer(); var shaderOffset = result.ShaderOffset = variableReader.ReadUInt32("ShaderOffset"); var SODeclOffset = result.SODeclOffset = variableReader.ReadUInt32("SODeclOffset"); var bytecodeReader = reader.CopyAtOffset("BytecodeReader", variableReader, (int)shaderOffset); var shaderSize = bytecodeReader.ReadUInt32("ShaderSize"); if (shaderSize != 0) { result.Shader = BytecodeContainer.Parse(bytecodeReader.ReadBytes("Shader", (int)shaderSize)); } var declReader = reader.CopyAtOffset("DeclReader", variableReader, (int)SODeclOffset); result.SODecl = declReader.ReadString("SODecl"); return(result); }
public static BytecodeChunk ParseChunk(BytecodeReader chunkReader, BytecodeContainer container) { // Type of chunk this is. uint fourCc = chunkReader.ReadUInt32(); // Total length of the chunk in bytes. uint chunkSize = chunkReader.ReadUInt32(); ChunkType chunkType; if (KnownChunkTypes.ContainsKey(fourCc)) { chunkType = KnownChunkTypes[fourCc]; } else { System.Diagnostics.Debug.WriteLine("Chunk type '" + fourCc.ToFourCcString() + "' is not yet supported."); return null; } var chunkContentReader = chunkReader.CopyAtCurrentPosition((int) chunkSize); BytecodeChunk chunk; switch (chunkType) { case ChunkType.Ifce : chunk = InterfacesChunk.Parse(chunkContentReader, chunkSize); break; case ChunkType.Isgn : case ChunkType.Osgn: case ChunkType.Osg5: case ChunkType.Pcsg: chunk = InputOutputSignatureChunk.Parse(chunkContentReader, chunkType, container.ResourceDefinition.Target.ProgramType); break; case ChunkType.Rdef: chunk = ResourceDefinitionChunk.Parse(chunkContentReader); break; case ChunkType.Sdbg : case ChunkType.Spdb : chunk = DebuggingChunk.Parse(chunkContentReader, chunkType, (int) chunkSize); break; case ChunkType.Sfi0: chunk = Sfi0Chunk.Parse(chunkContentReader); break; case ChunkType.Shdr: case ChunkType.Shex: chunk = ShaderProgramChunk.Parse(chunkContentReader); break; case ChunkType.Stat: chunk = StatisticsChunk.Parse(chunkContentReader, chunkSize); break; default : throw new ParseException("Invalid chunk type: " + chunkType); } chunk.Container = container; chunk.FourCc = fourCc; chunk.ChunkSize = chunkSize; chunk.ChunkType = chunkType; return chunk; }