public void SetsNextProgramCounterForEveryInstruction()
        {
            // Arrange.
            var instructions = new List <InstructionBase>
            {
                CreateInstruction <NormalInstruction>(),                   // 0
                CreateInstruction <BranchingInstruction>(),                // 1 Unconditional branch to [3]
                CreateInstruction <NormalInstruction>(),                   // 2 Skipped
                CreateInstruction <BranchingInstruction>(),                // 3 Conditional branch to [5]
                CreateInstruction <NormalInstruction>(),                   // 4
                CreateInstruction <NormalInstruction>()                    // 5
            };

            ((BranchingInstruction)instructions[1]).BranchType   = BranchType.Unconditional;
            ((BranchingInstruction)instructions[1]).BranchTarget = instructions[3];
            ((BranchingInstruction)instructions[3]).BranchType   = BranchType.Conditional;
            ((BranchingInstruction)instructions[3]).BranchTarget = instructions[5];
            var controlFlowGraph = ControlFlowGraph.FromInstructions(instructions);

            // Act.
            var executableInstructions = ExecutableInstructionRewriter.Rewrite(controlFlowGraph).ToList();

            // Assert.
            Assert.That(executableInstructions, Has.Count.EqualTo(6));
            Assert.That(((NonDivergentExecutableInstruction)executableInstructions[0]).NextPC, Is.EqualTo(1));
            Assert.That(((NonDivergentExecutableInstruction)executableInstructions[1]).NextPC, Is.EqualTo(3));
            Assert.That(((NonDivergentExecutableInstruction)executableInstructions[2]).NextPC, Is.EqualTo(3));
            Assert.That(((DivergentExecutableInstruction)executableInstructions[3]).NextPCs, Is.EquivalentTo(new[] { 4, 5 }));
            Assert.That(((DivergentExecutableInstruction)executableInstructions[3]).ReconvergencePC, Is.EqualTo(5));
            Assert.That(((NonDivergentExecutableInstruction)executableInstructions[4]).NextPC, Is.EqualTo(5));
            Assert.That(((NonDivergentExecutableInstruction)executableInstructions[5]).NextPC, Is.EqualTo(6));
        }
Пример #2
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];
        }