예제 #1
0
        protected override void UpdateSettings(DX11RenderSettings settings)
        {
            float f = this.FDoubleScale[0] ? 2.0f : 1.0f;

            float w = vp[0].Width;
            float h = vp[0].Height;

            settings.View = Matrix.Identity;
            settings.Projection = Matrix.Scaling(f / w, f / h, 1.0f) * FTransformIn[0];

            if (FTopLeft[0])
            {
                float tx = w * 0.5f;
                float ty = h * 0.5f;
                settings.Projection = Matrix.Translation(-tx, ty, 0.0f) * settings.Projection;
            }

            settings.ViewProjection = settings.Projection;
        }
예제 #2
0
        public void Update(IPluginIO pin, DX11RenderContext context)
        {
            if (this.CalculateSpreadMax() == 0)
            {
                return;
            }

            Device device = context.Device;
            DeviceContext ctx = context.CurrentDeviceContext;

            if (!this.deviceshaderdata.ContainsKey(context))
            {
                this.deviceshaderdata.Add(context, new DX11ShaderData(context));
                this.deviceshaderdata[context].SetEffect(this.FShader);
            }

            DX11ShaderData shaderdata = this.deviceshaderdata[context];
            if (this.shaderupdated)
            {
                shaderdata.SetEffect(this.FShader);
                shaderdata.Update(this.FInTechnique[0].Index, 0, this.FIn);
                this.shaderupdated = false;
            }

            if (this.FInEnabled[0] && this.FIn.PluginIO.IsConnected)
            {
                //Clear shader stages (important here)
                shaderdata.ResetShaderStages(ctx);

                if (this.FIn.IsChanged || this.FInTechnique.IsChanged || shaderdata.LayoutValid.Count == 0)
                {
                    shaderdata.Update(this.FInTechnique[0].Index, 0, this.FIn);

                }

                if (shaderdata.IsLayoutValid(0) && this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance,this.settings))
                {
                    this.OnBeginQuery(context);

                    this.settings = new DX11RenderSettings();
                    this.settings.RenderWidth = 1;
                    this.settings.RenderHeight = 1;
                    this.settings.View = this.FInView[0];
                    this.settings.Projection = this.FInProjection[0];
                    this.settings.ViewProjection = this.settings.View * this.settings.Projection;
                    this.settings.RenderDepth = 1;
                    this.settings.BackBuffer = null;

                    if (this.FInSemantics.PluginIO.IsConnected)
                    {
                        this.settings.CustomSemantics.AddRange(this.FInSemantics.ToArray());
                    }
                    if (this.FInResSemantics.PluginIO.IsConnected)
                    {
                        this.settings.ResourceSemantics.AddRange(this.FInResSemantics.ToArray());
                    }

                    this.varmanager.ApplyGlobal(shaderdata.ShaderInstance);

                    if (this.clone == null || this.FIn.IsChanged || this.FInAsAuto.IsChanged || this.FInMaxElements.IsChanged || this.FInLayout.IsChanged || this.FInAutoLayout.IsChanged)
                    {
                        if (this.buffer != null) { this.buffer.Dispose(); }

                        bool customlayout = this.FInLayout.PluginIO.IsConnected || this.FInAutoLayout[0];
                        InputElement[] elems = null;
                        int size = 0;

                        if (this.FInAutoLayout[0])
                        {
                            elems = this.FShader.DefaultEffect.GetTechniqueByIndex(tid).GetPassByIndex(0).GetStreamOutputLayout(out size);
                        }
                        else
                        {
                            if (customlayout)
                            {
                                elems = this.BindInputLayout(out size);
                            }
                        }

                        #region Vertex Geom
                        if (this.FIn[0][context] is DX11VertexGeometry)
                        {
                            if (!this.FInAsAuto[0])
                            {
                                DX11VertexGeometry vg = (DX11VertexGeometry)this.FIn[0][context].ShallowCopy();

                                int vsize = customlayout ? size : vg.VertexSize;
                                Buffer vbo = BufferHelper.CreateStreamOutBuffer(context, vsize, vg.VerticesCount);
                                if (customlayout) { vg.VertexSize = vsize; }
                                vg.VertexBuffer = vbo;

                                this.clone = vg;
                                this.buffer = vbo;
                            }
                            else
                            {
                                DX11VertexGeometry vg = (DX11VertexGeometry)this.FIn[0][context].ShallowCopy();

                                int maxv = vg.VerticesCount;
                                if (this.FInMaxElements[0] > 0)
                                {
                                    maxv = this.FInMaxElements[0];
                                }

                                int vsize = customlayout ? size : vg.VertexSize;
                                Buffer vbo = BufferHelper.CreateStreamOutBuffer(context, vsize, maxv);
                                vg.VertexBuffer = vbo;
                                vg.AssignDrawer(new DX11VertexAutoDrawer());
                                if (customlayout) { vg.VertexSize = vsize; }

                                this.clone = vg;
                                this.buffer = vbo;
                            }
                        }
                        #endregion

                        #region Inxexed geom
                        if (this.FIn[0][context] is DX11IndexedGeometry)
                        {
                            if (!this.FInAsAuto[0])
                            {

                                DX11IndexedGeometry ig = (DX11IndexedGeometry)this.FIn[0][context].ShallowCopy();

                                int vsize = customlayout ? size : ig.VertexSize;
                                Buffer vbo = BufferHelper.CreateStreamOutBuffer(context, vsize, ig.VerticesCount);
                                ig.VertexBuffer = vbo;
                                if (customlayout) { ig.VertexSize = vsize; }
                                this.clone = ig;
                                this.buffer = vbo;
                            }
                            else
                            {
                                //Need to rebind indexed geom as vertex
                                DX11IndexedGeometry ig = (DX11IndexedGeometry)this.FIn[0][context];

                                int maxv = ig.VerticesCount;
                                if (this.FInMaxElements[0] > 0)
                                {
                                    maxv = this.FInMaxElements[0];
                                }

                                int vsize = customlayout ? size : ig.VertexSize;
                                Buffer vbo = BufferHelper.CreateStreamOutBuffer(context, vsize, maxv);

                                //Copy a new Vertex buffer with stream out
                                DX11VertexGeometry vg = new DX11VertexGeometry(context);
                                vg.AssignDrawer(new DX11VertexAutoDrawer());
                                vg.BoundingBox = ig.BoundingBox;
                                vg.HasBoundingBox = ig.HasBoundingBox;
                                vg.InputLayout = ig.InputLayout;
                                vg.Topology = ig.Topology;
                                vg.VertexBuffer = vbo;
                                vg.VertexSize = ig.VertexSize;
                                vg.VerticesCount = ig.VerticesCount;

                                if (customlayout) { vg.VertexSize = vsize; }

                                this.clone = vg;
                                this.buffer = vbo;
                            }
                        }
                        #endregion

                        #region Null geom
                        if (this.FIn[0][context] is DX11NullGeometry)
                        {
                            DX11NullGeometry ng = (DX11NullGeometry)this.FIn[0][context];

                            Buffer vbo = BufferHelper.CreateStreamOutBuffer(context, size, this.FInMaxElements[0]);

                            //Copy a new Vertex buffer with stream out
                            DX11VertexGeometry vg = new DX11VertexGeometry(context);
                            vg.AssignDrawer(new DX11VertexAutoDrawer());
                            vg.BoundingBox = ng.BoundingBox;
                            vg.HasBoundingBox = ng.HasBoundingBox;
                            vg.InputLayout = ng.InputLayout;
                            vg.Topology = ng.Topology;
                            vg.VertexBuffer = vbo;
                            vg.VertexSize = size;
                            vg.VerticesCount = this.FInMaxElements[0];

                            this.clone = vg;
                            this.buffer = vbo;

                        }
                        #endregion

                        #region Index Only geom
                        if (this.FIn[0][context] is DX11IndexOnlyGeometry)
                        {
                            DX11IndexOnlyGeometry ng = (DX11IndexOnlyGeometry)this.FIn[0][context];

                            Buffer vbo = BufferHelper.CreateStreamOutBuffer(context, size, this.FInMaxElements[0]);

                            //Copy a new Vertex buffer with stream out
                            DX11VertexGeometry vg = new DX11VertexGeometry(context);
                            vg.AssignDrawer(new DX11VertexAutoDrawer());
                            vg.BoundingBox = ng.BoundingBox;
                            vg.HasBoundingBox = ng.HasBoundingBox;
                            vg.InputLayout = ng.InputLayout;
                            vg.Topology = ng.Topology;
                            vg.VertexBuffer = vbo;
                            vg.VertexSize = size;
                            vg.VerticesCount = this.FInMaxElements[0];

                            this.clone = vg;
                            this.buffer = vbo;

                        }
                        #endregion

                        if (customlayout) { this.clone.InputLayout = elems; }

                        if (this.FOutBuffer[0][context] != null)
                        {
                            this.FOutBuffer[0][context].SRV.Dispose();
                        }

                        if (context.ComputeShaderSupport)
                        {
                            this.FOutBuffer[0][context] = new DX11RawBuffer(context, this.buffer);
                        }
                        else
                        {
                            this.FOutBuffer[0][context] = null;
                        }

                    }

                    ctx.StreamOutput.SetTargets(new StreamOutputBufferBinding(this.buffer, 0));
                    shaderdata.SetInputAssembler(ctx, this.FIn[0][context], 0);

                    DX11ObjectRenderSettings ors = new DX11ObjectRenderSettings();
                    ors.DrawCallIndex = 0;
                    ors.Geometry = this.FIn[0][context];
                    ors.WorldTransform = Matrix.Identity;

                    this.varmanager.ApplyPerObject(context, shaderdata.ShaderInstance, ors, 0);

                    shaderdata.ApplyPass(ctx);

                    this.FIn[0][context].Draw();

                    ctx.StreamOutput.SetTargets(null);

                    this.FOut[0][context] = this.clone;

                    this.OnEndQuery(context);

                }
                else
                {
                    this.FOut[0][context] = this.FIn[0][context];
                }
            }
            else
            {
                this.FOut[0][context] = this.FIn[0][context];
            }
        }
예제 #3
0
        public void Update(IPluginIO pin, DX11RenderContext context)
        {
            Device device = context.Device;
            DeviceContext ctx = context.CurrentDeviceContext;

            if (!this.deviceshaderdata.ContainsKey(context))
            {
                this.deviceshaderdata.Add(context, new DX11ShaderData(context));
                this.deviceshaderdata[context].SetEffect(this.FShader);
            }

            DX11ShaderData shaderdata = this.deviceshaderdata[context];
            if (this.shaderupdated)
            {
                shaderdata.SetEffect(this.FShader);
                this.shaderupdated = false;
            }

            context.RenderStateStack.Push(new DX11RenderState());

            this.OnBeginQuery(context);

            //Clear shader stages
            shaderdata.ResetShaderStages(ctx);
            context.Primitives.ApplyFullTriVS();

            foreach (DX11ResourcePoolEntry<DX11RenderTarget2D> rt in this.lastframetargets)
            {
                rt.UnLock();
            }
            this.lastframetargets.Clear();

            DX11ObjectRenderSettings or = new DX11ObjectRenderSettings();

            int wi, he;
            bool preserve = false;
            DX11ResourcePoolEntry<DX11RenderTarget2D> preservedtarget = null;

            for (int i = 0; i < this.spmax; i++)
            {
                int passcounter = 0;

                if (this.FInEnabled[i])
                {
                    List<DX11ResourcePoolEntry<DX11RenderTarget2D>> locktargets = new List<DX11ResourcePoolEntry<DX11RenderTarget2D>>();

                    #region Manage size
                    DX11Texture2D initial;
                    if (this.FIn.PluginIO.IsConnected)
                    {
                        if (this.FInUseDefaultSize[0])
                        {
                            initial = context.DefaultTextures.WhiteTexture;
                            wi = (int)this.FInSize[0].X;
                            he = (int)this.FInSize[0].Y;
                        }
                        else
                        {
                            initial = this.FIn[i][context];
                            if (initial != null)
                            {
                                wi = initial.Width;
                                he = initial.Height;
                            }
                            else
                            {
                                initial = context.DefaultTextures.WhiteTexture;
                                wi = (int)this.FInSize[i].X;
                                he = (int)this.FInSize[i].Y;
                            }
                        }
                    }
                    else
                    {
                        initial = context.DefaultTextures.WhiteTexture;
                        wi = (int)this.FInSize[i].X;
                        he = (int)this.FInSize[i].Y;
                    }
                    #endregion

                    DX11RenderSettings r = new DX11RenderSettings();
                    r.RenderWidth = wi;
                    r.RenderHeight = he;
                    if (this.FInSemantics.PluginIO.IsConnected)
                    {
                        r.CustomSemantics.AddRange(this.FInSemantics.ToArray());
                    }
                    if (this.FInResSemantics.PluginIO.IsConnected)
                    {
                        r.ResourceSemantics.AddRange(this.FInResSemantics.ToArray());
                    }

                    this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, r);

                    this.varmanager.ApplyGlobal(shaderdata.ShaderInstance);

                    DX11Texture2D lastrt = initial;
                    DX11ResourcePoolEntry<DX11RenderTarget2D> lasttmp = null;

                    List<DX11Texture2D> rtlist = new List<DX11Texture2D>();

                    //Bind Initial (once only is ok)
                    this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, "INITIAL", initial);

                    //Go trough all passes
                    EffectTechnique tech = shaderdata.ShaderInstance.Effect.GetTechniqueByIndex(tid);

                    for (int j = 0; j < tech.Description.PassCount; j++)
                    {
                        ImageShaderPass pi = this.varmanager.passes[j];
                        EffectPass pass = tech.GetPassByIndex(j);
                        bool isLastPass = j == tech.Description.PassCount - 1;

                        for (int kiter = 0; kiter < pi.IterationCount; kiter++)
                        {

                            if (passcounter > 0)
                            {
                                for (int pid = 0; pid < passcounter; pid++)
                                {
                                    string pname = "PASSRESULT" + pid;
                                    this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, pname, rtlist[pid]);
                                }
                            }

                            Format fmt = initial.Format;
                            if (pi.CustomFormat)
                            {
                                fmt = pi.Format;
                            }
                            bool mips = pi.Mips || (isLastPass && FInMipLastPass[i]);

                            int w, h;
                            if (j == 0)
                            {
                                h = he;
                                w = wi;
                            }
                            else
                            {
                                h = pi.Reference == ImageShaderPass.eImageScaleReference.Initial ? he : lastrt.Height;
                                w = pi.Reference == ImageShaderPass.eImageScaleReference.Initial ? wi : lastrt.Width;
                            }

                            if (pi.DoScale)
                            {
                                if (pi.Absolute)
                                {
                                    w = Convert.ToInt32(pi.ScaleVector.X);
                                    h = Convert.ToInt32(pi.ScaleVector.Y);
                                }
                                else
                                {
                                    w = Convert.ToInt32((float)w * pi.ScaleVector.X);
                                    h = Convert.ToInt32((float)h * pi.ScaleVector.Y);
                                }

                                w = Math.Max(w, 1);
                                h = Math.Max(h, 1);
                            }

                            //Check format support for render target, and default to rgb8 if not
                            if (!context.IsSupported(FormatSupport.RenderTarget, fmt))
                            {
                                fmt = Format.R8G8B8A8_UNorm;
                            }

                            //Since device is not capable of telling us BGR not supported
                            if (fmt == Format.B8G8R8A8_UNorm) { fmt = Format.R8G8B8A8_UNorm; }

                            DX11ResourcePoolEntry<DX11RenderTarget2D> elem;
                            if (preservedtarget != null)
                            {
                                elem = preservedtarget;
                            }
                            else
                            {
                                elem = context.ResourcePool.LockRenderTarget(w, h, fmt, new SampleDescription(1, 0), mips, 0);
                                locktargets.Add(elem);
                            }
                            DX11RenderTarget2D rt = elem.Element;

                            if (this.FDepthIn.PluginIO.IsConnected && pi.UseDepth)
                            {
                                context.RenderTargetStack.Push(this.FDepthIn[0][context], true, elem.Element);
                            }
                            else
                            {
                                context.RenderTargetStack.Push(elem.Element);
                            }

                            if (pi.Clear)
                            {
                                elem.Element.Clear(new Color4(0, 0, 0, 0));
                            }

                            #region Check for depth/blend preset
                            bool validdepth = false;
                            bool validblend = false;

                            DepthStencilStateDescription ds = new DepthStencilStateDescription();
                            BlendStateDescription bs = new BlendStateDescription();

                            if (pi.DepthPreset != "")
                            {
                                try
                                {
                                    ds = DX11DepthStencilStates.Instance.GetState(pi.DepthPreset);
                                    validdepth = true;
                                }
                                catch
                                {

                                }
                            }

                            if (pi.BlendPreset != "")
                            {
                                try
                                {
                                    bs = DX11BlendStates.Instance.GetState(pi.BlendPreset);
                                    validblend = true;
                                }
                                catch
                                {

                                }
                            }
                            #endregion

                            if (validdepth || validblend)
                            {
                                DX11RenderState state = new DX11RenderState();
                                if (validdepth) { state.DepthStencil = ds; }
                                if (validblend) { state.Blend = bs; }
                                context.RenderStateStack.Push(state);
                            }

                            r.RenderWidth = w;
                            r.RenderHeight = h;
                            r.BackBuffer = elem.Element;
                            this.varmanager.ApplyGlobal(shaderdata.ShaderInstance);

                            //Apply settings (note that textures swap is handled later)
                            this.varmanager.ApplyPerObject(context, shaderdata.ShaderInstance, or, i);

                            //Bind last render target
                            this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, "PREVIOUS", lastrt);

                            this.BindPassIndexSemantic(shaderdata.ShaderInstance.Effect, j);
                            this.BindPassIterIndexSemantic(shaderdata.ShaderInstance.Effect, kiter);

                            if (this.FDepthIn.PluginIO.IsConnected)
                            {
                                if (this.FDepthIn[0].Contains(context))
                                {
                                    this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, "DEPTHTEXTURE", this.FDepthIn[0][context]);
                                }
                            }

                            //Apply pass and draw quad
                            pass.Apply(ctx);

                            if (pi.ComputeData.Enabled)
                            {
                                pi.ComputeData.Dispatch(context, w, h);
                                context.CleanUpCS();
                            }
                            else
                            {
                                ctx.ComputeShader.Set(null);
                                context.Primitives.FullScreenTriangle.Draw();
                                ctx.OutputMerger.SetTargets(this.nullrtvs);
                            }

                            //Generate mips if applicable
                            if (mips) { ctx.GenerateMips(rt.SRV); }

                            if (!pi.KeepTarget)
                            {
                                preserve = false;
                                rtlist.Add(rt);
                                lastrt = rt;
                                lasttmp = elem;
                                preservedtarget = null;
                                passcounter++;
                            }
                            else
                            {
                                preserve = true;
                                preservedtarget = elem;
                            }

                            context.RenderTargetStack.Pop();

                            if (validblend || validdepth)
                            {
                                context.RenderStateStack.Pop();
                            }

                            if (pi.HasState)
                            {
                                context.RenderStateStack.Apply();
                            }
                        }
                    }

                    //Set last render target
                    this.FOut[i][context] = lastrt;

                    //Unlock all resources
                    foreach (DX11ResourcePoolEntry<DX11RenderTarget2D> lt in locktargets)
                    {
                        lt.UnLock();
                    }

                    //Keep lock on last rt, since don't want it overidden
                    lasttmp.Lock();

                    this.lastframetargets.Add(lasttmp);
                }
                else
                {
                    this.FOut[i][context] = this.FIn[i][context];
                }
            }

            context.RenderStateStack.Pop();

            this.OnEndQuery(context);

            //UnLock previous frame in applicable
            //if (previoustarget != null) { context.ResourcePool.Unlock(previoustarget); }
        }
예제 #4
0
        public static void RenderAll(this ISpread <DX11Resource <DX11Layer> > layer, DX11RenderContext context, DX11RenderSettings settings)
        {
            var buffer = layer.Stream.Buffer;

            for (int i = 0; i < layer.SliceCount; i++)
            {
                buffer[i][context].Render(context, settings);
            }
        }
예제 #5
0
        public static void RenderAllWithLog(this ISpread <DX11Resource <DX11Layer> > layer, DX11RenderContext context, DX11RenderSettings settings, ILogger logger)
        {
            var buffer = layer.Stream.Buffer;

            for (int i = 0; i < layer.SliceCount; i++)
            {
                try
                {
                    buffer[i][context].Render(context, settings);
                }
                catch (Exception ex)
                {
                    logger.Log(ex);
                }
            }
        }
예제 #6
0
 public static void RenderSlice(this ISpread <DX11Resource <DX11Layer> > layer, DX11RenderContext context, DX11RenderSettings settings, int slice)
 {
     layer[slice][context]?.Render(context, settings);
 }
예제 #7
0
        public void Render(DX11RenderContext context)
        {
            Device device = context.Device;

            //Just in case
            if (!this.updateddevices.Contains(context))
            {
                this.Update(null, context);
            }

            if (this.rendereddevices.Contains(context)) { return; }

            if (this.FInEnabled[0])
            {

                DX11GraphicsRenderer renderer = this.renderers[context];

                if (this.BeginQuery != null)
                {
                    this.BeginQuery(context);
                }

                this.BeforeRender(renderer, context);

                Exception exception = null;

                try
                {
                    renderer.SetTargets();

                    if (this.FInClearDepth[0] && this.FInDepthBuffer[0])
                    {
                        this.depthmanager.Clear(context);
                    }

                    this.DoClear(context);

                    if (this.FInLayer.PluginIO.IsConnected)
                    {

                        int rtmax = Math.Max(this.FInProjection.SliceCount, this.FInView.SliceCount);
                        rtmax = Math.Max(rtmax, this.FInViewPort.SliceCount);

                        DX11RenderSettings settings = new DX11RenderSettings();
                        settings.ViewportCount = rtmax;

                        bool viewportpop = this.FInViewPort.PluginIO.IsConnected;

                        float cw = (float)this.width;
                        float ch = (float)this.height;

                        for (int i = 0; i < rtmax; i++)
                        {
                            settings.ViewportIndex = i;
                            settings.View = this.FInView[i];

                            Matrix proj = this.FInProjection[i];
                            Matrix aspect = Matrix.Invert(this.FInAspect[i]);
                            Matrix crop = Matrix.Invert(this.FInCrop[i]);

                            settings.Projection = proj * aspect * crop;
                            settings.ViewProjection = settings.View * settings.Projection;
                            settings.RenderWidth = this.width;
                            settings.RenderHeight = this.height;
                            settings.BackBuffer = this.GetMainTarget(context);
                            settings.CustomSemantics.Clear();
                            settings.ResourceSemantics.Clear();

                            if (viewportpop)
                            {
                                context.RenderTargetStack.PushViewport(this.FInViewPort[i].Normalize(cw, ch));
                            }

                            //Call render on all layers
                            for (int j = 0; j < this.FInLayer.SliceCount; j++)
                            {
                                try
                                {
                                    this.FInLayer[j][context].Render(this.FInLayer.PluginIO, context, settings);
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex.Message);
                                }
                            }

                            if (viewportpop)
                            {
                                context.RenderTargetStack.PopViewport();
                            }
                        }
                    }

                    //Post render
                    this.AfterRender(renderer, context);

                }
                catch (Exception ex)
                {
                    exception = ex;
                }
                finally
                {
                    if (this.EndQuery != null)
                    {
                        this.EndQuery(context);
                    }

                    renderer.CleanTargets();
                }

                this.rendereddevices.Add(context);

                if (exception != null)
                {
                    throw exception;
                }
            }
        }
예제 #8
0
        public void Render(DX11RenderContext context)
        {
            Device device = context.Device;

            //Just in case
            if (!this.updateddevices.Contains(context))
            {
                this.Update(null, context);
            }

            if (this.rendereddevices.Contains(context))
            {
                return;
            }

            if (this.FInEnabled[0])
            {
                DX11GraphicsRenderer renderer = this.renderers[context];

                if (this.BeginQuery != null)
                {
                    this.BeginQuery(context);
                }

                this.BeforeRender(renderer, context);

                Exception exception = null;

                try
                {
                    renderer.SetTargets();

                    if (this.FInClearDepth[0] && this.FInDepthBuffer[0])
                    {
                        this.depthmanager.Clear(context, this.FInClearDepthValue[0]);
                    }

                    this.DoClear(context);

                    if (this.FInLayer.IsConnected)
                    {
                        int rtmax = Math.Max(this.FInProjection.SliceCount, this.FInView.SliceCount);
                        rtmax = Math.Max(rtmax, this.FInViewPort.SliceCount);

                        DX11RenderSettings settings = new DX11RenderSettings();
                        settings.ViewportCount = rtmax;

                        bool viewportpop = this.FInViewPort.PluginIO.IsConnected;

                        float cw = (float)this.width;
                        float ch = (float)this.height;

                        for (int i = 0; i < rtmax; i++)
                        {
                            settings.ViewportIndex = i;
                            settings.View          = this.FInView[i];

                            Matrix proj   = this.FInProjection[i];
                            Matrix aspect = Matrix.Invert(this.FInAspect[i]);
                            Matrix crop   = Matrix.Invert(this.FInCrop[i]);

                            settings.Projection     = proj * aspect * crop;
                            settings.ViewProjection = settings.View * settings.Projection;
                            settings.RenderWidth    = this.width;
                            settings.RenderHeight   = this.height;
                            settings.BackBuffer     = this.GetMainTarget(context);
                            settings.CustomSemantics.Clear();
                            settings.ResourceSemantics.Clear();

                            if (viewportpop)
                            {
                                context.RenderTargetStack.PushViewport(this.FInViewPort[i].Normalize(cw, ch));
                            }

                            //Call render on all layers
                            for (int j = 0; j < this.FInLayer.SliceCount; j++)
                            {
                                try
                                {
                                    this.FInLayer[j][context].Render(this.FInLayer.PluginIO, context, settings);
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex.Message);
                                }
                            }

                            if (viewportpop)
                            {
                                context.RenderTargetStack.PopViewport();
                            }
                        }
                    }


                    //Post render
                    this.AfterRender(renderer, context);
                }
                catch (Exception ex)
                {
                    exception = ex;
                }
                finally
                {
                    if (this.EndQuery != null)
                    {
                        this.EndQuery(context);
                    }

                    renderer.CleanTargets();
                }

                this.rendereddevices.Add(context);

                if (exception != null)
                {
                    throw exception;
                }
            }
        }
예제 #9
0
        public void Update(IPluginIO pin, DX11RenderContext context)
        {
            Device device = context.Device;
            DeviceContext ctx = context.CurrentDeviceContext;

            if (!this.deviceshaderdata.ContainsKey(context))
            {
                this.deviceshaderdata.Add(context, new DX11ShaderData(context));
                this.deviceshaderdata[context].SetEffect(this.FShader);
            }

            DX11ShaderData shaderdata = this.deviceshaderdata[context];
            if (this.shaderupdated)
            {
                shaderdata.SetEffect(this.FShader);
                this.shaderupdated = false;
            }

            context.RenderStateStack.Push(new DX11RenderState());

            this.OnBeginQuery(context);

            //Clear shader stages
            shaderdata.ResetShaderStages(ctx);
            context.Primitives.ApplyFullTriVS();

            foreach (DX11ResourcePoolEntry<DX11RenderTarget2D> rt in this.lastframetargets)
            {
                rt.UnLock();
            }
            this.lastframetargets.Clear();

            DX11ObjectRenderSettings or = new DX11ObjectRenderSettings();

            int wi, he;

            for (int i = 0; i < this.spmax; i++)
            {
                if (this.FInEnabled[i])
                {
                    List<DX11ResourcePoolEntry<DX11RenderTarget2D>> locktargets = new List<DX11ResourcePoolEntry<DX11RenderTarget2D>>();

                    DX11Texture2D initial;
                    if (this.FIn.PluginIO.IsConnected)
                    {
                        if (this.FInUseDefaultSize[0])
                        {
                            initial = context.DefaultTextures.WhiteTexture;
                            wi = (int)this.FInSize[0].X;
                            he = (int)this.FInSize[0].Y;
                        }
                        else
                        {
                            initial = this.FIn[i][context];
                            if (initial != null)
                            {
                                wi = initial.Width;
                                he = initial.Height;
                            }
                            else
                            {
                                initial = context.DefaultTextures.WhiteTexture;
                                wi = (int)this.FInSize[0].X;
                                he = (int)this.FInSize[0].Y;
                            }
                        }
                    }
                    else
                    {
                        initial = context.DefaultTextures.WhiteTexture;
                        wi = (int)this.FInSize[0].X;
                        he = (int)this.FInSize[0].Y;
                    }

                    DX11RenderSettings r = new DX11RenderSettings();
                    r.RenderWidth = wi;
                    r.RenderHeight = he;
                    if (this.FInSemantics.PluginIO.IsConnected)
                    {
                        r.CustomSemantics.AddRange(this.FInSemantics.ToArray());
                    }
                    if (this.FInResSemantics.PluginIO.IsConnected)
                    {
                        r.ResourceSemantics.AddRange(this.FInResSemantics.ToArray());
                    }

                    this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, r);

                    this.varmanager.ApplyGlobal(shaderdata.ShaderInstance);

                    DX11Texture2D lastrt = initial;
                    DX11ResourcePoolEntry<DX11RenderTarget2D> lasttmp = null;

                    List<DX11Texture2D> rtlist = new List<DX11Texture2D>();

                    //Bind Initial (once only is ok)
                    this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, "INITIAL", initial);

                    if (this.persistedframe != null)
                    {
                        this.BindSemanticSRV(shaderdata.ShaderInstance.Effect, "LASTFRAME", persistedframe.SRV);
                    }

                    //Go trough all passes
                    EffectTechnique tech = shaderdata.ShaderInstance.Effect.GetTechniqueByIndex(tid);

                    for (int j = 0; j < tech.Description.PassCount; j++)
                    {
                        ImageShaderPass pi = this.varmanager.passes[j];
                        EffectPass pass = tech.GetPassByIndex(j);

                        if (j > 0)
                        {
                            int pid = j - 1;
                            string pname = "PASSRESULT" + pid;

                            this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, pname, rtlist[pid]);
                        }

                        Format fmt = initial.Format;
                        if (pi.CustomFormat)
                        {
                            fmt = pi.Format;
                        }
                        bool mips = pi.Mips;

                        int w, h;
                        if (j == 0)
                        {
                            h = he;
                            w = wi;
                        }
                        else
                        {
                            h = pi.Reference == ImageShaderPass.eImageScaleReference.Initial ? he : lastrt.Height;
                            w = pi.Reference == ImageShaderPass.eImageScaleReference.Initial ? wi : lastrt.Width;
                        }

                        if (pi.DoScale)
                        {
                            h = Convert.ToInt32((float)h * pi.Scale);
                            w = Convert.ToInt32((float)w * pi.Scale);
                            h = Math.Max(h, 1);
                            w = Math.Max(w, 1);
                        }

                        //Check format support for render target, and default to rgb8 if not
                        if (!context.IsSupported(FormatSupport.RenderTarget, fmt))
                        {
                            fmt = Format.R8G8B8A8_UNorm;
                        }

                        //Since device is not capable of telling us BGR not supported
                        if (fmt == Format.B8G8R8A8_UNorm) { fmt = Format.R8G8B8A8_UNorm; }

                        DX11ResourcePoolEntry<DX11RenderTarget2D> elem = context.ResourcePool.LockRenderTarget(w, h, fmt, new SampleDescription(1, 0), mips, 0);
                        locktargets.Add(elem);
                        DX11RenderTarget2D rt = elem.Element;
                        ctx.OutputMerger.SetTargets(rt.RTV);

                        r.RenderWidth = w;
                        r.RenderHeight = h;
                        r.BackBuffer = rt;
                        this.varmanager.ApplyGlobal(shaderdata.ShaderInstance);

                        //Apply settings (note that textures swap is handled later)
                        this.varmanager.ApplyPerObject(context, shaderdata.ShaderInstance, or, i);

                        Viewport vp = new Viewport();
                        vp.Width = rt.Width;
                        vp.Height = rt.Height;
                        ctx.Rasterizer.SetViewports(vp);

                        //Bind last render target
                        this.BindTextureSemantic(shaderdata.ShaderInstance.Effect, "PREVIOUS", lastrt);

                        //Apply pass and draw quad
                        pass.Apply(ctx);

                        if (pi.ComputeData.Enabled)
                        {
                            pi.ComputeData.Dispatch(context, w, h);
                            context.CleanUpCS();
                        }
                        else
                        {
                            ctx.ComputeShader.Set(null);
                            context.Primitives.FullScreenTriangle.Draw();
                            ctx.OutputMerger.SetTargets(this.nullrtvs);
                        }

                        //Generate mips if applicable
                        if (pi.Mips) { ctx.GenerateMips(rt.SRV); }

                        rtlist.Add(rt);

                        lastrt = rt;
                        lasttmp = elem;
                    }

                    //Set last render target
                    this.FOut[i][context] = lastrt;

                    //Unlock all resources
                    foreach (DX11ResourcePoolEntry<DX11RenderTarget2D> lt in locktargets)
                    {
                        lt.UnLock();
                    }

                    //Keep lock on last rt, since don't want it overidden
                    lasttmp.Lock();

                    //this.lastframetargets.
                    //this.lasttarget = lasttmp;

                    this.lastframetargets.Add(lasttmp);

                    //previousrts[context] = lasttmp.Element;
                }
                else
                {
                    this.FOut[i][context] = this.FIn[i][context];
                }
            }

            context.RenderStateStack.Pop();

            this.OnEndQuery(context);

            //UnLock previous frame in applicable
            //if (previoustarget != null) { context.ResourcePool.Unlock(previoustarget); }
        }