예제 #1
0
		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];
		}
예제 #2
0
		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]];
		}
예제 #3
0
		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;
		}
예제 #4
0
        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);
        }