/// <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); }
public void SetInputLayout(Device device, InputSignatureChunk inputSignature) { foreach (ModelMesh mesh in _meshes) { mesh.SetInputLayout(device, inputSignature); } _inputLayoutSet = true; }
/// <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); }
internal IEnumerable <InputAssemblerVertexOutput> GetVertexStreamIndexedInstanced( InputSignatureChunk vertexShaderInputSignature, int indexCountPerInstance, int instanceCount, int startIndexLocation, int baseVertexLocation, int startInstanceLocation) { throw new NotImplementedException(); }
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)); }
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) })); }
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); } } }
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); } } }
public InputLayout CreateInputLayout(InputElement[] elements, InputSignatureChunk inputSignature) { return(CreateInputLayout(elements, inputSignature.Container.RawBytes)); }
public void SetInputLayout(Device device, InputSignatureChunk inputSignature) { InputLayout = device.CreateInputLayout(InputElements, inputSignature); }