protected override void OnUpdate(DX11RenderContext context) { //Grab a temp target if enabled TexInfo ti = this.rtm.GetRenderTarget(context); if (ti.w != this.width || ti.h != this.height || !this.targets.ContainsKey(context) || this.invalidate || ti.format != this.format) { this.invalidate = false; this.width = ti.w; this.height = ti.h; this.format = ti.format; this.depthmanager.NeedReset = true; if (targets.ContainsKey(context)) { context.ResourcePool.Unlock(targets[context]); } if (targetresolve.ContainsKey(context)) { context.ResourcePool.Unlock(targetresolve[context]); } int aacount = Convert.ToInt32(this.FInAASamplesPerPixel[0].Name); int aaquality = 0; if (aacount > 1) { List <SampleDescription> sds = context.GetMultisampleFormatInfo(ti.format); int maxlevels = sds[sds.Count - 1].Count; if (aacount > maxlevels) { FHost.Log(TLogType.Warning, "Multisample count too high for this format, reverted to: " + maxlevels); aacount = maxlevels; } DX11RenderTarget2D temptarget = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element; DX11RenderTarget2D temptargetresolve = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(1, 0), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element; targets[context] = temptarget; targetresolve[context] = temptargetresolve; this.FOutBuffers[0][context] = temptargetresolve; this.FOutAABuffers[0][context] = temptarget; } else { //Bind both texture as same output DX11RenderTarget2D temptarget = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element; targets[context] = temptarget; this.FOutBuffers[0][context] = temptarget; this.FOutAABuffers[0][context] = temptarget; } } }
public void Update(DX11RenderContext context) { Device device = context.Device; if (this.spmax == 0) { return; } if (this.updateddevices.Contains(context)) { return; } if (!this.FOutTexture[0].Contains(context)) { for (int i = 0; i < this.FInElementCount[0]; i++) { var rt = new DX11RenderTarget2D(context, (int)this.FInSize[i].X, (int)this.FInSize[i].Y, new SampleDescription(1, 0), DeviceFormatHelper.GetFormat(this.FInFormat[i]), this.FInMips[i], 0, false, false); this.FOutTexture[i][context] = rt; if (this.FInDepthBuffer[0]) { Format depthfmt = DeviceFormatHelper.GetFormat(this.depthformatpin[0].Name); var db = new DX11DepthStencil(context, (int)this.FInSize[i].X, (int)this.FInSize[i].Y, new SampleDescription(1, 0), depthfmt); this.FOutDepthTexture[i][context] = db; } } } this.updateddevices.Add(context); }
public void CreateWithUAV() { DX11RenderTarget2D rt = new DX11RenderTarget2D(this.Device, 320, 240, new SampleDescription(1, 0), SharpDX.DXGI.Format.R8G8B8A8_UNorm, false, 0, true); Assert.IsNotNull(rt.UnorderedView); rt.Dispose(); }
public void TestTwoTarget() { DX11RenderTarget2D rt1 = this.Device.ResourcePool.LockRenderTarget(100, 100, SharpDX.DXGI.Format.R8G8B8A8_UNorm); this.Device.ResourcePool.Unlock(rt1); DX11RenderTarget2D rt2 = this.Device.ResourcePool.LockRenderTarget(120, 100, SharpDX.DXGI.Format.R8G8B8A8_UNorm); Assert.AreNotEqual(rt1.Texture.NativePointer, rt2.Texture.NativePointer); }
public void CreateMS() { DX11RenderTarget2D rt = new DX11RenderTarget2D(this.Device, 320, 240, new SampleDescription(2, 0), SharpDX.DXGI.Format.R8G8B8A8_UNorm, false, 0, false); Assert.IsNull(rt.UnorderedView); rt.Dispose(); //Since we have multisampled version, flag for uav should be ignored rt = new DX11RenderTarget2D(this.Device, 320, 240, new SampleDescription(2, 0), SharpDX.DXGI.Format.R8G8B8A8_UNorm, false, 0, true); Assert.IsNull(rt.UnorderedView); rt.Dispose(); }
public void Update(DX11RenderContext context) { if (!init) { PluginEntry.InitHBAO(context.Device.ComPointer); PluginEntry.SetDepthParameters(FDepthIn[0][context].SRV.ComPointer, Array.ConvertAll(FProjIn[0].Values, x => (float)x), FSceneScaleIn[0]); PluginEntry.SetAoParameters(FRadiusIn[0], FBiasIn[0], FPowerExpIn[0], FSmallScaleAoIn[0], FLargeScaleAoIn[0], FStepCountIn[0], FForegroundAoIn[0], FForegroundViewDepthIn[0], FBackgroundAoIn[0], FBackgroundViewDepthIn[0], FDepthStorageIn[0], FDepthClampModeIn[0], FDepthThresholdIn[0], FDepthThresholdMaxViewDepthIn[0], FDepthThresholdSharpnessIn[0], FBlurIn[0], FBlurRadiusIn[0], FBlurSharpnessIn[0], FBlurSharpnessProfileIn[0], FBlurSharpnessProfileForegroundScaleIn[0], FBlurSharpnessProfileForegroundViewDepthIn[0], FBlurSharpnessProfileBackgroundViewDepthIn[0]); init = true; } w = FDepthIn[0][context].Width; h = FDepthIn[0][context].Height; aa = FDepthIn[0][context].Description.SampleDescription.Count; if (w != lastW || h != lastH || aa != lastAa || reset) { lastW = w; lastH = h; lastAa = aa; rt?.Dispose(); rt = new DX11RenderTarget2D(context, w, h, new SampleDescription(1, 0), Format.R8G8B8A8_UNorm); FOut[0][context] = rt; // make sure it doesn't try to run on the old depth buffer PluginEntry.SetDepthParameters(FDepthIn[0][context].SRV.ComPointer, Array.ConvertAll(FProjIn[0].Values, x => (float)x), FSceneScaleIn[0]); reset = false; } if (FProjIn.IsChanged || FSceneScaleIn.IsChanged) { PluginEntry.SetDepthParameters(FDepthIn[0][context].SRV.ComPointer, Array.ConvertAll(FProjIn[0].Values, x => (float)x), FSceneScaleIn[0]); } // uff if (FRadiusIn.IsChanged || FBiasIn.IsChanged || FPowerExpIn.IsChanged || FSmallScaleAoIn.IsChanged || FLargeScaleAoIn.IsChanged || FStepCountIn.IsChanged || FForegroundAoIn.IsChanged || FForegroundViewDepthIn.IsChanged || FBackgroundAoIn.IsChanged || FBackgroundViewDepthIn.IsChanged || FDepthStorageIn.IsChanged || FDepthClampModeIn.IsChanged || FDepthThresholdIn.IsChanged || FDepthThresholdMaxViewDepthIn.IsChanged || FDepthThresholdSharpnessIn.IsChanged || FBlurIn.IsChanged || FBlurRadiusIn.IsChanged || FBlurSharpnessIn.IsChanged || FBlurSharpnessProfileIn.IsChanged || FBlurSharpnessProfileForegroundScaleIn.IsChanged || FBlurSharpnessProfileForegroundViewDepthIn.IsChanged || FBlurSharpnessProfileBackgroundViewDepthIn.IsChanged) { PluginEntry.SetAoParameters(FRadiusIn[0], FBiasIn[0], FPowerExpIn[0], FSmallScaleAoIn[0], FLargeScaleAoIn[0], FStepCountIn[0], FForegroundAoIn[0], FForegroundViewDepthIn[0], FBackgroundAoIn[0], FBackgroundViewDepthIn[0], FDepthStorageIn[0], FDepthClampModeIn[0], FDepthThresholdIn[0], FDepthThresholdMaxViewDepthIn[0], FDepthThresholdSharpnessIn[0], FBlurIn[0], FBlurRadiusIn[0], FBlurSharpnessIn[0], FBlurSharpnessProfileIn[0], FBlurSharpnessProfileForegroundScaleIn[0], FBlurSharpnessProfileForegroundViewDepthIn[0], FBlurSharpnessProfileBackgroundViewDepthIn[0]); } BeginQuery?.Invoke(context); RenderHBAO(context.CurrentDeviceContext.ComPointer, rt.RTV.ComPointer); EndQuery?.Invoke(context); }
public DX11RenderTarget2D PlaceRenderTarget(RenderContext context, int width, int height, SharpDX.DXGI.Format format) { var rt = DX11RenderTarget2D.CreateTiled(this.device, width, height, format); int fs = SharpDX.DXGI.FormatHelper.SizeOfInBytes(format); var tiledSize = this.AlignImage(rt.Width, rt.Height, format); int rtSize = tiledSize.Width * tiledSize.Height * fs; this.AggregateMemory(context, rtSize); MapEntireResource(context, rt.Texture); this.currentRangeOffset = this.aggregatedPageCount; return(rt); }
protected override void OnUpdate(DX11RenderContext context) { //Grab a temp target if enabled TexInfo ti = this.rtm.GetRenderTarget(context); if (ti.w != this.width || ti.h != this.height || !this.targets.ContainsKey(context) || this.FInAASamplesPerPixel.IsChanged) { this.width = ti.w; this.height = ti.h; this.depthmanager.NeedReset = true; if (targets.ContainsKey(context)) { context.ResourcePool.Unlock(targets[context]); } if (targetresolve.ContainsKey(context)) { context.ResourcePool.Unlock(targetresolve[context]); } int aacount = Convert.ToInt32(this.FInAASamplesPerPixel[0].Name); int aaquality = 0; if (aacount > 1) { DX11RenderTarget2D temptarget = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element; DX11RenderTarget2D temptargetresolve = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(1, 0), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element; targets[context] = temptarget; targetresolve[context] = temptargetresolve; this.FOutBuffers[0][context] = temptargetresolve; this.FOutAABuffers[0][context] = temptarget; } else { //Bind both texture as same output DX11RenderTarget2D temptarget = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0]).Element; targets[context] = temptarget; this.FOutBuffers[0][context] = temptarget; this.FOutAABuffers[0][context] = temptarget; } } }
protected override void OnUpdate(DX11RenderContext context) { if (this.resetbuffers || !this.FOutBuffers[0].Contains(context)) { this.DisposeBuffers(context); for (int i = 0; i < this.FInTargetCount[0]; i++) { DX11RenderTarget2D rt = new DX11RenderTarget2D(context, this.width, this.height, this.sd, DeviceFormatHelper.GetFormat(this.FInFormat[i].Name), this.genmipmap, this.mipmaplevel); #if DEBUG rt.Resource.DebugName = "MRTRenderTexture"; #endif this.FOutBuffers[i][context] = rt; } } }
public void Unlock(DX11RenderTarget2D target) { this.targetpool.UnLock(target); }
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); } }
protected override void OnUpdate(DX11RenderContext context) { bool resetta = true; try { var ptadesc = FOutTexArray[0][context].Description; resetta = FTADepth[0] != ptadesc.ArraySize || (int)FTASize[0].x != ptadesc.Width || (int)FTASize[0].y != ptadesc.Height || FTAFormat[0] != ptadesc.Format; } catch (Exception e) { } if (resetta) { try { FOutTexArray[0].Dispose(context); } catch (Exception e) { } var tadesc = new Texture2DDescription { ArraySize = FTADepth[0], Width = (int)FTASize[0].x, Height = (int)FTASize[0].y, Format = FTAFormat[0], BindFlags = BindFlags.UnorderedAccess | BindFlags.ShaderResource, //CpuAccessFlags = CpuAccessFlags.None, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), //Usage = ResourceUsage.Default }; FOutTexArray[0][context] = new DX11RWTextureArray2D(context, new Texture2D(context.Device, tadesc)); foreach (var semantic in CustomSemantics) { semantic.Dispose(); } CustomSemantics.Clear(); CustomSemantics.Add(new RWTexture2dArrayRenderSemantic("TEXTUREARRAY", false) { Data = FOutTexArray[0][context] }); CustomSemantics.Add(new Texture2dArrayRenderSemantic("TEXTUREARRAY_SRV", false) { Data = FOutTexArray[0][context] }); } TexInfo ti = this.rtm.GetRenderTarget(context); if (ti.w != this.width || ti.h != this.height || !this.targets.ContainsKey(context) || this.invalidate || ti.format != this.format) { this.invalidate = false; this.width = ti.w; this.height = ti.h; this.format = ti.format; this.depthmanager.NeedReset = true; if (targets.ContainsKey(context)) { context.ResourcePool.Unlock(targets[context]); } if (targetresolve.ContainsKey(context)) { context.ResourcePool.Unlock(targetresolve[context]); } int aacount = Convert.ToInt32(this.FInAASamplesPerPixel[0].Name); int aaquality = 0; if (aacount > 1) { List <SampleDescription> sds = context.GetMultisampleFormatInfo(ti.format); int maxlevels = sds[sds.Count - 1].Count; if (aacount > maxlevels) { FHost.Log(TLogType.Warning, "Multisample count too high for this format, reverted to: " + maxlevels); aacount = maxlevels; } DX11RenderTarget2D temptarget = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0], this.FInSharedTex[0]).Element; DX11RenderTarget2D temptargetresolve = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(1, 0), this.FInDoMipMaps[0], this.FInMipLevel[0], this.FInSharedTex[0]).Element; targets[context] = temptarget; targetresolve[context] = temptargetresolve; this.FOutBuffers[0][context] = temptargetresolve; this.FOutAABuffers[0][context] = temptarget; } else { //Bind both texture as same output DX11RenderTarget2D temptarget = context.ResourcePool.LockRenderTarget(this.width, this.height, ti.format, new SampleDescription(aacount, aaquality), this.FInDoMipMaps[0], this.FInMipLevel[0], this.FInSharedTex[0]).Element; targets[context] = temptarget; this.FOutBuffers[0][context] = temptarget; this.FOutAABuffers[0][context] = temptarget; } } }
public void Render(DX11RenderContext context) { Device device = context.Device; //Just in case if (!this.updateddevices.Contains(context)) { this.Update(context); } if (this.rendereddevices.Contains(context)) { return; } if (this.FInEnabled[0]) { if (this.BeginQuery != null) { this.BeginQuery(context); } int sliceCount = this.FInElementCount[0]; for (int i = 0; i < sliceCount; i++) { DX11RenderTarget2D target = this.FOutTexture[i][context]; DX11DepthStencil depth = null; bool viewportpop = this.FInViewPort.IsConnected; if (this.FInDepthBuffer[0]) { depth = this.FOutDepthTexture[i][context]; } if (depth != null && this.FInClearDepth[i]) { context.CurrentDeviceContext.ClearDepthStencilView(depth.DSV, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); } if (this.FInClear[i]) { context.CurrentDeviceContext.ClearRenderTargetView(target.RTV, this.FInBgColor[i]); } if (depth != null) { context.RenderTargetStack.Push(depth, false, target); } else { context.RenderTargetStack.Push(target); } if (this.FInLayer.IsConnected) { settings.ViewportIndex = i; settings.ViewportCount = sliceCount; settings.ApplyTransforms(this.FInView[i], this.FInProjection[i], this.FInAspect[i], this.FInCrop[i]); settings.RenderWidth = target.Width; settings.RenderHeight = target.Height; settings.RenderDepth = 1; settings.BackBuffer = null; settings.CustomSemantics.Clear(); settings.ResourceSemantics.Clear(); if (viewportpop) { float cw = this.FInSize[i].X; float ch = this.FInSize[i].Y; context.RenderTargetStack.PushViewport(this.FInViewPort[i].Normalize(cw, ch)); } for (int j = 0; j < this.FInLayer.SliceCount; j++) { try { this.FInLayer[j][context].Render(context, settings); } catch (Exception ex) { Console.WriteLine(ex.Message); } } if (viewportpop) { context.RenderTargetStack.Pop(); } } context.RenderTargetStack.Pop(); if (this.FInMips[i]) { context.CurrentDeviceContext.GenerateMips(this.FOutTexture[i][context].SRV); } } if (this.EndQuery != null) { this.EndQuery(context); } this.rendereddevices.Add(context); } }
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); }