public override void Draw(int id, ITexture texture) { if (texture == null) { return; } base.Draw(id, texture); var dev = Device.Get(); dev.OutputMerger.BlendState = models.ViewData.AlphaDarkenState; if (models.Display.LinearInterpolation) { shader.Run(models.Display.ClientAspectRatio, GetWorldToImage(), CalcFarplane(), texture.GetSrView(models.Display.ActiveLayerMipmap), helpTextures[id].GetSrView(models.Display.ActiveMipmap)); } else { marchingShader.Run(models.Display.ClientAspectRatio, GetWorldToImage(), CalcFarplane(), displayEx.FlatShading, texture.GetSrView(models.Display.ActiveLayerMipmap), helpTextures[id].GetSrView(models.Display.ActiveMipmap)); } dev.OutputMerger.BlendState = models.ViewData.DefaultBlendState; }
public override void Draw(ITexture texture) { if (texture == null) { return; } base.Draw(texture); var dev = Device.Get(); dev.OutputMerger.BlendState = data.AlphaDarkenState; if (models.Display.LinearInterpolation) { shader.Run(data.Buffer, models.Display.ClientAspectRatio, GetWorldToImage(), models.Display.Multiplier, CalcFarplane(), models.Display.DisplayNegative, texture.GetSrView(models.Display.ActiveLayer, models.Display.ActiveMipmap)); } else { marchingShader.Run(data.Buffer, models.Display.ClientAspectRatio, GetWorldToImage(), models.Display.Multiplier, CalcFarplane(), models.Display.DisplayNegative, displayEx.FlatShading, texture.GetSrView(models.Display.ActiveLayer, models.Display.ActiveMipmap)); } dev.OutputMerger.BlendState = data.DefaultBlendState; }
private void swapTextures(ref bool readHelpTex, ITexture helpTex, ITexture pong, LayerMipmapSlice lm) { var dev = Device.Get(); if (readHelpTex) { readHelpTex = false; dev.Compute.SetShaderResource(0, null); dev.Compute.SetUnorderedAccessView(0, null); dev.Compute.SetShaderResource(0, pong.GetSrView(lm)); dev.Compute.SetUnorderedAccessView(0, helpTex.GetUaView(lm.Mipmap)); } else { readHelpTex = true; dev.Compute.SetShaderResource(0, null); dev.Compute.SetUnorderedAccessView(0, null); dev.Compute.SetShaderResource(0, helpTex.GetSrView(lm)); dev.Compute.SetUnorderedAccessView(0, pong.GetUaView(lm.Mipmap)); } }
// executes a 3x3 gauss kernel on the given texture mipmap public void Run(ITexture texSrc, ITexture texDst, int mipmap, bool hasAlpha, UploadBuffer upload) { Debug.Assert(texSrc.NumLayers == texDst.NumLayers); Debug.Assert(texSrc.NumMipmaps == texDst.NumMipmaps); Debug.Assert(texSrc.Size == texDst.Size); var dev = Device.Get(); dev.Compute.Set(texSrc.Is3D ? Shader3D.Compute : Shader.Compute); var builder = texSrc.Is3D ? ShaderBuilder.Builder3D : ShaderBuilder.Builder2D; var data = new BufferData { Size = texSrc.Size.GetMip(mipmap), HasAlpha = hasAlpha?1:0, }; foreach (var lm in texSrc.LayerMipmap.LayersOfMipmap(mipmap)) { data.Layer = lm.Layer; upload.SetData(data); dev.Compute.SetConstantBuffer(0, upload.Handle); dev.Compute.SetShaderResource(0, texSrc.GetSrView(lm)); dev.Compute.SetUnorderedAccessView(0, texDst.GetUaView(mipmap)); dev.Dispatch( Utility.Utility.DivideRoundUp(data.Size.Width, builder.LocalSizeX), Utility.Utility.DivideRoundUp(data.Size.Height, builder.LocalSizeY), Utility.Utility.DivideRoundUp(data.Size.Depth, builder.LocalSizeZ) ); } dev.Compute.SetShaderResource(0, null); dev.Compute.SetUnorderedAccessView(0, null); }
/// <summary> /// copies the values of the +4th mipmap into the specified mipmap /// </summary> /// <param name="tex"></param> /// <param name="lm">dst layer/mipmap</param> /// <param name="upload"></param> public void RunCopy(ITexture tex, LayerMipmapSlice lm, UploadBuffer upload) { var size = tex.Size.GetMip(lm.SingleMipmap); var nMipmaps = tex.NumMipmaps - lm.Mipmap; if (nMipmaps == 1) { return; // already finished } upload.SetData(new BufferData { Layer = lm.SingleLayer, Size = size }); var dev = Device.Get(); var builder = tex.Is3D ? ShaderBuilder.Builder3D : ShaderBuilder.Builder2D; dev.Compute.Set(tex.Is3D ? CopyShader3D.Compute : CopyShader.Compute); dev.Compute.SetConstantBuffer(0, upload.Handle); dev.Compute.SetSampler(0, sampler); dev.Compute.SetUnorderedAccessView(0, tex.GetUaView(lm.Mipmap)); dev.Compute.SetShaderResource(0, tex.GetSrView(lm.AddMipmap(Math.Min(4, nMipmaps - 1)))); dev.Dispatch( Utility.Utility.DivideRoundUp(size.X, builder.LocalSizeX), Utility.Utility.DivideRoundUp(size.Y, builder.LocalSizeY), Utility.Utility.DivideRoundUp(size.Z, builder.LocalSizeZ) ); dev.Compute.SetShaderResource(0, null); dev.Compute.SetUnorderedAccessView(0, null); }
public void Run(ITexture src, ITexture guide, ITexture dst, int srcMipmap, int dstMipmap, bool hasAlpha, UploadBuffer upload) { Debug.Assert(guide.Size == dst.Size); Debug.Assert(guide.NumMipmaps >= dstMipmap); Debug.Assert(dst.NumMipmaps >= dstMipmap); Debug.Assert(guide.NumLayers == dst.NumLayers); Debug.Assert(src.NumLayers == dst.NumLayers); var bufferData = new BufferData { SrcSize = src.Size.GetMip(srcMipmap), DstSize = dst.Size.GetMip(dstMipmap), HasAlpha = hasAlpha?1:0, }; bufferData.FilterSizeFloatX = bufferData.SrcSize.X / (float)bufferData.DstSize.X; bufferData.FilterSizeFloatY = bufferData.SrcSize.Y / (float)bufferData.DstSize.Y; bufferData.FilterSizeFloatZ = bufferData.SrcSize.Z / (float)bufferData.DstSize.Z; // select shader and builder var builder = src.Is3D ? ShaderBuilder.Builder3D : ShaderBuilder.Builder2D; bool isFastShader = (bufferData.SrcSize.X % bufferData.DstSize.X == 0) && (bufferData.SrcSize.Y % bufferData.DstSize.Y == 0) && (bufferData.SrcSize.Z % bufferData.DstSize.Z == 0); DirectX.Shader shader; if (isFastShader) { shader = src.Is3D ? FastShader3D : FastShader; } else { shader = src.Is3D ? SlowShader3D : SlowShader; } var dev = Device.Get(); dev.Compute.Set(shader.Compute); for (int layer = 0; layer < src.NumLayers; ++layer) { bufferData.Layer = layer; upload.SetData(bufferData); dev.Compute.SetConstantBuffer(0, upload.Handle); dev.Compute.SetShaderResource(0, src.GetSrView(new LayerMipmapSlice(layer, srcMipmap))); dev.Compute.SetShaderResource(1, guide.GetSrView(new LayerMipmapSlice(layer, dstMipmap))); dev.Compute.SetUnorderedAccessView(0, dst.GetUaView(dstMipmap)); dev.Dispatch( Utility.Utility.DivideRoundUp(bufferData.DstSize.X, builder.LocalSizeX / 2), Utility.Utility.DivideRoundUp(bufferData.DstSize.Y, builder.LocalSizeY / 2), Utility.Utility.DivideRoundUp(bufferData.DstSize.Z, Math.Max(builder.LocalSizeZ / 2, 1)) ); } dev.Compute.SetShaderResource(0, null); dev.Compute.SetShaderResource(1, null); dev.Compute.SetUnorderedAccessView(0, null); }
public override void Draw(ITexture texture) { if (texture == null) { return; } DrawLayer(Matrix.Identity, models.Display.ActiveLayer, texture.GetSrView(models.Display.ActiveLayer, models.Display.ActiveMipmap)); }
/// <summary> /// adds pixels to the image edges /// </summary> /// <param name="src">source image</param> /// <param name="leftPad">padding on the left/top/front side</param> /// <param name="rightPad">padding on the right/bot/back side</param> /// <param name="fill">padding fill mode</param> /// <param name="scaling">used for regenerating mipmaps (may be null if no mipmaps need to be generated)</param> /// <param name="shared"></param> /// <param name="keepMipmaps">if set to false, no mipmaps will be generated</param> /// <returns>same as source with added padding (amount of mipmaps might change, format remains)</returns> public ITexture Run(ITexture src, Size3 leftPad, Size3 rightPad, FillMode fill, ScalingModel scaling, SharedModel shared, bool keepMipmaps = true) { Size3 dstSize = leftPad + rightPad + src.Size; int nMipmaps = src.NumMipmaps > 1 ? dstSize.MaxMipLevels : 1; if (!keepMipmaps) { nMipmaps = 1; } var dst = src.Create(new LayerMipmapCount(src.NumLayers, nMipmaps), dstSize, src.Format, src.HasUaViews, true); var dev = DirectX.Device.Get(); shared.Upload.SetData(new BufferData { Depth = dstSize.Depth, Offset = new Float3(leftPad) / new Float3(dstSize), Scale = new Float3(dstSize) / new Float3(src.Size), }); shared.QuadShader.Bind(src.Is3D); if (src.Is3D) { dev.Pixel.Set(shader3D.Pixel); } else { dev.Pixel.Set(shader.Pixel); } dev.Pixel.SetSampler(0, sampler[(int)fill]); dev.Pixel.SetConstantBuffer(0, shared.Upload.Handle); foreach (var lm in src.LayerMipmap.RangeOf(LayerMipmapRange.MostDetailed)) { dev.OutputMerger.SetRenderTargets(dst.GetRtView(lm)); dev.SetViewScissors(dstSize.Width, dstSize.Height); dev.Pixel.SetShaderResource(0, src.GetSrView(lm)); dev.DrawFullscreenTriangle(dstSize.Depth); } // remove bindings shared.QuadShader.Unbind(); dev.Pixel.Set(null); dev.OutputMerger.SetRenderTargets((RenderTargetView)null); dev.Pixel.SetShaderResource(0, null); if (dst.NumMipmaps > 1) { Debug.Assert(scaling != null); scaling.WriteMipmaps(dst); } return(dst); }
/// <summary> /// puts statistic data of all pixels into the buffer /// </summary> /// <param name="lm">range with single mipmap</param> /// <param name="offset">offset in each direction</param> /// <param name="source"></param> /// <param name="buffer"></param> internal void CopyToBuffer(ITexture source, GpuBuffer buffer, LayerMipmapRange lm, Size3 offset) { Debug.Assert(lm.IsSingleMipmap); // copy pixels from the source image into a texture from the texture cache var dev = Device.Get(); if (source.Is3D) { dev.Compute.Set(shader3d.Compute); } else { dev.Compute.Set(shader.Compute); } var dim = source.Size.GetMip(lm.Mipmap); AdjustDim(ref dim, ref offset, source.Is3D); var numLayers = source.LayerMipmap.Layers; var curData = new BufferData { Level = lm.Mipmap, TrueBool = true, Offset = offset, Size = dim }; if (lm.AllLayer) { dev.Compute.SetShaderResource(0, source.View); } else { // single layer dev.Compute.SetShaderResource(0, source.GetSrView(lm.Single)); curData.Level = 0; // view with single level numLayers = 1; } cbuffer.SetData(curData); // buffer big enough? Debug.Assert(buffer.ElementCount >= dim.Product * numLayers); dev.Compute.SetUnorderedAccessView(0, buffer.View); dev.Compute.SetConstantBuffer(0, cbuffer.Handle); dev.Dispatch(Utility.Utility.DivideRoundUp(dim.Width, LocalSizeX), Utility.Utility.DivideRoundUp(dim.Height, LocalSizeY), Math.Max(dim.Depth, numLayers)); dev.Compute.SetUnorderedAccessView(0, null); dev.Compute.SetShaderResource(0, null); }
/// <summary> /// weights the values of the given mipmap with values from higher mipmaps (according to ms-ssim) /// </summary> /// <param name="tex"></param> /// <param name="lm">dst layer/mipmap</param> /// <param name="upload"></param> public void RunWeighted(ITexture tex, LayerMipmapSlice lm, UploadBuffer upload) { var size = tex.Size.GetMip(lm.SingleMipmap); var nMipmaps = tex.NumMipmaps - lm.Mipmap; if (nMipmaps == 1) { return; // already finished } upload.SetData(new BufferData { Layer = lm.SingleLayer, Size = size, InvWeightSum = GetInvWeightSum(nMipmaps), NumMipmaps = nMipmaps }); var dev = Device.Get(); var builder = tex.Is3D ? ShaderBuilder.Builder3D : ShaderBuilder.Builder2D; dev.Compute.Set(tex.Is3D ? Shader3D.Compute : Shader.Compute); dev.Compute.SetConstantBuffer(0, upload.Handle); dev.Compute.SetSampler(0, sampler); dev.Compute.SetUnorderedAccessView(0, tex.GetUaView(lm.Mipmap)); dev.Compute.SetShaderResource(0, nMipmaps >= 2 ? tex.GetSrView(lm.AddMipmap(1)) : null); dev.Compute.SetShaderResource(1, nMipmaps >= 3 ? tex.GetSrView(lm.AddMipmap(2)) : null); dev.Compute.SetShaderResource(2, nMipmaps >= 4 ? tex.GetSrView(lm.AddMipmap(3)) : null); dev.Compute.SetShaderResource(3, nMipmaps >= 5 ? tex.GetSrView(lm.AddMipmap(4)) : null); dev.Dispatch( Utility.Utility.DivideRoundUp(size.X, builder.LocalSizeX), Utility.Utility.DivideRoundUp(size.Y, builder.LocalSizeY), Utility.Utility.DivideRoundUp(size.Z, builder.LocalSizeZ) ); for (var i = 0; i < 4; i++) { dev.Compute.SetShaderResource(i, null); } dev.Compute.SetUnorderedAccessView(0, null); }
public override void Draw(ITexture texture) { if (texture == null) { return; } DrawLayer(Matrix.Identity, models.Display.ActiveLayer, texture.GetSrView(models.Display.ActiveLayer, models.Display.ActiveMipmap), displayEx.FreeAxis1, displayEx.FreeAxis2, displayEx.FixedAxisSlice); }
public void Run(ITexture src, ITexture dst, int srcMipmap, int dstMipmap, bool hasAlpha, UploadBuffer upload, ITextureCache cache) { Debug.Assert(cache.IsCompatibleWith(src)); Debug.Assert(src.NumLayers == dst.NumLayers); Debug.Assert(dstMipmap < dst.NumMipmaps && dstMipmap >= 0); Debug.Assert(srcMipmap < src.NumMipmaps && dstMipmap >= 0); var dstSize = dst.Size.GetMip(dstMipmap); var srcSize = src.Size.GetMip(srcMipmap); var cbuffer = new BufferData { HasAlpha = hasAlpha ? 1 : 0 }; var tmpTex1 = cache.GetTexture(); ITexture tmpTex2 = null; if (src.Is3D) { tmpTex2 = cache.GetTexture(); } foreach (var srcLm in src.LayerMipmap.LayersOfMipmap(srcMipmap)) { cbuffer.Layer = srcLm.Layer; cbuffer.DstSize = srcSize; cbuffer.DstSize.X = dstSize.X; ExecuteDimension(ref cbuffer, upload, src.Is3D, 0, srcSize, src.GetSrView(srcLm), tmpTex1.GetUaView(srcMipmap)); // var tst = tmpTex1.GetPixelColors(layer, 0); cbuffer.DstSize.Y = dstSize.Y; if (src.Is3D) { ExecuteDimension(ref cbuffer, upload, src.Is3D, 1, srcSize, tmpTex1.GetSrView(srcLm), tmpTex2.GetUaView(srcMipmap)); cbuffer.DstSize.Z = dstSize.Z; ExecuteDimension(ref cbuffer, upload, src.Is3D, 2, srcSize, tmpTex2.GetSrView(srcLm), dst.GetUaView(dstMipmap)); } else { ExecuteDimension(ref cbuffer, upload, src.Is3D, 1, srcSize, tmpTex1.GetSrView(srcLm), dst.GetUaView(dstMipmap)); } } cache.StoreTexture(tmpTex1); if (tmpTex2 != null) { cache.StoreTexture(tmpTex2); } }
public override void Draw(int id, ITexture texture) { if (texture == null) { return; } base.Draw(id, texture); var dev = Device.Get(); dev.OutputMerger.BlendState = models.ViewData.AlphaDarkenState; if (models.Display.LinearInterpolation) { smooth.Run(GetWorldToImage(), texture.GetSrView(models.Display.ActiveLayerMipmap), helpTextures[id].GetView(models.Display.ActiveMipmap)); } else { cube.Run(GetWorldToImage(), displayEx.Shading, texture.GetSrView(models.Display.ActiveLayerMipmap), helpTextures[id].GetView(models.Display.ActiveMipmap)); } dev.OutputMerger.BlendState = models.ViewData.DefaultBlendState; using (var draw = models.Window.SwapChain.Draw.Begin()) { using (var t = draw.SetCanonical(new Float2(20.0f), new Float2(150.0f))) { var rot = GetRotation(); Sphere3DOverlay.Draw(draw, new Float3(rot.M11, rot.M21, rot.M31), new Float3(rot.M12, rot.M22, rot.M32), new Float3(rot.M13, rot.M23, rot.M33), models.Settings.FlipYAxis); } } }
public override void Draw(int id, ITexture texture) { if (texture == null) { return; } var mip = models.Display.ActiveMipmap; // -x var lm = new LayerMipmapSlice(1, mip); DrawLayer(Matrix.Translation(-2.0f, 0.0f, 0.0f), texture.GetSrView(lm), models.Overlay.Overlay?.GetSrView(lm)); // -y lm.Layer = 3; DrawLayer(Matrix.Translation(0.0f, -2.0f, 0.0f), texture.GetSrView(lm), models.Overlay.Overlay?.GetSrView(lm)); // +y lm.Layer = 2; DrawLayer(Matrix.Translation(0.0f, 2.0f, 0.0f), texture.GetSrView(lm), models.Overlay.Overlay?.GetSrView(lm)); // +z lm.Layer = 4; DrawLayer(Matrix.Translation(0.0f, 0.0f, 0.0f), texture.GetSrView(lm), models.Overlay.Overlay?.GetSrView(lm)); // +x lm.Layer = 0; DrawLayer(Matrix.Translation(2.0f, 0.0f, 0.0f), texture.GetSrView(lm), models.Overlay.Overlay?.GetSrView(lm)); // -z lm.Layer = 5; DrawLayer(Matrix.Translation(4.0f, 0.0f, 0.0f), texture.GetSrView(lm), models.Overlay.Overlay?.GetSrView(lm)); }
/// <summary> /// binds dstTex as source and tmpTex as destination and then swaps the references. /// => after rendering, dst tex will be the texture with the result /// </summary> /// <param name="dstTex"></param> /// <param name="tmpTex"></param> /// <param name="lm"></param> private void BindAndSwapTextures(ref ITexture dstTex, ref ITexture tmpTex, LayerMipmapSlice lm) { var dev = Device.Get(); dev.Compute.SetShaderResource(0, null); dev.Compute.SetUnorderedAccessView(0, null); dev.Compute.SetShaderResource(0, dstTex.GetSrView(lm)); dev.Compute.SetUnorderedAccessView(0, tmpTex.GetUaView(lm.Mipmap)); var tmp = tmpTex; tmpTex = dstTex; dstTex = tmp; }
public override void UpdateImage(int id, ITexture texture) { base.UpdateImage(id, texture); helpTextures[id]?.Dispose(); if (texture is null) { return; } SpaceSkippingTexture3D tex = new SpaceSkippingTexture3D(texture.Size, texture.NumMipmaps); helpTextures[id] = tex; emptySpaceSkippingShader.Execute(texture.GetSrView(LayerMipmapSlice.Mip0), helpTextures[id], texture.Size); }
/// <summary> /// puts statistic data of all pixels into the buffer /// </summary> internal void CopyToBuffer(ITexture source, GpuBuffer buffer, int layer = -1, int mipmap = 0) { // copy pixels from the source image into a texture from the texture cache var dev = Device.Get(); if (source.Is3D) { dev.Compute.Set(shader3d.Compute); } else { dev.Compute.Set(shader.Compute); } var dim = source.Size.GetMip(mipmap); var numLayers = source.NumLayers; var curData = new StatisticsData { Level = mipmap, TrueBool = true }; if (layer == -1) { dev.Compute.SetShaderResource(0, source.View); } else { // single layer dev.Compute.SetShaderResource(0, source.GetSrView(layer, mipmap)); curData.Level = 0; // view with single level numLayers = 1; } cbuffer.SetData(curData); // buffer big enough? Debug.Assert(buffer.ElementCount >= dim.Product * numLayers); dev.Compute.SetUnorderedAccessView(0, buffer.View); dev.Compute.SetConstantBuffer(0, cbuffer.Handle); dev.Dispatch(Utility.Utility.DivideRoundUp(dim.Width, LocalSizeX), Utility.Utility.DivideRoundUp(dim.Height, LocalSizeY), Math.Max(dim.Depth, numLayers)); dev.Compute.SetUnorderedAccessView(0, null); dev.Compute.SetShaderResource(0, null); }
public override void Draw(int id, ITexture texture) { if (texture == null) { return; } base.Draw(id, texture); var dev = Device.Get(); dev.OutputMerger.BlendState = models.ViewData.AlphaBlendState; shader.Run(GetTransform(), CalcFarplane(), texture.GetSrView(models.Display.ActiveLayerMipmap), models.Overlay.Overlay?.GetSrView(models.Display.ActiveLayerMipmap)); dev.OutputMerger.BlendState = models.ViewData.DefaultBlendState; }
public override void Draw(int id, ITexture texture) { if (texture == null) { return; } base.Draw(id, texture); var dev = Device.Get(); dev.OutputMerger.BlendState = models.ViewData.AlphaBlendState; var projection = Matrix.PerspectiveFovLH(1.57f, models.Window.ClientSize.Width / (float)models.Window.ClientSize.Height, 0.01f, 10000.0f); shader.Run(models.ViewData.Buffer, projection, GetModel(), models.Display.Multiplier, models.Display.DisplayNegative, texture.GetSrView(models.Display.ActiveLayerMipmap), models.ViewData.GetSampler(models.Display.LinearInterpolation), models.Images.Size.GetMip(models.Display.ActiveMipmap)); dev.OutputMerger.BlendState = models.ViewData.DefaultBlendState; }
/// <summary> /// returns pixel color at the given position /// </summary> /// <param name="image">source image</param> /// <param name="coord">x pixel coordinate</param> /// <param name="radius">summation radius (0 = only this pixel)</param> /// <returns></returns> public Color Run(ITexture image, Size3 coord, LayerMipmapSlice lm, int radius = 0) { var dim = image.Size.GetMip(lm.SingleMipmap); cbuffer.SetData(new PixelValueData { PixelX = coord.X, PixelY = coord.Y, PixelZ = coord.Z, SizeX = dim.Width, SizeY = dim.Height, SizeZ = dim.Depth, Radius = radius }); var dev = Device.Get(); if (image.Is3D) { dev.Compute.Set(shader3D.Compute); } else { dev.Compute.Set(shader2D.Compute); } dev.Compute.SetConstantBuffer(0, cbuffer.Handle); dev.Compute.SetShaderResource(0, image.GetSrView(lm)); dev.Compute.SetUnorderedAccessView(0, dstBuffer.View); dev.Dispatch(1, 1); // unbind textures dev.Compute.SetShaderResource(0, null); dev.Compute.SetUnorderedAccessView(0, null); // obtain data readBuffer.CopyFrom(dstBuffer, Marshal.SizeOf(typeof(Color))); return(readBuffer.GetData <Color>()); }
public override void Draw(ITexture texture) { if (texture == null) { return; } base.Draw(texture); var dev = Device.Get(); dev.OutputMerger.BlendState = data.AlphaBlendState; shader.Run(data.Buffer, GetTransform(), data.GetCrop(models, models.Display.ActiveLayer), models.Display.Multiplier, CalcFarplane(), models.Display.DisplayNegative, texture.GetSrView(models.Display.ActiveLayer, models.Display.ActiveMipmap), data.GetSampler(models.Display.LinearInterpolation) ); dev.OutputMerger.BlendState = data.DefaultBlendState; }
public override void Draw(ITexture texture) { if (texture == null) { return; } var mip = models.Display.ActiveMipmap; // -x DrawLayer(Matrix.Translation(-2.0f, 0.0f, 0.0f), 1, texture.GetSrView(1, mip)); // -y DrawLayer(Matrix.Translation(0.0f, -2.0f, 0.0f), 3, texture.GetSrView(3, mip)); // +y DrawLayer(Matrix.Translation(0.0f, 2.0f, 0.0f), 2, texture.GetSrView(2, mip)); // +z DrawLayer(Matrix.Translation(0.0f, 0.0f, 0.0f), 4, texture.GetSrView(4, mip)); // +x DrawLayer(Matrix.Translation(2.0f, 0.0f, 0.0f), 0, texture.GetSrView(0, mip)); // -z DrawLayer(Matrix.Translation(4.0f, 0.0f, 0.0f), 5, texture.GetSrView(5, mip)); }
/// <summary> /// executes on iteration of the filter (for all layers and mipmaps) /// </summary> /// <param name="image">original images (might be used for texture bindings)</param> /// <param name="src">source texture</param> /// <param name="dst">destination texture</param> /// <param name="cbuffer">buffer that stores some runtime information</param> /// <param name="iteration">current filter iteration. Should be 0 if not separable. Should be 0 or 1 if separable (x- and y-direction pass) or 2 for z-direction pass</param> /// <remarks>make sure to call UpdateParamBuffer() if parameters have changed after the last invocation</remarks> internal void Run(ImagesModel image, ITexture src, ITexture dst, UploadBuffer cbuffer, int iteration) { if (parent.IsSepa) { Debug.Assert(iteration == 0 || iteration == 1 || iteration == 2); } else { Debug.Assert(iteration == 0); } // compatible textures? Debug.Assert(src.Is3D == is3D); Debug.Assert(dst.Is3D == is3D); var dev = Device.Get(); dev.Compute.Set(shader.Compute); // filter parameters (constant) if (paramBuffer != null) { dev.Compute.SetConstantBuffer(1, paramBuffer.Handle); } dev.Compute.SetShaderResource(1, src.View); for (int curMipmap = 0; curMipmap < image.NumMipmaps; ++curMipmap) { // dst texture dev.Compute.SetUnorderedAccessView(0, dst.GetUaView(curMipmap)); var size = image.GetSize(curMipmap); for (int curLayer = 0; curLayer < image.NumLayers; ++curLayer) { // src textures dev.Compute.SetShaderResource(0, src.GetSrView(curLayer, curMipmap)); BindTextureParameters(image, curLayer, curMipmap); cbuffer.SetData(new LayerLevelFilter { Layer = curLayer, Level = curMipmap, FilterX = iteration == 0?1:0, FilterY = iteration == 1?1:0, FilterZ = iteration == 2?1:0 }); dev.Compute.SetConstantBuffer(0, cbuffer.Handle); dev.Dispatch( Utility.Utility.DivideRoundUp(size.Width, localSize), Utility.Utility.DivideRoundUp(size.Height, localSize), Utility.Utility.DivideRoundUp(size.Depth, localSize)); } } // remove texture bindings dev.Compute.SetUnorderedAccessView(0, null); dev.Compute.SetShaderResource(0, null); dev.Compute.SetShaderResource(1, null); }
public void Run(ITexture src, ITexture dst, ITexture tmpTex, LayerMipmapSlice lm, UploadBuffer upload) { var size = src.Size.GetMip(lm.Mipmap); var dev = Device.Get(); // debugging var originalDst = dst; initTexShader.Run(src, dst, lm, upload); initTexShader.Run(src, tmpTex, lm, upload); ImageFramework.DirectX.Query.SyncQuery syncQuery = new ImageFramework.DirectX.Query.SyncQuery(); //var watch = new Stopwatch(); //watch.Start(); for (int i = 0; i < 254; ++i) { // bind textures dev.Compute.SetShaderResource(0, dst.GetSrView(lm)); dev.Compute.SetUnorderedAccessView(0, tmpTex.GetUaView(lm.Mipmap)); dev.Compute.Set(compute.Compute); upload.SetData(new BufferData { Size = size, Iteration = i }); dev.Compute.SetConstantBuffer(0, upload.Handle); // execute dev.Dispatch( Utility.DivideRoundUp(size.X, workgroupSize.X), Utility.DivideRoundUp(size.Y, workgroupSize.Y), Utility.DivideRoundUp(size.Z, workgroupSize.Z) ); // unbind texture dev.Compute.SetShaderResource(0, null); dev.Compute.SetUnorderedAccessView(0, null); // swap textures var tmp = tmpTex; tmpTex = dst; dst = tmp; #if DEBUG if (i % 16 == 0) { syncQuery.Set(); syncQuery.WaitForGpu(); Console.WriteLine("Iteration: " + i); } #endif } /*syncQuery.Set(); * syncQuery.WaitForGpu(); * watch.Stop(); * * Console.WriteLine($"Time: {watch.ElapsedMilliseconds}ms"); */ dev.Compute.Set(null); Debug.Assert(ReferenceEquals(originalDst, dst)); syncQuery?.Dispose(); }
public void Run(ITexture src, ITexture dst, LayerMipmapSlice lm, UploadBuffer buffer, ITextureCache cache) { Debug.Assert(src.HasSameDimensions(dst)); Debug.Assert(cache.IsCompatibleWith(src)); Debug.Assert(lm.IsIn(src.LayerMipmap)); var srcSize = src.Size.GetMip(lm.Mipmap); var dev = Device.Get(); dev.Compute.Set(src.Is3D ? Shader3D.Compute : Shader.Compute); var builder = src.Is3D ? ShaderBuilder.Builder3D : ShaderBuilder.Builder2D; // execute x buffer.SetData(new BufferData { Size = srcSize, Direction = new Size3(1, 0, 0), Layer = lm.Layer }); dev.Compute.SetConstantBuffer(0, buffer.Handle); dev.Compute.SetShaderResource(0, src.GetSrView(lm)); var tmp1 = cache.GetTexture(); ITexture tmp2 = null; dev.Compute.SetUnorderedAccessView(0, tmp1.GetUaView(lm.Mipmap)); dev.Dispatch( Utility.Utility.DivideRoundUp(srcSize.Width, builder.LocalSizeX), Utility.Utility.DivideRoundUp(srcSize.Height, builder.LocalSizeY), Utility.Utility.DivideRoundUp(srcSize.Depth, builder.LocalSizeZ) ); UnbindResources(dev); // execute y buffer.SetData(new BufferData { Size = srcSize, Direction = new Size3(0, 1, 0), Layer = lm.Layer }); dev.Compute.SetConstantBuffer(0, buffer.Handle); dev.Compute.SetShaderResource(0, tmp1.GetSrView(lm)); if (src.Is3D) { tmp2 = cache.GetTexture(); dev.Compute.SetUnorderedAccessView(0, tmp2.GetUaView(lm.Mipmap)); dev.Dispatch( Utility.Utility.DivideRoundUp(srcSize.Width, builder.LocalSizeX), Utility.Utility.DivideRoundUp(srcSize.Height, builder.LocalSizeY), Utility.Utility.DivideRoundUp(srcSize.Depth, builder.LocalSizeZ) ); UnbindResources(dev); // execute z buffer.SetData(new BufferData { Size = srcSize, Direction = new Size3(0, 0, 1), Layer = lm.Layer }); dev.Compute.SetConstantBuffer(0, buffer.Handle); dev.Compute.SetShaderResource(0, tmp2.GetSrView(lm)); } // bind final target dev.Compute.SetUnorderedAccessView(0, dst.GetUaView(lm.Mipmap)); dev.Dispatch( Utility.Utility.DivideRoundUp(srcSize.Width, builder.LocalSizeX), Utility.Utility.DivideRoundUp(srcSize.Height, builder.LocalSizeY), Utility.Utility.DivideRoundUp(srcSize.Depth, builder.LocalSizeZ) ); UnbindResources(dev); cache.StoreTexture(tmp1); if (tmp2 != null) { cache.StoreTexture(tmp2); } }
/// <summary> /// creates a thumbnail for one image layer/mipmap /// </summary> /// <param name="size">maximum width/height of the thumbnail</param> /// <param name="texture">source texture</param> /// <param name="dstFormat">destination texture format</param> /// <param name="layer">source layer</param> /// <returns>texture with width, height smaller or equal to size. One layer and one mipmap</returns> public TextureArray2D CreateThumbnail(int size, ITexture texture, SharpDX.DXGI.Format dstFormat, int layer, ScalingModel scaling) { Debug.Assert(ImageFormat.IsSupported(dstFormat)); Debug.Assert(ImageFormat.IsSupported(texture.Format)); // determine dimensions of output texture var width = 0; var height = 0; if (texture.Size.Width > texture.Size.Height) { width = size; height = (texture.Size.Height * size) / texture.Size.Width; } else { height = size; width = (texture.Size.Width * size) / texture.Size.Height; } Debug.Assert(width <= size); Debug.Assert(height <= size); var res = new TextureArray2D(LayerMipmapCount.One, new Size3(width, height), dstFormat, false); // compute which mipmap has the closest fit var mipmap = 0; var curWidth = texture.Size.Width; while (curWidth >= width) { ++mipmap; curWidth /= 2; } // mipmap just jumped over the optimal size mipmap = Math.Max(0, mipmap - 1); var dev = Device.Get(); ITexture tmpTex = null; if (texture.NumMipmaps < mipmap + 1) { // generate new texture with mipmaps tmpTex = texture.CloneWithMipmaps(mipmap + 1); scaling.WriteMipmaps(tmpTex); dev.Pixel.SetShaderResource(0, tmpTex.GetSrView(new LayerMipmapSlice(layer, mipmap))); } else { dev.Pixel.SetShaderResource(0, texture.GetSrView(new LayerMipmapSlice(layer, mipmap))); } quad.Bind(false); if (texture.Is3D) { dev.Pixel.Set(convert3D.Pixel); } else { dev.Pixel.Set(convert2D.Pixel); } dev.Pixel.SetSampler(0, sampler); dev.OutputMerger.SetRenderTargets(res.GetRtView(LayerMipmapSlice.Mip0)); dev.SetViewScissors(width, height); dev.DrawFullscreenTriangle(1); // remove bindings dev.Pixel.SetShaderResource(0, null); dev.OutputMerger.SetRenderTargets((RenderTargetView)null); quad.Unbind(); tmpTex?.Dispose(); return(res); }