private static void Execute(ExecutionContext context, ExecutableInstruction instruction, NumberType numberType, Number4ToNumber4Callback callback) { var src0 = GetOperandValue(context, instruction.Operands[1], numberType); var result = callback(ref src0); SetRegisterValue(context, instruction.Operands[0], result); }
private static void Execute(ExecutionContext context, ExecutableInstruction instruction, NumberType numberType, BoolNumber4Number4Number4ToNumber4Callback callback) { var src0 = GetOperandValue(context, instruction.Operands[1], numberType); var src1 = GetOperandValue(context, instruction.Operands[2], numberType); var src2 = GetOperandValue(context, instruction.Operands[3], numberType); var result = callback(instruction.Saturate, ref src0, ref src1, ref src2); SetRegisterValue(context, instruction.Operands[0], result); }
private static void GenerateExecute2NoSat(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 result = InstructionImplementations.{0}(ref src0, ref src1);", methodName); GenerateSetRegisterValue(sb, instruction.Operands[0]); sb.AppendLineIndent(2, "}"); }
private static void ExecuteScalar(ExecutionContext context, ExecutableInstruction instruction, NumberType numberType, Number4Number4ToNumberCallback callback) { var src0 = GetOperandValue(context, instruction.Operands[1], numberType); var src1 = GetOperandValue(context, instruction.Operands[2], numberType); var result = callback(instruction.Saturate, ref src0, ref src1); SetRegisterValue(context, instruction.Operands[0], new Number4 { Number0 = result, Number1 = result, Number2 = result, Number3 = result }); }
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."); } }