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); } }
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); } }