예제 #1
0
        /// <summary>
        /// Creates a new instance of the Shader class.
        /// </summary>
        /// <param name="shaderBytecode">Byte array containing the compiled shader bytecode.</param>
        public Shader(byte[] shaderBytecode)
        {
            var bytecodeContainer = new BytecodeContainer(shaderBytecode);

            var programType = bytecodeContainer.Shader.Version.ProgramType;

            switch (programType)
            {
            case ProgramType.GeometryShader:
            case ProgramType.HullShader:
            case ProgramType.DomainShader:
            case ProgramType.ComputeShader:
                throw new NotSupportedException(string.Format(
                                                    "The '{0}' shader type is not yet supported.",
                                                    bytecodeContainer.Shader.Version.ProgramType));
            }

            _constantBuffers     = bytecodeContainer.ResourceDefinition.ConstantBuffers;
            _resourceBindings    = bytecodeContainer.ResourceDefinition.ResourceBindings;
            _inputSignature      = bytecodeContainer.InputSignature;
            _inputSignatureSize  = _inputSignature.Parameters.Sum(x => x.ByteCount);
            _outputSignature     = bytecodeContainer.OutputSignature;
            _outputSignatureSize = _outputSignature.Parameters.Sum(x => x.ByteCount);

            var numContexts = (programType == ProgramType.PixelShader) ? 4 : 1;

            _virtualMachine = new VirtualMachine(bytecodeContainer, numContexts);
        }
예제 #2
0
 public void SetInputLayout(Device device, InputSignatureChunk inputSignature)
 {
     foreach (ModelMesh mesh in _meshes)
     {
         mesh.SetInputLayout(device, inputSignature);
     }
     _inputLayoutSet = true;
 }
예제 #3
0
 /// <summary>
 /// Only used in unit tests.
 /// </summary>
 internal InputLayout(Device device, InputElement[] elements, InputSignatureChunk inputSignature)
     : base(device)
 {
     // TODO: Verify that shader bytecode matches input elements.
     _inputSignature = inputSignature;
     _rawElements    = elements;
     _elements       = ProcessElements(elements);
     _slots          = ProcessSlots(elements);
 }
예제 #4
0
 internal IEnumerable <InputAssemblerVertexOutput> GetVertexStreamIndexedInstanced(
     InputSignatureChunk vertexShaderInputSignature,
     int indexCountPerInstance,
     int instanceCount,
     int startIndexLocation,
     int baseVertexLocation,
     int startInstanceLocation)
 {
     throw new NotImplementedException();
 }
예제 #5
0
        internal IEnumerable <InputAssemblerVertexOutput> GetVertexStream(
            InputSignatureChunk vertexShaderInputSignature,
            int vertexCount,
            int startVertexLocation)
        {
            var vertexBufferIndices = _vertexBufferBindings
                                      .Select(x => new VertexBufferIndex(x, startVertexLocation))
                                      .ToArray();

            return(GetVertexStreamInternal(vertexShaderInputSignature, vertexCount, 0, startVertexLocation, vertexBufferIndices));
        }
예제 #6
0
        public void CanGetVertexStreamForTriangleListWithNoBuffersBound()
        {
            // Arrange.
            var device         = new Device();
            var inputAssembler = new InputAssemblerStage(device);

            inputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
            var inputSignature = new InputSignatureChunk
            {
                Parameters =
                {
                    new SignatureParameterDescription("SV_VertexID",                                      0, Name.VertexID,   RegisterComponentType.UInt32,
                                                      0,                                    ComponentMask.X, ComponentMask.X),
                    new SignatureParameterDescription("SV_InstanceID",                                    0, Name.InstanceID, RegisterComponentType.UInt32,
                                                      1,                                    ComponentMask.X, ComponentMask.X),
                }
            };

            // Act.
            var vertexStream = inputAssembler.GetVertexStream(inputSignature, 3, 0).ToList();

            // Assert.
            Assert.That(vertexStream, Has.Count.EqualTo(3));

            Assert.That(vertexStream[0].InstanceID, Is.EqualTo(0));
            Assert.That(vertexStream[0].VertexID, Is.EqualTo(0));
            Assert.That(vertexStream[0].Data, Is.EqualTo(new[]
            {
                new Number4(0.0f, 0, 0, 0),
                new Number4(0.0f, 0, 0, 0)
            }));

            Assert.That(vertexStream[1].InstanceID, Is.EqualTo(0));
            Assert.That(vertexStream[1].VertexID, Is.EqualTo(1));
            Assert.That(vertexStream[1].Data, Is.EqualTo(new[]
            {
                new Number4(1.0f, 0, 0, 0),
                new Number4(0.0f, 0, 0, 0)
            }));

            Assert.That(vertexStream[2].InstanceID, Is.EqualTo(0));
            Assert.That(vertexStream[2].VertexID, Is.EqualTo(2));
            Assert.That(vertexStream[2].Data, Is.EqualTo(new[]
            {
                new Number4(2.0f, 0, 0, 0),
                new Number4(0.0f, 0, 0, 0)
            }));
        }
예제 #7
0
        internal IEnumerable <InputAssemblerVertexOutput> GetVertexStreamInstanced(
            InputSignatureChunk vertexShaderInputSignature,
            int vertexCountPerInstance,
            int instanceCount,
            int startVertexLocation,
            int startInstanceLocation)
        {
            // Setup per-instance data (applies across draw call).
            // TODO: This isn't quite right - we need make vertexBufferIndices a dictionary, keyed on slot.
            var vertexBufferIndices = InputLayout.Slots
                                      .Select(x => (x.InputSlotClass == InputClassification.PerInstanceData)
                                        ? new InstancedVertexBufferIndex(x.InstanceDataStepRate, _vertexBufferBindings[x.InputSlot], startInstanceLocation)
                                        : new VertexBufferIndex(_vertexBufferBindings[x.InputSlot], startVertexLocation))
                                      .ToArray();
            var perInstanceBufferIndices = vertexBufferIndices
                                           .Where(x => x.InputDataClass == InputClassification.PerInstanceData)
                                           .ToArray();
            var perVertexBufferIndices = vertexBufferIndices
                                         .Where(x => x.InputDataClass == InputClassification.PerVertexData)
                                         .ToArray();

            for (int i = 0; i < instanceCount; i++)
            {
                // Reset per-vertex data (applies to each instance).
                foreach (var perVertexBufferIndex in perVertexBufferIndices)
                {
                    perVertexBufferIndex.Reset();
                }

                foreach (var result in GetVertexStreamInternal(vertexShaderInputSignature, vertexCountPerInstance, i, startVertexLocation, vertexBufferIndices))
                {
                    yield return(result);
                }

                foreach (var vertexBufferIndex in perInstanceBufferIndices)
                {
                    vertexBufferIndex.Increment(InputClassification.PerInstanceData);
                }
            }
        }
예제 #8
0
        private IEnumerable <InputAssemblerVertexOutput> GetVertexStreamInternal(
            InputSignatureChunk vertexShaderInputSignature,
            int vertexCount, int instanceID, int vertexID,
            VertexBufferIndex[] vertexBufferIndices)
        {
            var inputParameterCount = vertexShaderInputSignature.Parameters.Count;
            Dictionary <int, InputLayout.ProcessedInputElement> inputElementsKeyedByRegister = null;

            if (InputLayout != null)
            {
                inputElementsKeyedByRegister = InputLayout.Elements.ToDictionary(x => x.RegisterIndex);
            }

            var processedVertexHandler = ProcessedVertex;

            for (int i = 0; i < vertexCount; i++)
            {
                var output = new InputAssemblerVertexOutput();
                output.VertexID   = vertexID++;
                output.InstanceID = instanceID;
                output.Data       = new Number4[inputParameterCount];

                // TODO: Support non-32-bit formats.
                foreach (var parameter in vertexShaderInputSignature.Parameters)
                {
                    switch (parameter.SystemValueType)
                    {
                    case Name.Undefined:
                    case Name.Position:
                        if (inputElementsKeyedByRegister == null)
                        {
                            throw new Exception("InputLayout must be set in order to use these system value types.");
                        }
                        var inputElement = inputElementsKeyedByRegister[(int)parameter.Register];
                        vertexBufferIndices[inputElement.InputSlot].GetData(
                            output.Data, inputElement.RegisterIndex,
                            inputElement.AlignedByteOffset,
                            FormatHelper.SizeOfInBytes(inputElement.Format));
                        break;

                    case Name.VertexID:
                        output.Data[parameter.Register] = new Number4(output.VertexID, 0, 0, 0);
                        break;

                    case Name.InstanceID:
                        output.Data[parameter.Register] = new Number4(output.InstanceID, 0, 0, 0);
                        break;
                    }
                }

                if (processedVertexHandler != null)
                {
                    processedVertexHandler(this, new InputAssemblerVertexEventArgs(output));
                }

                yield return(output);

                foreach (var vertexBufferIndex in vertexBufferIndices)
                {
                    vertexBufferIndex.Increment(InputClassification.PerVertexData);
                }
            }
        }
예제 #9
0
파일: Device.cs 프로젝트: prepare/rasterizr
 public InputLayout CreateInputLayout(InputElement[] elements, InputSignatureChunk inputSignature)
 {
     return(CreateInputLayout(elements, inputSignature.Container.RawBytes));
 }
예제 #10
0
 public void SetInputLayout(Device device, InputSignatureChunk inputSignature)
 {
     InputLayout = device.CreateInputLayout(InputElements, inputSignature);
 }