public void Evaluate(int SpreadMax) { if (this.FBlendMode.IsChanged || this.FDepthMode.IsChanged || this.FRasterMode.IsChanged || this.FInStencilReference.IsChanged) { this.FOutState.SliceCount = SpreadMax; for (int i = 0; i < SpreadMax; i++) { this.FOutState[i] = new DX11RenderState() { Blend = DX11BlendStates.GetState(this.FBlendMode[i]), DepthStencil = DX11DepthStencilStates.GetState(this.FDepthMode[i]), Rasterizer = DX11RasterizerStates.GetState(this.FRasterMode[i]), DepthStencilReference = FInStencilReference[i], BlendFactor = FInBlendFactor[i] }; } } }
public void Evaluate(int SpreadMax) { if (this.FMode.IsChanged || this.FInState.IsChanged) { this.FOutState.SliceCount = SpreadMax; for (int i = 0; i < SpreadMax; i++) { DX11RenderState rs; if (this.FInState.IsConnected) { rs = this.FInState[i].Clone(); } else { rs = new DX11RenderState(); } rs.Blend = DX11BlendStates.GetState(this.FMode[i]); this.FOutState[i] = rs; } } }
public void Render(DX11RenderContext context) { if (this.lasthandle != this.Handle) { if (this.swapchain != null) { if (this.swapchain.Contains(context)) { this.swapchain.Dispose(context); } } this.lasthandle = this.Handle; } if (!this.swapchain.Contains(context)) { this.swapchain[context] = new DX11SwapChain(context, this.Handle, SlimDX.DXGI.Format.R8G8B8A8_UNorm, new SampleDescription(1, 0), 60, 1, false); } if (this.resized) { this.swapchain[context].Resize(); } if (this.FEnabled[0]) { context.CurrentDeviceContext.ClearRenderTargetView(this.swapchain[context].RTV, new SlimDX.Color4(0, 0, 0, 0)); } if (this.FIn.IsConnected && this.spreadMax > 0 && this.FEnabled[0]) { int id = this.FIndex[0]; if (this.FIn[id].Contains(context) && this.FIn[id][context] != null) { context.RenderTargetStack.Push(this.swapchain[context]); var rs = new DX11RenderState(); if (FAlpha[0]) { rs.Blend = DX11BlendStates.GetState(BlendStatePreset.Blend); context.CurrentDeviceContext.ClearRenderTargetView(this.swapchain[context].RTV, FInBgColor[0].Color); } context.RenderStateStack.Push(rs); context.CleanShaderStages(); context.Primitives.FullTriVS.GetVariableBySemantic("TEXTURE").AsResource().SetResource(this.FIn[id][context].SRV); EffectSamplerVariable samplervariable = context.Primitives.FullTriVS.GetVariableByName("linSamp").AsSampler(); SamplerState state = null; if (this.FInSamplerState.IsConnected) { state = SamplerState.FromDescription(context.Device, this.FInSamplerState[0]); samplervariable.SetSamplerState(0, state); } else { samplervariable.UndoSetSamplerState(0); } context.Primitives.FullScreenTriangle.Bind(null); context.Primitives.ApplyFullTri(); context.Primitives.FullScreenTriangle.Draw(); context.RenderStateStack.Pop(); context.RenderTargetStack.Pop(); context.CleanUpPS(); samplervariable.UndoSetSamplerState(0); //undo as can be used in other places if (state != null) { state.Dispose(); } } } }
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); }
public void Render(DX11RenderContext context, DX11RenderSettings settings) { if (this.spmax == 0) { return; } if (this.BeginQuery != null) { this.BeginQuery(context); } context.CleanShaderStages(); ShaderDeviceData deviceData = this.shaderData[context]; context.Primitives.FullScreenTriangle.Bind(null); for (int i = 0; i < spmax; i++) { if (this.FEnabled[i]) { if (this.FInState.IsConnected) { context.RenderStateStack.Push(this.FInState[i]); } else { this.defaultState.Blend = DX11BlendStates.GetState(this.FInBlendState[i]); context.RenderStateStack.Push(this.defaultState); } if (this.FInSamplerState.IsConnected) { SamplerState state = SamplerState.FromDescription(context.Device, this.FInSamplerState[i]); deviceData.samplerVariable.SetSamplerState(0, state); } else { deviceData.samplerVariable.UndoSetSamplerState(0); } var color = this.FInColor[i]; color.Alpha *= settings.LayerOpacity; deviceData.colorVariable.Set(color); deviceData.texTransformVariable.SetMatrix(this.FInTexTransform[i]); if (this.FInTexture.IsConnected) { if (this.FInTexture[i].Contains(context) && this.FInTexture[i][context] != null) { deviceData.inputTextureVariable.SetResource(this.FInTexture[i][context].SRV); } else { deviceData.inputTextureVariable.SetResource(null); } } else { deviceData.inputTextureVariable.SetResource(context.DefaultTextures.WhiteTexture.SRV); } deviceData.pass.Apply(context.CurrentDeviceContext); context.CurrentDeviceContext.Draw(3, 0); context.RenderStateStack.Pop(); } } if (this.EndQuery != null) { this.EndQuery(context); } }