From 53aa5d88e273150ed1524506b42bb8f1039544a0 Mon Sep 17 00:00:00 2001 From: Julien Vulliet Date: Wed, 21 Jun 2017 19:09:14 +0300 Subject: [PATCH] [Nodes] Add new raw textur version, and advanced stream out renderer --- .../DX11AdvancedStreamOutRendererNode.cs | 275 ++++++++++++++++++ .../Nodes/Textures/2D/AsTextureNode.cs | 153 ++++++++++ Nodes/VVVV.DX11.Nodes/VVVV.DX11.Nodes.csproj | 2 + 3 files changed, 430 insertions(+) create mode 100644 Nodes/VVVV.DX11.Nodes/Nodes/Renderers/Buffers/DX11AdvancedStreamOutRendererNode.cs create mode 100644 Nodes/VVVV.DX11.Nodes/Nodes/Textures/2D/AsTextureNode.cs diff --git a/Nodes/VVVV.DX11.Nodes/Nodes/Renderers/Buffers/DX11AdvancedStreamOutRendererNode.cs b/Nodes/VVVV.DX11.Nodes/Nodes/Renderers/Buffers/DX11AdvancedStreamOutRendererNode.cs new file mode 100644 index 00000000..387dde3b --- /dev/null +++ b/Nodes/VVVV.DX11.Nodes/Nodes/Renderers/Buffers/DX11AdvancedStreamOutRendererNode.cs @@ -0,0 +1,275 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using VVVV.PluginInterfaces.V2; +using VVVV.PluginInterfaces.V1; +using SlimDX; + +using SlimDX.Direct3D11; +using System.ComponentModel.Composition; + +using FeralTic.DX11.Queries; +using FeralTic.DX11.Resources; +using FeralTic.DX11; +using FeralTic.DX11.Utils; +using FeralTic.DX11.Resources.Misc; + +namespace VVVV.DX11.Nodes +{ + [PluginInfo(Name = "Renderer", Category = "DX11", Version = "StreamOut.Advanced", Author = "vux", AutoEvaluate = false, + Help ="Advanced version of stream out renderer, allows to set up to 4 buffers")] + public class DX11AdvancedStreamOutRendererNode : IPluginEvaluate, IDX11RendererHost, IDisposable, IDX11Queryable + { + protected IPluginHost FHost; + + [Input("Layer", Order = 1)] + protected Pin> FInLayer; + + [Input("Buffer Count", Order = 7, DefaultValue = 1, MinValue = 1, MaxValue = 4)] + protected IDiffSpread FInBufferCount; + + [Input("Vertex Size", Order = 8, DefaultValue = 12)] + protected IDiffSpread FInVSize; + + [Input("Element Count", Order = 8, DefaultValue = 512)] + protected IDiffSpread FInElemCount; + + + [Input("Output Layout", Order = 10005)] + protected IDiffSpread FInLayouts; + + [Input("Output Layout Element Count", Order = 10006, DefaultValue = -1)] + protected IDiffSpread FInLayoutsElementCount; + + [Input("Enabled", DefaultValue = 1, Order = 15)] + protected ISpread FInEnabled; + + [Input("Keep In Memory", Order = 18, Visibility = PinVisibility.OnlyInspector, IsSingle=true)] + protected ISpread FInKeepInMemory; + + [Output("Geometry Out")] + protected ISpread> FOutGeom; + + [Output("Buffer Out")] + protected ISpread> FOutBuffer; + + [Output("Query", Order = 200, IsSingle = true)] + protected ISpread FOutQueryable; + + + + protected List updateddevices = new List(); + protected List rendereddevices = new List(); + + + + public event DX11QueryableDelegate BeginQuery; + public event DX11QueryableDelegate EndQuery; + + + private DX11RenderSettings settings = new DX11RenderSettings(); + + private StreamOutputBufferWithRawSupport[] outputBuffer = new StreamOutputBufferWithRawSupport[4]; + private int currentBufferCount = 0; + private bool invalidate = false; + + + [ImportingConstructor()] + public DX11AdvancedStreamOutRendererNode(IPluginHost FHost) + { + + } + + public void Evaluate(int SpreadMax) + { + if (this.FOutQueryable[0] == null) { this.FOutQueryable[0] = this; } + + this.rendereddevices.Clear(); + this.updateddevices.Clear(); + + invalidate = this.FInVSize.IsChanged || this.FInElemCount.IsChanged || this.FInLayouts.IsChanged || this.FInLayoutsElementCount.IsChanged; + + int bufferCount = SpreadMax == 0 ? 0 : this.FInBufferCount[0]; + if (bufferCount > 4) + bufferCount = 4; + + if (bufferCount < 0) + bufferCount = 0; + + if (bufferCount != this.currentBufferCount) + { + for (int i = 0; i < 4; i++) + { + if (this.outputBuffer[i] != null) + { + this.outputBuffer[i].Dispose(); + this.outputBuffer[i] = null; + } + } + invalidate = true; + } + this.currentBufferCount = bufferCount; + + this.FOutGeom.SliceCount = this.currentBufferCount; + this.FOutBuffer.SliceCount = this.currentBufferCount; + + for (int i = 0; i < this.currentBufferCount; i++) + { + if (this.FOutBuffer[i] == null) + { + this.FOutBuffer[i] = new DX11Resource(); + this.FOutGeom[i] = new DX11Resource(); + } + } + } + + public bool IsEnabled + { + get { return this.FInEnabled[0]; } + } + + public void Render(DX11RenderContext context) + { + if (this.currentBufferCount == 0) + return; + + Device device = context.Device; + DeviceContext ctx = context.CurrentDeviceContext; + + //Just in case + if (!this.updateddevices.Contains(context)) + { + this.Update(context); + } + + if (!this.FInLayer.IsConnected) { return; } + + if (this.rendereddevices.Contains(context)) { return; } + + if (this.FInEnabled[0]) + { + if (this.BeginQuery != null) + { + this.BeginQuery(context); + } + + + context.CurrentDeviceContext.OutputMerger.SetTargets(new RenderTargetView[0]); + + StreamOutputBufferBinding[] binding = new StreamOutputBufferBinding[this.currentBufferCount]; + for (int i = 0; i < this.currentBufferCount; i++) + { + binding[i].Buffer = this.outputBuffer[i].D3DBuffer; + binding[i].Offset = 0; + } + ctx.StreamOutput.SetTargets(binding); + + settings.ViewportIndex = 0; + settings.ViewportCount = 1; + settings.View = Matrix.Identity; + settings.Projection = Matrix.Identity; + settings.ViewProjection = Matrix.Identity; + settings.RenderWidth = 1; + settings.RenderHeight =1; + settings.RenderDepth =1; + settings.BackBuffer = null; + + this.FInLayer.RenderAll(context, settings); + + ctx.StreamOutput.SetTargets(null); + + if (this.EndQuery != null) + { + this.EndQuery(context); + } + + } + } + + + + public void Update(DX11RenderContext context) + { + if (this.currentBufferCount == 0) + return; + + if (this.updateddevices.Contains(context)) { return; } + if (this.invalidate || this.outputBuffer[0] == null) + { + this.DisposeBuffers(context); + + bool all = this.FInLayoutsElementCount[0] == -1; + int currentOffset = 0; + if (all) + { + for (int index = 0; index < this.currentBufferCount; index++) + { + this.outputBuffer[index] = new StreamOutputBufferWithRawSupport(context, this.FInVSize[index], this.FInElemCount[index], this.FInLayouts.ToArray()); + this.FOutGeom[index][context] = this.outputBuffer[index].VertexGeometry; + this.FOutBuffer[index][context] = this.outputBuffer[index].RawBuffer; + } + } + else + { + for (int index = 0; index < this.currentBufferCount; index++) + { + + int elemCount = this.FInLayoutsElementCount[index]; + elemCount = elemCount < 0 ? this.FInLayouts.SliceCount : elemCount; + + InputElement[] elems = new InputElement[elemCount]; + for (int j = 0; j < elems.Length; j++) + { + elems[j] = this.FInLayouts[currentOffset++]; + } + + this.outputBuffer[index] = new StreamOutputBufferWithRawSupport(context, this.FInVSize[index], this.FInElemCount[index], elems); + this.FOutGeom[index][context] = this.outputBuffer[index].VertexGeometry; + this.FOutBuffer[index][context] = this.outputBuffer[index].RawBuffer; + } + } + + + } + + this.updateddevices.Add(context); + } + + public void Destroy(DX11RenderContext context, bool force) + { + if (force || this.FInKeepInMemory[0] == false) + { + this.DisposeBuffers(context); + } + } + + #region Dispose Buffers + private void DisposeBuffers(DX11RenderContext context) + { + for (int i = 0; i < 4; i++) + { + if (this.outputBuffer[i] != null) + { + this.outputBuffer[i].Dispose(); + this.outputBuffer[i] = null; + } + } + } + #endregion + + public void Dispose() + { + for (int i = 0; i < 4; i++) + { + if (this.outputBuffer[i] != null) + { + this.outputBuffer[i].Dispose(); + this.outputBuffer[i] = null; + } + } + } + } + + +} diff --git a/Nodes/VVVV.DX11.Nodes/Nodes/Textures/2D/AsTextureNode.cs b/Nodes/VVVV.DX11.Nodes/Nodes/Textures/2D/AsTextureNode.cs new file mode 100644 index 00000000..f7927007 --- /dev/null +++ b/Nodes/VVVV.DX11.Nodes/Nodes/Textures/2D/AsTextureNode.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; + +using VVVV.PluginInterfaces.V1; +using VVVV.PluginInterfaces.V2; + +using SlimDX.Direct3D11; +using SlimDX; + +using FeralTic.DX11.Resources; +using FeralTic.DX11; +using VVVV.Core.Logging; +using VVVV.DX11.Internals.Helpers; +using VVVV.Utils.Win32; +using System.IO; + +namespace VVVV.DX11.Nodes +{ + [PluginInfo(Name = "AsTexture", Category = "DX11.Texture", Version = "2d Raw", Author = "vux", Help ="Creates a DirectX11 texture from raw pixel data (not from a file format")] + public unsafe class DynamidRawTexture : IPluginEvaluate, IDX11ResourceHost, IDisposable + { + [Import()] + protected ILogger logger; + + [Input("Width", DefaultValue = 1,AutoValidate=false)] + protected ISpread FInWidth; + + [Input("Height", DefaultValue = 1, AutoValidate = false)] + protected ISpread FInHeight; + + [Input("Format", DefaultEnumEntry ="R8G8B8A8_UNrom", AutoValidate = false)] + protected ISpread FInFormat; + + [Input("Stride", DefaultValue = 0, AutoValidate = false)] + protected ISpread FInStride; + + [Input("Data", DefaultValue = 0, AutoValidate = false)] + protected Pin FInData; + + [Input("Read Location", DefaultValue = 0, AutoValidate = false)] + protected ISpread FInDataLocation; + + [Input("Apply", IsBang = true, DefaultValue = 1)] + protected ISpread FApply; + + [Output("Texture Out")] + protected Pin> FTextureOutput; + + [Output("Is Valid")] + protected ISpread FValid; + + private bool FInvalidate; + + private Spread byteSpread = new Spread(1); + + public void Evaluate(int SpreadMax) + { + if (this.FApply[0]) + { + this.FInWidth.Sync(); + this.FInHeight.Sync(); + this.FInFormat.Sync(); + this.FInStride.Sync(); + + this.FInData.Sync(); + this.FInDataLocation.Sync(); + + this.FInvalidate = true; + } + + if (SpreadMax == 0) + { + if (this.FTextureOutput.SliceCount == 1) + { + this.FTextureOutput.SafeDisposeAll(); + } + } + else + { + this.FTextureOutput.SliceCount = 1; + if (this.FTextureOutput[0] == null) + { + this.FTextureOutput[0] = new DX11Resource(); + } + } + } + + public unsafe void Update(DX11RenderContext context) + { + if (this.FTextureOutput.SliceCount == 0) { return; } + + if (this.FInvalidate) + { + + int index = 0; + var data = this.FInData[index]; + + if (this.FTextureOutput[0].Contains(context)) + { + this.FTextureOutput[0].Dispose(context); + } + + if (this.FInData.IsConnected && data != null) + { + int width = this.FInWidth[index]; + int height = this.FInHeight[index]; + var fmt = this.FInFormat[index]; + + int pixelSize = DeviceFormatHelper.GetPixelSizeInBytes(fmt); + + int stride = this.FInStride[index]; + stride = stride <= 0 ? pixelSize * width : stride; + + //Normally spread implementation, afaik , doesn't downsize the buffer + byteSpread.SliceCount = stride * pixelSize; + + data.Position = this.FInDataLocation[0]; + data.Read(byteSpread.Stream.Buffer, 0, stride * height); + data.Position = 0; + + using (SlimDX.DataStream dataStream = new DataStream(byteSpread.Stream.Buffer, true, true)) + { + DX11Texture2D texture = DX11Texture2D.CreateImmutable(context, width, height, fmt, stride, dataStream); + this.FTextureOutput[0][context] = texture; + } + } + this.FInvalidate = false; + } + } + + public void Destroy(DX11RenderContext context, bool force) + { + this.FTextureOutput[0].Dispose(context); + } + + + #region IDisposable Members + public void Dispose() + { + if (this.FTextureOutput.SliceCount > 0) + { + if (this.FTextureOutput[0] != null) + { + this.FTextureOutput[0].Dispose(); + } + } + } + #endregion + } +} diff --git a/Nodes/VVVV.DX11.Nodes/VVVV.DX11.Nodes.csproj b/Nodes/VVVV.DX11.Nodes/VVVV.DX11.Nodes.csproj index cc916943..d8abe5ac 100644 --- a/Nodes/VVVV.DX11.Nodes/VVVV.DX11.Nodes.csproj +++ b/Nodes/VVVV.DX11.Nodes/VVVV.DX11.Nodes.csproj @@ -67,6 +67,7 @@ + @@ -82,6 +83,7 @@ +