private static void GenerateSetRegisterValue(StringBuilder sb, Operand operand, string contextName = "context") { var register = GetRegister(operand, contextName); if (operand.ComponentMask.HasFlag(ComponentMask.X) && operand.ComponentMask.HasFlag(ComponentMask.Y) && operand.ComponentMask.HasFlag(ComponentMask.Z) && operand.ComponentMask.HasFlag(ComponentMask.W)) { sb.AppendLineIndent(2, " {0} = result;", register); return; } if (operand.ComponentMask.HasFlag(ComponentMask.X)) { sb.AppendLineIndent(2, " {0}.Number0 = result.Number0;", register); } if (operand.ComponentMask.HasFlag(ComponentMask.Y)) { sb.AppendLineIndent(2, " {0}.Number1 = result.Number1;", register); } if (operand.ComponentMask.HasFlag(ComponentMask.Z)) { sb.AppendLineIndent(2, " {0}.Number2 = result.Number2;", register); } if (operand.ComponentMask.HasFlag(ComponentMask.W)) { sb.AppendLineIndent(2, " {0}.Number3 = result.Number3;", register); } }
private static void GenerateExecute1(StringBuilder sb, ExecutableInstruction instruction, string methodName) { sb.AppendLineIndent(2, "foreach (var context in activeExecutionContexts)"); sb.AppendLineIndent(2, "{"); sb.AppendLineIndent(2, " var src0 = {0};", GenerateGetOperandValue(instruction.Operands[1], NumberType.Float)); sb.AppendLineIndent(2, " var result = InstructionImplementations.{0}({1}, ref src0);", methodName, instruction.Saturate.ToString().ToLower()); GenerateSetRegisterValue(sb, instruction.Operands[0]); sb.AppendLineIndent(2, "}"); }
private static string GenerateNonDivergent(ExecutableInstruction[] instructions) { var instructionsCode = new StringBuilder(); int instructionIndex = 0; foreach (var instruction in instructions) { instructionsCode.AppendLineIndent(2, "// " + instruction); GenerateInstructionCode(instructionsCode, instruction); instructionsCode.AppendLine(); ++instructionIndex; } return @" using System.Collections; using System.Collections.Generic; using SlimShader; using SlimShader.VirtualMachine; using SlimShader.VirtualMachine.Analysis.ExecutableInstructions; using SlimShader.VirtualMachine.Execution; public static class DynamicShaderExecutor { public static IEnumerable<ExecutionResponse> Execute( VirtualMachine virtualMachine, ExecutionContext[] executionContexts, ExecutableInstruction[] instructions) { var activeExecutionContexts = executionContexts; " + instructionsCode + @" } }"; }
private static string GenerateNonDivergent(ExecutableInstruction[] instructions) { var instructionsCode = new StringBuilder(); int instructionIndex = 0; foreach (var instruction in instructions) { instructionsCode.AppendLineIndent(2, "// " + instruction); GenerateInstructionCode(instructionsCode, instruction); instructionsCode.AppendLine(); ++instructionIndex; } return(@" using System.Collections; using System.Collections.Generic; using SlimShader; using SlimShader.VirtualMachine; using SlimShader.VirtualMachine.Analysis.ExecutableInstructions; using SlimShader.VirtualMachine.Execution; public static class DynamicShaderExecutor { public static IEnumerable<ExecutionResponse> Execute( VirtualMachine virtualMachine, ExecutionContext[] executionContexts, ExecutableInstruction[] instructions) { var activeExecutionContexts = executionContexts; " + instructionsCode + @" } }"); }
private static void GenerateSetRegisterValueScalar(StringBuilder sb, Operand operand) { var register = GetRegister(operand); if (operand.ComponentMask.HasFlag(ComponentMask.X)) { sb.AppendLineIndent(2, " {0}.Number0 = result;", register); } if (operand.ComponentMask.HasFlag(ComponentMask.Y)) { sb.AppendLineIndent(2, " {0}.Number1 = result;", register); } if (operand.ComponentMask.HasFlag(ComponentMask.Z)) { sb.AppendLineIndent(2, " {0}.Number2 = result;", register); } if (operand.ComponentMask.HasFlag(ComponentMask.W)) { sb.AppendLineIndent(2, " {0}.Number3 = result;", register); } }
public static string FormatName(this MethodDefinition method) { if (method == null) return String.Empty; string name = method.Name; var sb = new StringBuilder (); if (method.HasCustomAttributes) sb.Append (method.CustomAttributes.Format ()); sb.AppendIndent (FormatAttributes (method)); if (!method.IsSpecialName) { sb.Append (FormatName (method.ReturnType)); sb.Append (' '); } else if (method.IsAccessor ()) return String.Empty; if (method.IsConstructor) sb.Append (FormatGenericTypeName (method.DeclaringType.Name)); else if (name == "Finalize") sb.Append ("~" + FormatGenericTypeName (method.DeclaringType.Name)); else if (method.IsSpecialName) sb.Append (TranslateSpecialName (method)); else if (method.IsExplicitImplementation ()) { TypeReference iface; MethodReference ifaceMethod; method.GetInfoForExplicitlyImplementedMethod (out iface, out ifaceMethod); if (iface != null) { sb.Append (FormatName (iface)); sb.Append ('.'); sb.Append (ifaceMethod.Name); } else sb.Append (method.Name); } else sb.Append (name); bool first = true; if (method.HasGenericParameters) { sb.Append ('<'); foreach (GenericParameter gp in method.GenericParameters) { if (!first) sb.Append (", "); else first = false; sb.Append (FormatName (gp)); } sb.Append ("> "); } sb.Append (" ("); if (method.HasParameters) { first = true; foreach (ParameterDefinition p in method.Parameters) { if (!first) sb.Append (", "); else first = false; sb.Append (FormatName (p)); } } sb.Append (")"); if (method.IsAbstract || method.DeclaringType.IsInterface) sb.AppendLine (";"); else { sb.AppendLine (); sb.AppendLineIndent ("{"); try { Utils.Indent++; sb.AppendLineIndent ("throw new NotImplementedException ();"); } finally { Utils.Indent--; } sb.AppendLineIndent ("}"); sb.AppendLine (); } return sb.ToString (); }
public static string FormatName(this PropertyDefinition prop) { if (prop == null) return String.Empty; var sb = new StringBuilder (); if (prop.HasCustomAttributes) sb.Append (prop.CustomAttributes.Format ()); MethodDefinition getter = prop.GetMethod; MethodDefinition setter = prop.SetMethod; MethodDefinition accessor = null; ushort getterAccessMask; ushort setterAccessMask; ushort propAccessMask; GatherAccessorInfo (getter, setter, out accessor, out propAccessMask, out getterAccessMask, out setterAccessMask); sb.AppendIndent (FormatAttributes (accessor)); sb.Append (FormatName (prop.PropertyType)); sb.Append (' '); if (prop.HasParameters) { sb.Append ("this ["); bool first = true; foreach (ParameterDefinition p in prop.Parameters) { if (!first) sb.Append (", "); else first = false; sb.Append (FormatName (p)); } sb.Append ("]"); } else if (accessor.IsExplicitImplementation ()) { TypeReference iface; MethodReference ifaceMethod; accessor.GetInfoForExplicitlyImplementedMethod (out iface, out ifaceMethod); if (iface != null) { sb.Append (iface.Name); sb.Append ('.'); string name = prop.Name; string iname = iface.FullName + "."; if (name.StartsWith (iname, StringComparison.OrdinalIgnoreCase)) sb.Append (name.Substring (iname.Length)); else sb.Append (name); } else sb.Append (prop.Name); } else sb.Append (prop.Name); sb.Append (' '); sb.Append ("{"); sb.Append (FormatAccessor ("get", getter, getterAccessMask != propAccessMask)); sb.Append (FormatAccessor ("set", setter, setterAccessMask != propAccessMask)); sb.AppendLine (); sb.AppendLineIndent ("}"); sb.AppendLine (); return sb.ToString (); }
public static string FormatName(this EventDefinition ev) { if (ev == null) return String.Empty; var sb = new StringBuilder (); if (ev.HasCustomAttributes) sb.Append (ev.CustomAttributes.Format ()); MethodDefinition adder = ev.AddMethod; MethodDefinition remover = ev.RemoveMethod; MethodDefinition accessor = null; ushort adderAccessMask; ushort removerAccessMask; ushort evAccessMask; GatherAccessorInfo (adder, remover, out accessor, out evAccessMask, out adderAccessMask, out removerAccessMask); sb.AppendIndent (FormatAttributes (accessor)); sb.Append ("event "); sb.Append (FormatName (ev.EventType)); sb.Append (' '); sb.Append (ev.Name); sb.Append (' '); sb.Append ("{"); sb.Append (FormatAccessor ("add", adder, adderAccessMask != evAccessMask)); sb.Append (FormatAccessor ("remove", remover, removerAccessMask != evAccessMask)); sb.AppendLine (); sb.AppendLineIndent ("}"); sb.AppendLine (); return sb.ToString (); }
private static void GenerateSetRegisterValueScalar(StringBuilder sb, Operand operand) { var register = GetRegister(operand); if (operand.ComponentMask.HasFlag(ComponentMask.X)) sb.AppendLineIndent(2, " {0}.Number0 = result;", register); if (operand.ComponentMask.HasFlag(ComponentMask.Y)) sb.AppendLineIndent(2, " {0}.Number1 = result;", register); if (operand.ComponentMask.HasFlag(ComponentMask.Z)) sb.AppendLineIndent(2, " {0}.Number2 = result;", register); if (operand.ComponentMask.HasFlag(ComponentMask.W)) sb.AppendLineIndent(2, " {0}.Number3 = result;", register); }
private static void GenerateSetRegisterValue(StringBuilder sb, Operand operand, string contextName = "context") { var register = GetRegister(operand, contextName); if (operand.ComponentMask.HasFlag(ComponentMask.X) && operand.ComponentMask.HasFlag(ComponentMask.Y) && operand.ComponentMask.HasFlag(ComponentMask.Z) && operand.ComponentMask.HasFlag(ComponentMask.W)) { sb.AppendLineIndent(2, " {0} = result;", register); return; } if (operand.ComponentMask.HasFlag(ComponentMask.X)) sb.AppendLineIndent(2, " {0}.Number0 = result.Number0;", register); if (operand.ComponentMask.HasFlag(ComponentMask.Y)) sb.AppendLineIndent(2, " {0}.Number1 = result.Number1;", register); if (operand.ComponentMask.HasFlag(ComponentMask.Z)) sb.AppendLineIndent(2, " {0}.Number2 = result.Number2;", register); if (operand.ComponentMask.HasFlag(ComponentMask.W)) sb.AppendLineIndent(2, " {0}.Number3 = result.Number3;", register); }
private static void GenerateExecute3(StringBuilder sb, ExecutableInstruction instruction, string methodName) { sb.AppendLineIndent(2, "foreach (var context in activeExecutionContexts)"); sb.AppendLineIndent(2, "{"); sb.AppendLineIndent(2, " var src0 = {0};", GenerateGetOperandValue(instruction.Operands[1], NumberType.Float)); sb.AppendLineIndent(2, " var src1 = {0};", GenerateGetOperandValue(instruction.Operands[2], NumberType.Float)); sb.AppendLineIndent(2, " var src2 = {0};", GenerateGetOperandValue(instruction.Operands[3], NumberType.Float)); sb.AppendLineIndent(2, " var result = InstructionImplementations.{0}({1}, ref src0, ref src1, ref src2);", methodName, instruction.Saturate.ToString().ToLower()); GenerateSetRegisterValue(sb, instruction.Operands[0]); sb.AppendLineIndent(2, "}"); }
private static string GenerateDivergent(ExecutableInstruction[] instructions) { var instructionsCode = new StringBuilder(); int instructionIndex = 0; foreach (var instruction in instructions) { instructionsCode.AppendLineIndent(4, "case {0}:", instructionIndex); instructionsCode.AppendLineIndent(4, "{"); instructionsCode.AppendLineIndent(5, "// " + instruction); GenerateInstructionCode(instructionsCode, instruction); instructionsCode.AppendLine(); if (instruction is DivergentExecutableInstruction) instructionsCode.AppendLineIndent(5, "if (instruction.UpdateDivergenceStack(warp.DivergenceStack, activeMasks))"); else instructionsCode.AppendLineIndent(5, "if (instruction.UpdateDivergenceStack(warp.DivergenceStack, null))"); instructionsCode.AppendLineIndent(5, "{"); instructionsCode.AppendLineIndent(5, " activeExecutionContexts = Warp.GetActiveExecutionContexts(executionContexts, topOfDivergenceStack);"); instructionsCode.AppendLineIndent(5, " topOfDivergenceStack = warp.DivergenceStack.Peek();"); instructionsCode.AppendLineIndent(5, "}"); instructionsCode.AppendLineIndent(5, "break;"); instructionsCode.AppendLineIndent(4, "}"); instructionsCode.AppendLine(); ++instructionIndex; } return @" using System.Collections; using System.Collections.Generic; using SlimShader; using SlimShader.VirtualMachine; using SlimShader.VirtualMachine.Analysis.ExecutableInstructions; using SlimShader.VirtualMachine.Execution; public static class DynamicShaderExecutor { public static IEnumerable<ExecutionResponse> Execute( VirtualMachine virtualMachine, ExecutionContext[] executionContexts, ExecutableInstruction[] instructions) { var warp = new Warp(executionContexts.Length); var activeExecutionContexts = Warp.GetActiveExecutionContexts(executionContexts, warp.DivergenceStack.Peek()); var topOfDivergenceStack = warp.DivergenceStack.Peek(); while (topOfDivergenceStack.NextPC < instructions.Length) { var instruction = instructions[topOfDivergenceStack.NextPC]; switch (topOfDivergenceStack.NextPC) { " + instructionsCode + @" } } } }"; }
private static void GenerateInstructionCode(StringBuilder sb, ExecutableInstruction instruction) { switch (instruction.OpcodeType) { case Execution.ExecutableOpcodeType.Add: GenerateExecute2(sb, instruction, "Add"); break; case Execution.ExecutableOpcodeType.Branch : break; case Execution.ExecutableOpcodeType.BranchC : sb.AppendLineIndent(2, "var activeMasks = new List<BitArray>"); sb.AppendLineIndent(2, "{"); sb.AppendLineIndent(2, " new BitArray(executionContexts.Length),"); sb.AppendLineIndent(2, " new BitArray(executionContexts.Length)"); sb.AppendLineIndent(2, "};"); sb.AppendLineIndent(2, "foreach (var context in activeExecutionContexts)"); sb.AppendLineIndent(2, "{"); sb.AppendLineIndent(2, " var src0 = {0};", GenerateGetOperandValue(instruction.Operands[0], NumberType.UInt)); sb.AppendLineIndent(2, " var result = src0.{0};", GenerateTestCondition(instruction.TestBoolean)); sb.AppendLineIndent(2, " activeMasks[0][context.Index] = !result;"); sb.AppendLineIndent(2, " activeMasks[1][context.Index] = result;"); sb.AppendLineIndent(2, "}"); break; case Execution.ExecutableOpcodeType.Cut: case Execution.ExecutableOpcodeType.CutStream: sb.AppendLineIndent(2, "yield return ExecutionResponse.Cut;"); break; case Execution.ExecutableOpcodeType.Dp2: GenerateExecuteScalar2(sb, instruction, "Dp2"); break; case Execution.ExecutableOpcodeType.Dp3: GenerateExecuteScalar2(sb, instruction, "Dp3"); break; case Execution.ExecutableOpcodeType.Dp4: GenerateExecuteScalar2(sb, instruction, "Dp4"); break; case Execution.ExecutableOpcodeType.Emit: case Execution.ExecutableOpcodeType.EmitStream: sb.AppendLineIndent(2, "yield return ExecutionResponse.Emit;"); break; case Execution.ExecutableOpcodeType.IAdd: GenerateExecute2NoSat(sb, instruction, "IAdd"); break; case Execution.ExecutableOpcodeType.IGe: GenerateExecute2NoSat(sb, instruction, "IGe"); break; case Execution.ExecutableOpcodeType.IShl: GenerateExecute2NoSat(sb, instruction, "IShl"); break; case Execution.ExecutableOpcodeType.IShr: GenerateExecute2NoSat(sb, instruction, "IShr"); break; case Execution.ExecutableOpcodeType.Mad: GenerateExecute3(sb, instruction, "Mad"); break; case Execution.ExecutableOpcodeType.Max: GenerateExecute2(sb, instruction, "Max"); break; case Execution.ExecutableOpcodeType.Min: GenerateExecute2(sb, instruction, "Min"); break; case Execution.ExecutableOpcodeType.Mul: GenerateExecute2(sb, instruction, "Mul"); break; case Execution.ExecutableOpcodeType.Mov : GenerateExecute1(sb, instruction, "Mov"); break; case Execution.ExecutableOpcodeType.MovC: GenerateExecute3(sb, instruction, "MovC"); break; case Execution.ExecutableOpcodeType.Ret : sb.AppendLineIndent(2, "yield return ExecutionResponse.Finished;"); break; case Execution.ExecutableOpcodeType.Rsq: GenerateExecute1(sb, instruction, "Rsq"); break; case Execution.ExecutableOpcodeType.Sample : var srcResourceIndex = instruction.Operands[2].Indices[0].Value; var srcSamplerIndex = instruction.Operands[3].Indices[0].Value; sb.AppendLineIndent(2, "{"); sb.AppendLineIndent(2, " var textureSampler = virtualMachine.TextureSamplers[{0}];", srcResourceIndex); sb.AppendLineIndent(2, " var srcResource = virtualMachine.Textures[{0}];", srcResourceIndex); sb.AppendLineIndent(2, " var srcSampler = virtualMachine.Samplers[{0}];", srcSamplerIndex); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " if (textureSampler == null || srcResource == null)"); sb.AppendLineIndent(2, " {"); sb.AppendLineIndent(2, " var result = new Number4();"); sb.AppendLineIndent(2, " foreach (var context in executionContexts)"); GenerateSetRegisterValue(sb, instruction.Operands[0]); sb.AppendLineIndent(2, " }"); sb.AppendLineIndent(2, " else"); sb.AppendLineIndent(2, " {"); sb.AppendLineIndent(2, " for (var i = 0; i < executionContexts.Length; i += 4)"); sb.AppendLineIndent(2, " {"); sb.AppendLineIndent(2, " var topLeft = {0};", GenerateGetOperandValue(instruction.Operands[1], NumberType.Float, "executionContexts[i + 0]")); sb.AppendLineIndent(2, " var topRight = {0};", GenerateGetOperandValue(instruction.Operands[1], NumberType.Float, "executionContexts[i + 1]")); sb.AppendLineIndent(2, " var bottomLeft = {0};", GenerateGetOperandValue(instruction.Operands[1], NumberType.Float, "executionContexts[i + 2]")); sb.AppendLineIndent(2, " var bottomRight = {0};", GenerateGetOperandValue(instruction.Operands[1], NumberType.Float, "executionContexts[i + 3]")); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " var deltaX = Number4.Subtract(ref topRight, ref topLeft);"); sb.AppendLineIndent(2, " var deltaY = Number4.Subtract(ref bottomLeft, ref topLeft);"); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " var result = textureSampler.SampleGrad(srcResource, srcSampler, ref topLeft, ref deltaX, ref deltaY);"); GenerateSetRegisterValue(sb, instruction.Operands[0], "executionContexts[i + 0]"); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " result = textureSampler.SampleGrad(srcResource, srcSampler, ref topRight, ref deltaX, ref deltaY);"); GenerateSetRegisterValue(sb, instruction.Operands[0], "executionContexts[i + 1]"); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " result = textureSampler.SampleGrad(srcResource, srcSampler, ref bottomLeft, ref deltaX, ref deltaY);"); GenerateSetRegisterValue(sb, instruction.Operands[0], "executionContexts[i + 2]"); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " result = textureSampler.SampleGrad(srcResource, srcSampler, ref bottomRight, ref deltaX, ref deltaY);"); GenerateSetRegisterValue(sb, instruction.Operands[0], "executionContexts[i + 3]"); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " }"); sb.AppendLineIndent(2, " }"); sb.AppendLineIndent(2, "}"); break; default : throw new InvalidOperationException(instruction.OpcodeType + " is not yet supported."); } }
private static string GenerateDivergent(ExecutableInstruction[] instructions) { var instructionsCode = new StringBuilder(); int instructionIndex = 0; foreach (var instruction in instructions) { instructionsCode.AppendLineIndent(4, "case {0}:", instructionIndex); instructionsCode.AppendLineIndent(4, "{"); instructionsCode.AppendLineIndent(5, "// " + instruction); GenerateInstructionCode(instructionsCode, instruction); instructionsCode.AppendLine(); if (instruction is DivergentExecutableInstruction) { instructionsCode.AppendLineIndent(5, "if (instruction.UpdateDivergenceStack(warp.DivergenceStack, activeMasks))"); } else { instructionsCode.AppendLineIndent(5, "if (instruction.UpdateDivergenceStack(warp.DivergenceStack, null))"); } instructionsCode.AppendLineIndent(5, "{"); instructionsCode.AppendLineIndent(5, " activeExecutionContexts = Warp.GetActiveExecutionContexts(executionContexts, topOfDivergenceStack);"); instructionsCode.AppendLineIndent(5, " topOfDivergenceStack = warp.DivergenceStack.Peek();"); instructionsCode.AppendLineIndent(5, "}"); instructionsCode.AppendLineIndent(5, "break;"); instructionsCode.AppendLineIndent(4, "}"); instructionsCode.AppendLine(); ++instructionIndex; } return(@" using System.Collections; using System.Collections.Generic; using SlimShader; using SlimShader.VirtualMachine; using SlimShader.VirtualMachine.Analysis.ExecutableInstructions; using SlimShader.VirtualMachine.Execution; public static class DynamicShaderExecutor { public static IEnumerable<ExecutionResponse> Execute( VirtualMachine virtualMachine, ExecutionContext[] executionContexts, ExecutableInstruction[] instructions) { var warp = new Warp(executionContexts.Length); var activeExecutionContexts = Warp.GetActiveExecutionContexts(executionContexts, warp.DivergenceStack.Peek()); var topOfDivergenceStack = warp.DivergenceStack.Peek(); while (topOfDivergenceStack.NextPC < instructions.Length) { var instruction = instructions[topOfDivergenceStack.NextPC]; switch (topOfDivergenceStack.NextPC) { " + instructionsCode + @" } } } }"); }
private static void GenerateInstructionCode(StringBuilder sb, ExecutableInstruction instruction) { switch (instruction.OpcodeType) { case Execution.ExecutableOpcodeType.Add: GenerateExecute2(sb, instruction, "Add"); break; case Execution.ExecutableOpcodeType.Branch: break; case Execution.ExecutableOpcodeType.BranchC: sb.AppendLineIndent(2, "var activeMasks = new List<BitArray>"); sb.AppendLineIndent(2, "{"); sb.AppendLineIndent(2, " new BitArray(executionContexts.Length),"); sb.AppendLineIndent(2, " new BitArray(executionContexts.Length)"); sb.AppendLineIndent(2, "};"); sb.AppendLineIndent(2, "foreach (var context in activeExecutionContexts)"); sb.AppendLineIndent(2, "{"); sb.AppendLineIndent(2, " var src0 = {0};", GenerateGetOperandValue(instruction.Operands[0], NumberType.UInt)); sb.AppendLineIndent(2, " var result = src0.{0};", GenerateTestCondition(instruction.TestBoolean)); sb.AppendLineIndent(2, " activeMasks[0][context.Index] = !result;"); sb.AppendLineIndent(2, " activeMasks[1][context.Index] = result;"); sb.AppendLineIndent(2, "}"); break; case Execution.ExecutableOpcodeType.Cut: case Execution.ExecutableOpcodeType.CutStream: sb.AppendLineIndent(2, "yield return ExecutionResponse.Cut;"); break; case Execution.ExecutableOpcodeType.Dp2: GenerateExecuteScalar2(sb, instruction, "Dp2"); break; case Execution.ExecutableOpcodeType.Dp3: GenerateExecuteScalar2(sb, instruction, "Dp3"); break; case Execution.ExecutableOpcodeType.Dp4: GenerateExecuteScalar2(sb, instruction, "Dp4"); break; case Execution.ExecutableOpcodeType.Emit: case Execution.ExecutableOpcodeType.EmitStream: sb.AppendLineIndent(2, "yield return ExecutionResponse.Emit;"); break; case Execution.ExecutableOpcodeType.IAdd: GenerateExecute2NoSat(sb, instruction, "IAdd"); break; case Execution.ExecutableOpcodeType.IGe: GenerateExecute2NoSat(sb, instruction, "IGe"); break; case Execution.ExecutableOpcodeType.IShl: GenerateExecute2NoSat(sb, instruction, "IShl"); break; case Execution.ExecutableOpcodeType.IShr: GenerateExecute2NoSat(sb, instruction, "IShr"); break; case Execution.ExecutableOpcodeType.Mad: GenerateExecute3(sb, instruction, "Mad"); break; case Execution.ExecutableOpcodeType.Max: GenerateExecute2(sb, instruction, "Max"); break; case Execution.ExecutableOpcodeType.Min: GenerateExecute2(sb, instruction, "Min"); break; case Execution.ExecutableOpcodeType.Mul: GenerateExecute2(sb, instruction, "Mul"); break; case Execution.ExecutableOpcodeType.Mov: GenerateExecute1(sb, instruction, "Mov"); break; case Execution.ExecutableOpcodeType.MovC: GenerateExecute3(sb, instruction, "MovC"); break; case Execution.ExecutableOpcodeType.Ret: sb.AppendLineIndent(2, "yield return ExecutionResponse.Finished;"); break; case Execution.ExecutableOpcodeType.Rsq: GenerateExecute1(sb, instruction, "Rsq"); break; case Execution.ExecutableOpcodeType.Sample: var srcResourceIndex = instruction.Operands[2].Indices[0].Value; var srcSamplerIndex = instruction.Operands[3].Indices[0].Value; sb.AppendLineIndent(2, "{"); sb.AppendLineIndent(2, " var textureSampler = virtualMachine.TextureSamplers[{0}];", srcResourceIndex); sb.AppendLineIndent(2, " var srcResource = virtualMachine.Textures[{0}];", srcResourceIndex); sb.AppendLineIndent(2, " var srcSampler = virtualMachine.Samplers[{0}];", srcSamplerIndex); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " if (textureSampler == null || srcResource == null)"); sb.AppendLineIndent(2, " {"); sb.AppendLineIndent(2, " var result = new Number4();"); sb.AppendLineIndent(2, " foreach (var context in executionContexts)"); GenerateSetRegisterValue(sb, instruction.Operands[0]); sb.AppendLineIndent(2, " }"); sb.AppendLineIndent(2, " else"); sb.AppendLineIndent(2, " {"); sb.AppendLineIndent(2, " for (var i = 0; i < executionContexts.Length; i += 4)"); sb.AppendLineIndent(2, " {"); sb.AppendLineIndent(2, " var topLeft = {0};", GenerateGetOperandValue(instruction.Operands[1], NumberType.Float, "executionContexts[i + 0]")); sb.AppendLineIndent(2, " var topRight = {0};", GenerateGetOperandValue(instruction.Operands[1], NumberType.Float, "executionContexts[i + 1]")); sb.AppendLineIndent(2, " var bottomLeft = {0};", GenerateGetOperandValue(instruction.Operands[1], NumberType.Float, "executionContexts[i + 2]")); sb.AppendLineIndent(2, " var bottomRight = {0};", GenerateGetOperandValue(instruction.Operands[1], NumberType.Float, "executionContexts[i + 3]")); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " var deltaX = Number4.Subtract(ref topRight, ref topLeft);"); sb.AppendLineIndent(2, " var deltaY = Number4.Subtract(ref bottomLeft, ref topLeft);"); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " var result = textureSampler.SampleGrad(srcResource, srcSampler, ref topLeft, ref deltaX, ref deltaY);"); GenerateSetRegisterValue(sb, instruction.Operands[0], "executionContexts[i + 0]"); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " result = textureSampler.SampleGrad(srcResource, srcSampler, ref topRight, ref deltaX, ref deltaY);"); GenerateSetRegisterValue(sb, instruction.Operands[0], "executionContexts[i + 1]"); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " result = textureSampler.SampleGrad(srcResource, srcSampler, ref bottomLeft, ref deltaX, ref deltaY);"); GenerateSetRegisterValue(sb, instruction.Operands[0], "executionContexts[i + 2]"); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " result = textureSampler.SampleGrad(srcResource, srcSampler, ref bottomRight, ref deltaX, ref deltaY);"); GenerateSetRegisterValue(sb, instruction.Operands[0], "executionContexts[i + 3]"); sb.AppendLineIndent(2, " "); sb.AppendLineIndent(2, " }"); sb.AppendLineIndent(2, " }"); sb.AppendLineIndent(2, "}"); break; default: throw new InvalidOperationException(instruction.OpcodeType + " is not yet supported."); } }
static void WriteType(StringBuilder sb, List <string> usings, TypeDefinition type, StubGenOptions opts) { Action <StringBuilder, List <string>, TypeDefinition, StubGenOptions> typeWriter = null; // TODO: security attributes if (type.IsSerializable) sb.AppendLineIndent ("[Serializable]"); if (type.HasCustomAttributes) sb.Append (type.CustomAttributes.Format ()); sb.AppendIndent (); FormatTypeAttributes (sb, type); if (type.IsEnum) { sb.Append ("enum"); typeWriter = EnumWriter; } else if (type.IsClass) { sb.Append ("class"); typeWriter = ClassWriter; } else if (type.IsInterface) { sb.Append ("interface"); typeWriter = InterfaceWriter; } else if (type.IsValueType) { if (type.FullName == "System.Delegate" || type.FullName == "System.MulticastDelegate") sb.Append ("delegate"); else sb.Append ("struct"); } sb.AppendFormat (" {0}", type.FormatName ()); bool haveColon = false; bool first = true; TypeReference tref = type.BaseType; if (WritableBaseType (tref)) { sb.Append (" : "); haveColon = true; first = false; usings.AddUsing (tref.Namespace); sb.Append (tref.FormatName ()); } if (type.HasInterfaces) { foreach (TypeReference tr in type.Interfaces.OnlyVisible (opts.IncludeNonPublic)) { if (first) { if (!haveColon) sb.Append (" : "); first = false; } else sb.Append (", "); usings.AddUsing (tr.Namespace); sb.Append (tr.FormatName ()); } } // TODO: output generic parameter constraints sb.AppendLine (); sb.AppendLineIndent ("{"); if (typeWriter != null) { Utils.Indent++; try { typeWriter (sb, usings, type, opts); } finally { Utils.Indent--; } } sb.AppendLineIndent ("}"); }