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 ExecutionContext(VirtualMachine virtualMachine, int index, RequiredRegisters requiredRegisters) { _virtualMachine = virtualMachine; Index = index; Inputs = new Number4[requiredRegisters.NumPrimitives][]; for (int i = 0; i < requiredRegisters.NumPrimitives; i++) Inputs[i] = new Number4[requiredRegisters.Inputs]; Outputs = new Number4[requiredRegisters.Outputs]; Temps = new Number4[requiredRegisters.Temps]; IndexableTemps = new Number4[requiredRegisters.IndexableTemps.Count][]; for (int i = 0; i < requiredRegisters.IndexableTemps.Count; i++) IndexableTemps[i] = new Number4[requiredRegisters.IndexableTemps[i]]; }
public static RequiredRegisters FromShader(ShaderProgramChunk shader) { var result = new RequiredRegisters(); foreach (var declarationToken in shader.DeclarationTokens) { OperandIndex[] indices = (declarationToken.Operand != null) ? declarationToken.Operand.Indices : new OperandIndex[0]; var indexDimension = (declarationToken.Operand != null) ? declarationToken.Operand.IndexDimension : OperandIndexDimension._0D; switch (declarationToken.Header.OpcodeType) { case OpcodeType.DclInput: case OpcodeType.DclInputPs: case OpcodeType.DclInputPsSgv: case OpcodeType.DclInputPsSiv: case OpcodeType.DclInputSgv: case OpcodeType.DclInputSiv: switch (indexDimension) { case OperandIndexDimension._2D: result.NumPrimitives = (int) indices[0].Value; result.Inputs = Math.Max(result.Inputs, (int) indices[1].Value + 1); break; case OperandIndexDimension._1D: result.NumPrimitives = 1; result.Inputs = (int) indices[0].Value + 1; break; default: throw new ArgumentOutOfRangeException(); } break; case OpcodeType.DclOutput: case OpcodeType.DclOutputSgv: case OpcodeType.DclOutputSiv: result.Outputs = (int)indices[0].Value + 1; break; case OpcodeType.DclResource: result.Resources.Add(((ResourceDeclarationToken) declarationToken).ResourceDimension); break; case OpcodeType.DclSampler: result.Samplers = (int)indices[0].Value + 1; break; case OpcodeType.DclConstantBuffer: while (result.ConstantBuffers.Count < (int) indices[0].Value + 1) result.ConstantBuffers.Add(0); result.ConstantBuffers[(int)indices[0].Value] = (int) indices[1].Value; break; case OpcodeType.DclIndexableTemp: while (result.IndexableTemps.Count < (int)indices[0].Value + 1) result.IndexableTemps.Add(0); result.IndexableTemps[(int)indices[0].Value] = (int)indices[1].Value + 1; break; case OpcodeType.DclTemps: result.Temps = (int) ((TempRegisterDeclarationToken) declarationToken).TempCount; break; } } return result; }
public static RequiredRegisters FromShader(ShaderProgramChunk shader) { var result = new RequiredRegisters(); foreach (var declarationToken in shader.DeclarationTokens) { OperandIndex[] indices = (declarationToken.Operand != null) ? declarationToken.Operand.Indices : new OperandIndex[0]; var indexDimension = (declarationToken.Operand != null) ? declarationToken.Operand.IndexDimension : OperandIndexDimension._0D; switch (declarationToken.Header.OpcodeType) { case OpcodeType.DclInput: case OpcodeType.DclInputPs: case OpcodeType.DclInputPsSgv: case OpcodeType.DclInputPsSiv: case OpcodeType.DclInputSgv: case OpcodeType.DclInputSiv: switch (indexDimension) { case OperandIndexDimension._2D: result.NumPrimitives = (int)indices[0].Value; result.Inputs = Math.Max(result.Inputs, (int)indices[1].Value + 1); break; case OperandIndexDimension._1D: result.NumPrimitives = 1; result.Inputs = (int)indices[0].Value + 1; break; default: throw new ArgumentOutOfRangeException(); } break; case OpcodeType.DclOutput: case OpcodeType.DclOutputSgv: case OpcodeType.DclOutputSiv: result.Outputs = (int)indices[0].Value + 1; break; case OpcodeType.DclResource: result.Resources.Add(((ResourceDeclarationToken)declarationToken).ResourceDimension); break; case OpcodeType.DclSampler: result.Samplers = (int)indices[0].Value + 1; break; case OpcodeType.DclConstantBuffer: while (result.ConstantBuffers.Count < (int)indices[0].Value + 1) { result.ConstantBuffers.Add(0); } result.ConstantBuffers[(int)indices[0].Value] = (int)indices[1].Value; break; case OpcodeType.DclIndexableTemp: while (result.IndexableTemps.Count < (int)indices[0].Value + 1) { result.IndexableTemps.Add(0); } result.IndexableTemps[(int)indices[0].Value] = (int)indices[1].Value + 1; break; case OpcodeType.DclTemps: result.Temps = (int)((TempRegisterDeclarationToken)declarationToken).TempCount; break; } } return(result); }