private void ApplyOnly(DX11RenderContext context, DX11RenderSettings settings)
        {
            Device        device = context.Device;
            DeviceContext ctx    = context.CurrentDeviceContext;

            var            variableCache = this.shaderVariableCache[context];
            DX11ShaderData sdata         = this.deviceshaderdata[context];

            this.varmanager.SetGlobalSettings(sdata.ShaderInstance, settings);
            variableCache.ApplyGlobals(settings);

            DX11ObjectRenderSettings oset = new DX11ObjectRenderSettings();

            oset.DrawCallIndex  = 0;
            oset.Geometry       = null;
            oset.IterationCount = 1;
            oset.IterationIndex = 0;
            oset.WorldTransform = this.mworld[0 % this.mworldcount];
            variableCache.ApplySlice(oset, 0);
            sdata.ApplyPass(ctx);

            if (this.FInLayer.IsConnected)
            {
                this.FInLayer.RenderAll(context, settings);
            }
        }
Beispiel #2
0
        public void Update(IPluginIO pin, DX11RenderContext context)
        {
            if (!this.FOutLayer[0].Data.ContainsKey(context))
            {
                this.FOutLayer[0][context]        = new DX11Layer();
                this.FOutLayer[0][context].Render = this.Render;
            }

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

            DX11ShaderData shaderdata = this.deviceshaderdata[context];

            if (this.shaderupdated)
            {
                shaderdata.SetEffect(this.FShader);
                this.FOutShader[0][context] = new DX11Shader(shaderdata.ShaderInstance);
            }
            else
            {
                if (!this.FOutShader[0].Contains(context))
                {
                    this.FOutShader[0][context] = new DX11Shader(shaderdata.ShaderInstance);
                }
            }
        }
        public void Update(DX11RenderContext context)
        {
            if (!this.FOutLayer[0].Contains(context))
            {
                this.FOutLayer[0][context]        = new DX11Layer();
                this.FOutLayer[0][context].Render = this.Render;
            }

            if (!this.objectSettings.Contains(context))
            {
                this.objectSettings[context] = new DX11ObjectRenderSettings();
            }
            if (!this.orderedObjectSettings.Contains(context))
            {
                this.orderedObjectSettings[context] = new List <DX11ObjectRenderSettings>();
            }


            if (!this.deviceshaderdata.Contains(context))
            {
                this.deviceshaderdata[context] = new DX11ShaderData(context, this.FShader);
            }
            if (!this.shaderVariableCache.Contains(context))
            {
                this.shaderVariableCache[context] = new DX11ShaderVariableCache(context, this.deviceshaderdata[context].ShaderInstance, this.varmanager);
            }

            DX11ShaderData shaderdata = this.deviceshaderdata[context];

            if (!this.FOutShader[0].Contains(context))
            {
                this.FOutShader[0][context] = new DX11Shader(shaderdata.ShaderInstance);
            }
        }
        public void Render(DX11RenderContext context, DX11RenderSettings settings)
        {
            Device        device = context.Device;
            DeviceContext ctx    = context.CurrentDeviceContext;

            bool popstate = false;

            bool multistate     = this.FInState.IsConnected && this.FInState.SliceCount > 1;
            bool stateConnected = this.FInState.IsConnected;

            if (this.FInEnabled[0])
            {
                //In that case we do not care about geometry, but only apply pass for globals
                if (settings.RenderHint == eRenderHint.ApplyOnly)
                {
                    this.ApplyOnly(context, settings);
                    return;
                }

                if (settings.RenderHint == eRenderHint.Collector)
                {
                    this.Collect(context, settings);
                    return;
                }

                DX11ShaderData shaderdata = this.deviceshaderdata[context];
                if ((shaderdata.IsValid &&
                     (this.geomconnected || settings.Geometry != null) &&
                     this.spmax > 0 && this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, settings)) ||
                    this.FInApplyOnly[0])
                {
                    this.OnBeginQuery(context);

                    //Select preferred technique if available
                    if (settings.PreferredTechniques.Count == 0 && this.techniqueindex != this.FInTechnique[0].Index)
                    {
                        this.techniqueindex   = this.FInTechnique[0].Index;
                        this.techniquechanged = true;
                    }
                    else if (settings.PreferredTechniques.Count > 0)
                    {
                        int i = settings.GetPreferredTechnique(this.FShader);
                        if (i == -1)
                        {
                            i = this.FInTechnique[0].Index;
                        }
                        if (i != this.techniqueindex)
                        {
                            this.techniqueindex   = i;
                            this.techniquechanged = true;
                        }
                    }

                    //Need to build input layout
                    if (this.FGeometry.IsChanged || this.techniquechanged || shaderdata.LayoutValid.Count == 0)
                    {
                        shaderdata.Update(this.techniqueindex, 0, this.FGeometry);
                        this.FOutLayoutValid.AssignFrom(shaderdata.LayoutValid);
                        this.FOutLayoutMsg.AssignFrom(shaderdata.LayoutMsg);

                        int           errorCount = 0;
                        StringBuilder sbMsg      = new StringBuilder();
                        sbMsg.Append("Invalid layout detected for slices:");
                        for (int i = 0; i < shaderdata.LayoutValid.Count; i++)
                        {
                            if (shaderdata.LayoutValid[i] == false)
                            {
                                errorCount++;
                                sbMsg.Append(i + ",");
                            }
                        }

                        if (errorCount > 0)
                        {
                            this.FHost.Log(TLogType.Warning, sbMsg.ToString());
                        }

                        this.techniquechanged = false;
                    }

                    if (this.stateconnected && !multistate)
                    {
                        context.RenderStateStack.Push(this.FInState[0]);
                        popstate = true;
                    }

                    ShaderPipelineState pipelineState = null;
                    if (!settings.PreserveShaderStages)
                    {
                        shaderdata.ResetShaderStages(ctx);
                    }
                    else
                    {
                        pipelineState = new ShaderPipelineState(context);
                    }

                    settings.DrawCallCount = spmax; //Set number of draw calls

                    var objectsettings = this.objectSettings[context];
#pragma warning disable 0618
                    objectsettings.GeometryFromLayer = false;
#pragma warning restore 0618
                    var orderedobjectsettings = this.orderedObjectSettings[context];
                    var variableCache         = this.shaderVariableCache[context];
                    variableCache.ApplyGlobals(settings);

                    //IDX11Geometry drawgeom = null;
                    objectsettings.Geometry = null;
                    DX11Resource <IDX11Geometry> pg = null;
                    bool       doOrder       = false;
                    List <int> orderedSlices = null;
                    if (settings.LayerOrder != null && settings.LayerOrder.Enabled)
                    {
                        orderedobjectsettings.Clear();
                        for (int i = 0; i < this.spmax; i++)
                        {
                            DX11ObjectRenderSettings objSettings = new DX11ObjectRenderSettings();
                            objSettings.DrawCallIndex  = i;
                            objSettings.Geometry       = null;
                            objSettings.IterationCount = 1;
                            objSettings.IterationIndex = 0;
                            objSettings.WorldTransform = this.mworld[i % this.mworldcount];
                            objSettings.RenderStateTag = stateConnected ? this.FInState[i].Tag : null;
                            orderedobjectsettings.Add(objSettings);
                        }

                        orderedSlices = settings.LayerOrder.Reorder(settings, orderedobjectsettings);
                        doOrder       = true;
                    }

                    int drawCount = doOrder ? orderedSlices.Count : this.spmax;

                    if (this.spmax == 0)
                    {
                        drawCount = 0;
                    }

                    bool singleGeometry = this.FGeometry.SliceCount == 1 || settings.Geometry != null;
                    if (settings.Geometry != null && this.FGeometry.IsConnected == false)
                    {
#pragma warning disable 0618
                        objectsettings.GeometryFromLayer = true;
#pragma warning restore 0618

                        objectsettings.Geometry = settings.Geometry;
                        singleGeometry          = true;
                        if (!shaderdata.SetInputAssemblerFromLayer(ctx, objectsettings.Geometry, 0))
                        {
                            return;
                        }
                    }
                    else if (singleGeometry)
                    {
                        pg = this.FGeometry[0];
                        objectsettings.Geometry = pg[context];


                        if (objectsettings.Geometry == null)
                        {
                            objectsettings.Geometry = new DX11InvalidGeometry();
                        }
                        shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, 0);
                    }

                    if (!multistate)
                    {
                        objectsettings.RenderStateTag = this.FInState[0] != null ? this.FInState[0].Tag : null;
                    }

                    for (int i = 0; i < drawCount; i++)
                    {
                        int idx = doOrder ? orderedSlices[i] : i;
                        if (multistate)
                        {
                            context.RenderStateStack.Push(this.FInState[idx]);
                            objectsettings.RenderStateTag = this.FInState[idx] != null ? this.FInState[idx].Tag : null;
                        }

                        if (shaderdata.IsLayoutValid(idx) || settings.Geometry != null)
                        {
                            objectsettings.IterationCount = this.FIter[idx];

                            for (int k = 0; k < objectsettings.IterationCount; k++)
                            {
                                objectsettings.IterationIndex = k;

                                if (!singleGeometry)
                                {
                                    if (settings.Geometry == null)
                                    {
                                        if (this.FGeometry[idx] != pg)
                                        {
                                            pg = this.FGeometry[idx];

                                            objectsettings.Geometry = pg[context];
                                            if (objectsettings.Geometry == null)
                                            {
                                                objectsettings.Geometry = new DX11InvalidGeometry();
                                            }

                                            shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, idx);
                                        }
                                    }
                                    else
                                    {
                                        objectsettings.Geometry = settings.Geometry;
                                        shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, idx);
                                    }
                                }


                                //Prepare settings
                                objectsettings.DrawCallIndex  = idx;
                                objectsettings.WorldTransform = this.mworld[idx % this.mworldcount];

                                if (settings.ValidateObject(objectsettings))
                                {
                                    variableCache.ApplySlice(objectsettings, idx);

                                    for (int ip = 0; ip < shaderdata.PassCount; ip++)
                                    {
                                        shaderdata.ApplyPass(ctx, ip);

                                        if (settings.DepthOnly)
                                        {
                                            ctx.PixelShader.Set(null);
                                        }

                                        objectsettings.Geometry.Draw();
                                    }
                                }
                            }
                        }

                        if (multistate)
                        {
                            context.RenderStateStack.Pop();
                        }
                    }

                    shaderdata.ShaderInstance.CleanUp();

                    if (pipelineState != null)
                    {
                        pipelineState.Restore(context);
                    }


                    this.OnEndQuery(context);
                }
                //this.query.End();
            }

            if (popstate)
            {
                context.RenderStateStack.Pop();
            }
            else
            {
                //Since shaders can define their own states, reapply top of the stack
                context.RenderStateStack.Apply();
            }

            if (this.FInLayer.IsConnected && this.FInEnabled[0])
            {
                this.FInLayer.RenderAll(context, settings);
            }
        }
Beispiel #5
0
        public void Render(IPluginIO pin, DX11RenderContext context, DX11RenderSettings settings)
        {
            Device        device = context.Device;
            DeviceContext ctx    = context.CurrentDeviceContext;

            bool popstate = false;

            bool multistate = this.FInState.PluginIO.IsConnected && this.FInState.SliceCount > 1;

            if (this.FInEnabled[0])
            {
                if (settings.RenderHint == eRenderHint.Collector)
                {
                    if (this.FGeometry.PluginIO.IsConnected)
                    {
                        DX11ObjectGroup group = new DX11ObjectGroup();
                        group.ShaderName = this.Source.Name;
                        group.Semantics.AddRange(settings.CustomSemantics);

                        if (this.FGeometry.SliceCount == 1)
                        {
                            IDX11Geometry g = this.FGeometry[0][context];
                            if (g.Tag != null)
                            {
                                DX11RenderObject o = new DX11RenderObject();
                                o.ObjectType = g.PrimitiveType;
                                o.Descriptor = g.Tag;
                                o.Transforms = new Matrix[spmax];
                                for (int i = 0; i < this.spmax; i++)
                                {
                                    o.Transforms[i] = this.mworld[i % this.mworldcount];
                                }
                                group.RenderObjects.Add(o);

                                settings.SceneDescriptor.Groups.Add(group);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < this.spmax; i++)
                            {
                                IDX11Geometry g = this.FGeometry[i][context];
                                if (g.Tag != null)
                                {
                                    DX11RenderObject o = new DX11RenderObject();
                                    o.ObjectType    = g.PrimitiveType;
                                    o.Descriptor    = g.Tag;
                                    o.Transforms    = new Matrix[1];
                                    o.Transforms[0] = this.mworld[i % this.mworldcount];
                                    group.RenderObjects.Add(o);
                                }
                            }

                            settings.SceneDescriptor.Groups.Add(group);
                        }
                    }
                    return;
                }

                DX11ShaderData shaderdata = this.deviceshaderdata[context];
                if ((shaderdata.IsValid &&
                     (this.geomconnected || settings.Geometry != null) &&
                     this.spmax > 0 && this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, settings)) ||
                    this.FInApplyOnly[0])
                {
                    this.OnBeginQuery(context);

                    //Need to build input layout
                    if (this.FGeometry.IsChanged || this.FInTechnique.IsChanged || shaderdata.LayoutValid.Count == 0)
                    {
                        shaderdata.Update(this.FInTechnique[0].Index, 0, this.FGeometry);
                        this.FOutLayoutValid.AssignFrom(shaderdata.LayoutValid);
                        this.FOutLayoutMsg.AssignFrom(shaderdata.LayoutMsg);
                    }

                    if (this.stateconnected && !multistate)
                    {
                        context.RenderStateStack.Push(this.FInState[0]);
                        popstate = true;
                    }

                    if (!settings.PreserveShaderStages)
                    {
                        shaderdata.ResetShaderStages(ctx);
                    }

                    settings.DrawCallCount = spmax; //Set number of draw calls

                    this.varmanager.ApplyGlobal(shaderdata.ShaderInstance);

                    //IDX11Geometry drawgeom = null;
                    objectsettings.Geometry = null;
                    DX11Resource <IDX11Geometry> pg = null;



                    for (int i = 0; i < this.spmax; i++)
                    {
                        if (multistate)
                        {
                            context.RenderStateStack.Push(this.FInState[i]);
                        }

                        if (shaderdata.IsLayoutValid(i) || settings.Geometry != null)
                        {
                            objectsettings.IterationCount = this.FIter[i];

                            for (int k = 0; k < objectsettings.IterationCount; k++)
                            {
                                objectsettings.IterationIndex = k;
                                if (settings.Geometry == null)
                                {
                                    if (this.FGeometry[i] != pg)
                                    {
                                        pg = this.FGeometry[i];

                                        objectsettings.Geometry = pg[context];

                                        shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, i);
                                    }
                                }
                                else
                                {
                                    objectsettings.Geometry = settings.Geometry;
                                    shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, i);
                                }

                                //Prepare settings
                                objectsettings.DrawCallIndex  = i;
                                objectsettings.WorldTransform = this.mworld[i % this.mworldcount];

                                if (settings.ValidateObject(objectsettings))
                                {
                                    this.varmanager.ApplyPerObject(context, shaderdata.ShaderInstance, this.objectsettings, i);

                                    shaderdata.ApplyPass(ctx);

                                    if (settings.DepthOnly)
                                    {
                                        ctx.PixelShader.Set(null);
                                    }

                                    objectsettings.Geometry.Draw();
                                    shaderdata.ShaderInstance.CleanUp();
                                }
                            }
                        }

                        if (multistate)
                        {
                            context.RenderStateStack.Pop();
                        }
                    }

                    this.OnEndQuery(context);
                }
                //this.query.End();
            }

            if (popstate)
            {
                context.RenderStateStack.Pop();
            }
            else
            {
                //Since shaders can define their own states, reapply top of the stack
                context.RenderStateStack.Apply();
            }
        }
        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];
            }
        }
Beispiel #7
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[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;
                    }
                    #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);

                        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;

                            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 (pi.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); }
        }
        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); }
        }
Beispiel #9
0
        public void Render(IPluginIO pin, DX11RenderContext context, DX11RenderSettings settings)
        {
            Device        device = context.Device;
            DeviceContext ctx    = context.CurrentDeviceContext;

            bool popstate = false;

            if (this.FInEnabled[0])
            {
                DX11ShaderData shaderdata = this.deviceshaderdata[context];
                if ((shaderdata.IsValid &&
                     (this.geomconnected || settings.Geometry != null) &&
                     this.spmax > 0 && this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, settings)) ||
                    this.FInApplyOnly[0])
                {
                    this.OnBeginQuery(context);

                    //Need to build input layout
                    if (this.FGeometry.IsChanged || this.FInTechnique.IsChanged || shaderdata.LayoutValid.Count == 0)
                    {
                        shaderdata.Update(this.FInTechnique[0].Index, 0, this.FGeometry);
                        this.FOutLayoutValid.AssignFrom(shaderdata.LayoutValid);
                        this.FOutLayoutMsg.AssignFrom(shaderdata.LayoutMsg);
                    }

                    if (this.stateconnected)
                    {
                        context.RenderStateStack.Push(this.FInState[0]);
                        popstate = true;
                    }

                    if (!settings.PreserveShaderStages)
                    {
                        shaderdata.ResetShaderStages(ctx);
                    }

                    settings.DrawCallCount = spmax; //Set number of draw calls

                    this.varmanager.ApplyGlobal(shaderdata.ShaderInstance);

                    //IDX11Geometry drawgeom = null;
                    objectsettings.Geometry = null;
                    DX11Resource <IDX11Geometry> pg = null;



                    for (int i = 0; i < this.spmax; i++)
                    {
                        if (shaderdata.IsLayoutValid(i) || settings.Geometry != null)
                        {
                            objectsettings.IterationCount = this.FIter[i];

                            for (int k = 0; k < objectsettings.IterationCount; k++)
                            {
                                objectsettings.IterationIndex = k;
                                if (settings.Geometry == null)
                                {
                                    if (this.FGeometry[i] != pg)
                                    {
                                        pg = this.FGeometry[i];

                                        objectsettings.Geometry = pg[context];

                                        shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, i);
                                    }
                                }
                                else
                                {
                                    objectsettings.Geometry = settings.Geometry;
                                    shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, i);
                                }

                                //Prepare settings
                                objectsettings.DrawCallIndex  = i;
                                objectsettings.WorldTransform = this.mworld[i % this.mworldcount];

                                if (settings.ValidateObject(objectsettings))
                                {
                                    this.varmanager.ApplyPerObject(context, shaderdata.ShaderInstance, this.objectsettings, i);

                                    shaderdata.ApplyPass(ctx);

                                    if (settings.DepthOnly)
                                    {
                                        ctx.PixelShader.Set(null);
                                    }

                                    objectsettings.Geometry.Draw();
                                    shaderdata.ShaderInstance.CleanUp();
                                }
                            }
                        }
                    }

                    this.OnEndQuery(context);
                }
                //this.query.End();
            }

            if (popstate)
            {
                context.RenderStateStack.Pop();
            }
            else
            {
                //Since shaders can define their own states, reapply top of the stack
                context.RenderStateStack.Apply();
            }
        }
Beispiel #10
0
        public void Render(IPluginIO pin, DX11RenderContext context, DX11RenderSettings settings)
        {
            Device        device = context.Device;
            DeviceContext ctx    = context.CurrentDeviceContext;

            bool popstate = false;

            bool multistate = this.FInState.IsConnected && this.FInState.SliceCount > 1;

            if (this.FInEnabled[0])
            {
                //In that case we do not care about geometry, but only apply pass for globals
                if (settings.RenderHint == eRenderHint.ApplyOnly)
                {
                    DX11ShaderData sdata = this.deviceshaderdata[context];
                    this.varmanager.SetGlobalSettings(sdata.ShaderInstance, settings);
                    this.varmanager.ApplyGlobal(sdata.ShaderInstance);

                    DX11ObjectRenderSettings oset = new DX11ObjectRenderSettings();
                    oset.DrawCallIndex  = 0;
                    oset.Geometry       = null;
                    oset.IterationCount = 1;
                    oset.IterationIndex = 0;
                    oset.WorldTransform = this.mworld[0 % this.mworldcount];
                    this.varmanager.ApplyPerObject(context, sdata.ShaderInstance, oset, 0);
                    sdata.ApplyPass(ctx);


                    if (this.FInLayer.IsConnected)
                    {
                        this.FInLayer[0][context].Render(this.FInLayer.PluginIO, context, settings);
                    }

                    return;
                }

                if (settings.RenderHint == eRenderHint.Collector)
                {
                    if (this.FGeometry.PluginIO.IsConnected)
                    {
                        DX11ObjectGroup group = new DX11ObjectGroup();
                        group.ShaderName = this.Source.Name;
                        group.Semantics.AddRange(settings.CustomSemantics);

                        if (this.FGeometry.SliceCount == 1)
                        {
                            IDX11Geometry g = this.FGeometry[0][context];
                            if (g.Tag != null)
                            {
                                DX11RenderObject o = new DX11RenderObject();
                                o.ObjectType = g.PrimitiveType;
                                o.Descriptor = g.Tag;
                                o.Transforms = new Matrix[spmax];
                                for (int i = 0; i < this.spmax; i++)
                                {
                                    o.Transforms[i] = this.mworld[i % this.mworldcount];
                                }
                                group.RenderObjects.Add(o);

                                settings.SceneDescriptor.Groups.Add(group);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < this.spmax; i++)
                            {
                                IDX11Geometry g = this.FGeometry[i][context];
                                if (g.Tag != null)
                                {
                                    DX11RenderObject o = new DX11RenderObject();
                                    o.ObjectType    = g.PrimitiveType;
                                    o.Descriptor    = g.Tag;
                                    o.Transforms    = new Matrix[1];
                                    o.Transforms[0] = this.mworld[i % this.mworldcount];
                                    group.RenderObjects.Add(o);
                                }
                            }

                            settings.SceneDescriptor.Groups.Add(group);
                        }
                    }
                    return;
                }

                DX11ShaderData shaderdata = this.deviceshaderdata[context];
                if ((shaderdata.IsValid &&
                     (this.geomconnected || settings.Geometry != null) &&
                     this.spmax > 0 && this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, settings)) ||
                    this.FInApplyOnly[0])
                {
                    this.OnBeginQuery(context);

                    //Select preferred technique if available
                    if (settings.PreferredTechniques.Count == 0 && this.techniqueindex != this.FInTechnique[0].Index)
                    {
                        this.techniqueindex   = this.FInTechnique[0].Index;
                        this.techniquechanged = true;
                    }
                    else if (settings.PreferredTechniques.Count > 0)
                    {
                        int i = settings.GetPreferredTechnique(this.FShader);
                        if (i == -1)
                        {
                            i = this.FInTechnique[0].Index;
                        }
                        if (i != this.techniqueindex)
                        {
                            this.techniqueindex   = i;
                            this.techniquechanged = true;
                        }
                    }

                    //Need to build input layout
                    if (this.FGeometry.IsChanged || this.techniquechanged || shaderdata.LayoutValid.Count == 0)
                    {
                        shaderdata.Update(this.techniqueindex, 0, this.FGeometry);
                        this.FOutLayoutValid.AssignFrom(shaderdata.LayoutValid);
                        this.FOutLayoutMsg.AssignFrom(shaderdata.LayoutMsg);

                        int           errorCount = 0;
                        StringBuilder sbMsg      = new StringBuilder();
                        sbMsg.Append("Invalid layout detected for slices:");
                        for (int i = 0; i < shaderdata.LayoutValid.Count; i++)
                        {
                            if (shaderdata.LayoutValid[i] == false)
                            {
                                errorCount++;
                                sbMsg.Append(i + ",");
                            }
                        }

                        if (errorCount > 0)
                        {
                            this.FHost.Log(TLogType.Warning, sbMsg.ToString());
                        }

                        this.techniquechanged = false;
                    }

                    if (this.stateconnected && !multistate)
                    {
                        context.RenderStateStack.Push(this.FInState[0]);
                        popstate = true;
                    }

                    ShaderPipelineState pipelineState = null;
                    if (!settings.PreserveShaderStages)
                    {
                        shaderdata.ResetShaderStages(ctx);
                    }
                    else
                    {
                        pipelineState = new ShaderPipelineState(context);
                    }

                    settings.DrawCallCount = spmax; //Set number of draw calls

                    this.varmanager.ApplyGlobal(shaderdata.ShaderInstance);

                    //IDX11Geometry drawgeom = null;
                    objectsettings.Geometry = null;
                    DX11Resource <IDX11Geometry> pg = null;
                    bool       doOrder       = false;
                    List <int> orderedSlices = null;
                    if (settings.LayerOrder != null && settings.LayerOrder.Enabled)
                    {
                        this.orderedObjectSettings.Clear();
                        for (int i = 0; i < this.spmax; i++)
                        {
                            DX11ObjectRenderSettings objSettings = new DX11ObjectRenderSettings();
                            objSettings.DrawCallIndex  = i;
                            objSettings.Geometry       = null;
                            objSettings.IterationCount = 1;
                            objSettings.IterationIndex = 0;
                            objSettings.WorldTransform = this.mworld[i % this.mworldcount];

                            this.orderedObjectSettings.Add(objSettings);
                        }

                        orderedSlices = settings.LayerOrder.Reorder(settings, orderedObjectSettings);
                        doOrder       = true;
                    }

                    int drawCount = doOrder ? orderedSlices.Count : this.spmax;

                    if (this.spmax == 0)
                    {
                        drawCount = 0;
                    }

                    for (int i = 0; i < drawCount; i++)
                    {
                        int idx = doOrder ? orderedSlices[i] : i;
                        if (multistate)
                        {
                            context.RenderStateStack.Push(this.FInState[idx]);
                        }

                        if (shaderdata.IsLayoutValid(idx) || settings.Geometry != null)
                        {
                            objectsettings.IterationCount = this.FIter[idx];

                            for (int k = 0; k < objectsettings.IterationCount; k++)
                            {
                                objectsettings.IterationIndex = k;
                                if (settings.Geometry == null)
                                {
                                    if (this.FGeometry[idx] != pg)
                                    {
                                        pg = this.FGeometry[idx];

                                        objectsettings.Geometry = pg[context];

                                        shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, idx);
                                    }
                                }
                                else
                                {
                                    objectsettings.Geometry = settings.Geometry;
                                    shaderdata.SetInputAssembler(ctx, objectsettings.Geometry, idx);
                                }

                                //Prepare settings
                                objectsettings.DrawCallIndex  = idx;
                                objectsettings.WorldTransform = this.mworld[idx % this.mworldcount];

                                if (settings.ValidateObject(objectsettings))
                                {
                                    this.varmanager.ApplyPerObject(context, shaderdata.ShaderInstance, this.objectsettings, idx);

                                    shaderdata.ApplyPass(ctx);

                                    if (settings.DepthOnly)
                                    {
                                        ctx.PixelShader.Set(null);
                                    }

                                    if (settings.PostPassAction != null)
                                    {
                                        settings.PostPassAction(context);
                                    }


                                    objectsettings.Geometry.Draw();
                                    shaderdata.ShaderInstance.CleanUp();
                                }
                            }
                        }

                        if (multistate)
                        {
                            context.RenderStateStack.Pop();
                        }

                        if (settings.PostShaderAction != null)
                        {
                            settings.PostShaderAction(context);
                        }
                    }

                    if (pipelineState != null)
                    {
                        pipelineState.Restore(context);
                    }


                    this.OnEndQuery(context);
                }
                //this.query.End();
            }

            if (popstate)
            {
                context.RenderStateStack.Pop();
            }
            else
            {
                //Since shaders can define their own states, reapply top of the stack
                context.RenderStateStack.Apply();
            }

            if (this.FInLayer.IsConnected && this.FInEnabled[0])
            {
                this.FInLayer[0][context].Render(this.FInLayer.PluginIO, context, settings);
            }
        }
Beispiel #11
0
        public void Update(DX11RenderContext context)
        {
            Device        device = context.Device;
            DeviceContext ctx    = context.CurrentDeviceContext;

            if (!this.deviceshaderdata.Contains(context))
            {
                this.deviceshaderdata[context] = new DX11ShaderData(context, this.FShader);
            }
            if (!this.shaderVariableCache.Contains(context))
            {
                this.shaderVariableCache[context] = new DX11ShaderVariableCache(context, this.deviceshaderdata[context].ShaderInstance, this.varmanager);
            }
            if (!this.imageShaderInfo.Contains(context))
            {
                this.imageShaderInfo[context] = new ImageShaderInfo(this.deviceshaderdata[context].ShaderInstance);
            }

            DX11ShaderData  shaderdata = this.deviceshaderdata[context];
            ImageShaderInfo shaderInfo = this.imageShaderInfo[context];

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

            this.OnBeginQuery(context);


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

            for (int i = 0; i < this.previousFrameResults.SliceCount; i++)
            {
                if (this.FInEnabled[i] || this.FInPreserveOnDisable[i] == false)
                {
                    this.previousFrameResults[i]?.UnLock();
                    this.previousFrameResults[i] = null;
                }
            }


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

            renderSettings.CustomSemantics.Clear();
            renderSettings.ResourceSemantics.Clear();

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

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

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

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

                    renderSettings.RenderWidth  = wi;
                    renderSettings.RenderHeight = he;


                    this.varmanager.SetGlobalSettings(shaderdata.ShaderInstance, renderSettings);
                    var variableCache = this.shaderVariableCache[context];
                    variableCache.ApplyGlobals(renderSettings);


                    DX11ResourcePoolEntry <DX11RenderTarget2D> lasttmp = null;

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

                    //Go trough all passes
                    int tid = this.FInTechnique[textureIndex].Index;
                    ImageShaderTechniqueInfo techniqueInfo = shaderInfo.GetTechniqueInfo(tid);

                    //Now we need to add optional extra pass in case we want mip chain (only in case it's not needed, if texture has mips we just ignore)
                    if (techniqueInfo.WantMips)
                    {
                        //Single level and bigger than 1 should get a mip generation pass
                        if (initial.Width > 1 && initial.Height > 1 && initial.Resource.Description.MipLevels == 1)
                        {
                            //Texture might now be an allowed render target format, so we at least need to check that, and default to rgba8 unorm
                            //also check for auto mip map gen
                            var mipTargetFmt = initial.Format;
                            if (!context.IsSupported(FormatSupport.RenderTarget, mipTargetFmt) ||
                                !context.IsSupported(FormatSupport.MipMapAutoGeneration, mipTargetFmt) ||
                                !context.IsSupported(FormatSupport.UnorderedAccessView, mipTargetFmt))
                            {
                                mipTargetFmt = Format.R8G8B8A8_UNorm;
                            }



                            DX11ResourcePoolEntry <DX11RenderTarget2D> mipTarget = context.ResourcePool.LockRenderTarget(initial.Width, initial.Height, mipTargetFmt, new SampleDescription(1, 0), true, 0);
                            locktargets.Add(mipTarget);

                            context.RenderTargetStack.Push(mipTarget.Element);

                            context.BasicEffects.PointSamplerPixelPass.Apply(initial.SRV);

                            context.CurrentDeviceContext.Draw(3, 0);

                            context.RenderTargetStack.Pop();

                            context.CurrentDeviceContext.GenerateMips(mipTarget.Element.SRV);

                            //Replace initial by our new texture
                            initial = mipTarget.Element;
                        }
                    }

                    //Bind Initial (once only is ok) and mark for previous usage too
                    DX11Texture2D lastrt = initial;
                    shaderInfo.ApplyInitial(initial.SRV);

                    for (int passIndex = 0; passIndex < techniqueInfo.PassCount; passIndex++)
                    {
                        ImageShaderPassInfo passInfo = techniqueInfo.GetPassInfo(passIndex);
                        bool isLastPass = passIndex == techniqueInfo.PassCount - 1;


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

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

                        if (passInfo.DoScale)
                        {
                            if (passInfo.Absolute)
                            {
                                w = Convert.ToInt32(passInfo.ScaleVector.X);
                                h = Convert.ToInt32(passInfo.ScaleVector.Y);
                            }
                            else
                            {
                                w = Convert.ToInt32((float)w * passInfo.ScaleVector.X);
                                h = Convert.ToInt32((float)h * passInfo.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;
                        }

                        //To avoid uav issue
                        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.IsConnected && passInfo.UseDepth)
                        {
                            context.RenderTargetStack.Push(this.FDepthIn[0][context], true, elem.Element);
                        }
                        else
                        {
                            context.RenderTargetStack.Push(elem.Element);
                        }

                        if (passInfo.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 (passInfo.DepthPreset != "")
                        {
                            try
                            {
                                ds         = DX11DepthStencilStates.GetState(passInfo.DepthPreset);
                                validdepth = true;
                            }
                            catch
                            {
                            }
                        }

                        if (passInfo.BlendPreset != "")
                        {
                            try
                            {
                                bs         = DX11BlendStates.GetState(passInfo.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);
                        }

                        renderSettings.RenderWidth  = w;
                        renderSettings.RenderHeight = h;
                        renderSettings.BackBuffer   = elem.Element;

                        //Apply settings (we do both here, as texture size semantic might ahve
                        variableCache.ApplyGlobals(renderSettings);
                        variableCache.ApplySlice(objectSettings, textureIndex);
                        //Bind last render target

                        shaderInfo.ApplyPrevious(lastrt.SRV);

                        this.BindPassIndexSemantic(shaderdata.ShaderInstance.Effect, passIndex);

                        if (this.FDepthIn.IsConnected)
                        {
                            if (this.FDepthIn[0].Contains(context))
                            {
                                shaderInfo.ApplyDepth(this.FDepthIn[0][context].SRV);
                            }
                        }

                        for (int list = 0; list < this.FinPrePostActions.SliceCount; list++)
                        {
                            if (this.FinPrePostActions[list] != null)
                            {
                                this.FinPrePostActions[list].OnBeginPass(context, passIndex);
                            }
                        }

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

                        if (passInfo.ComputeData.Enabled)
                        {
                            passInfo.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 (!passInfo.KeepTarget)
                        {
                            rtlist.Add(rt);
                            lastrt          = rt;
                            lasttmp         = elem;
                            preservedtarget = null;
                            passcounter++;
                        }
                        else
                        {
                            preservedtarget = elem;
                        }


                        context.RenderTargetStack.Pop();

                        //Apply pass result semantic if applicable (after pop)
                        shaderInfo.ApplyPassResult(lasttmp.Element.SRV, passIndex);

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

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

                        for (int list = 0; list < this.FinPrePostActions.SliceCount; list++)
                        {
                            if (this.FinPrePostActions[list] != null)
                            {
                                this.FinPrePostActions[list].OnEndPass(context, passIndex);
                            }
                        }
                    }

                    //Set last render target
                    this.FOut[textureIndex][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.previousFrameResults[textureIndex] = lasttmp;
                }
                else
                {
                    if (this.FInPreserveOnDisable[textureIndex])
                    {
                        //We kept it locked on top
                        this.FOut[textureIndex][context] = this.previousFrameResults[textureIndex] != null ? this.previousFrameResults[textureIndex].Element : null;
                    }
                    else
                    {
                        this.FOut[textureIndex][context] = this.FIn[textureIndex][context];
                    }
                }
            }

            context.RenderStateStack.Pop();

            this.OnEndQuery(context);
        }