Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
 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 + @"
    }
}";
        }
Beispiel #4
0
        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 + @"
    }
}");
        }
Beispiel #5
0
        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.");
            }
        }
Beispiel #14
0
        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 + @"
            }
        }

    }
}");
        }
Beispiel #15
0
        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.");
            }
        }
Beispiel #16
0
        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 ("}");
        }