protected override Resource GetStagingTexture(LayerMipmapSlice lm) { Debug.Assert(IO.SupportedFormats.Contains(Format) || Format == Format.R8_UInt); Debug.Assert(lm.Layer == 0); Debug.Assert(lm.IsIn(LayerMipmap)); var mipDim = Size.GetMip(lm.Mipmap); var desc = new Texture3DDescription { Width = mipDim.Width, Height = mipDim.Height, Depth = mipDim.Depth, Format = Format, MipLevels = 1, BindFlags = BindFlags.None, CpuAccessFlags = CpuAccessFlags.Read, OptionFlags = ResourceOptionFlags.None, Usage = ResourceUsage.Staging }; // create staging texture var staging = new SharpDX.Direct3D11.Texture3D(Device.Get().Handle, desc); // copy data to staging texture Device.Get().CopySubresource(handle, staging, GetSubresourceIndex(lm), 0, mipDim); return(staging); }
private void RenderRedToRgba(ITexture src, ITexture dst, LayerMipmapSlice lm) { Debug.Assert(src.HasSameDimensions(dst)); Debug.Assert(src.Format == Format.R32_Float); Debug.Assert(dst.Format == Format.R32G32B32A32_Float); redToRgbaTransform.Run(src, dst, lm, models.SharedModel.Upload); }
protected override SharpDX.Direct3D11.Resource GetStagingTexture(LayerMipmapSlice lm) { Debug.Assert(IO.SupportedFormats.Contains(Format)); var newSize = Size.GetMip(lm.Mipmap); var desc = new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.None, CpuAccessFlags = CpuAccessFlags.Read, Format = Format, Height = newSize.Height, Width = newSize.Width, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Staging }; // create staging texture var staging = new Texture2D(Device.Get().Handle, desc); // copy data to staging resource Device.Get().CopySubresource(handle, staging, GetSubresourceIndex(lm), 0, newSize ); return(staging); }
/// <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 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)); }
private void RenderContrast(ImagesCorrelationStats src, ITexture dst, LayerMipmapSlice lm) { contrastShader.Run(new [] { src.Image1.Variance, src.Image2.Variance }, dst, lm, models.SharedModel.Upload); }
private void RenderLuminance(ImagesCorrelationStats src, ITexture dst, LayerMipmapSlice lm) { luminanceShader.Run(new [] { src.Image1.Expected, src.Image2.Expected }, dst, lm, models.SharedModel.Upload); }
private void BindTextureParameters(ImagesModel image, LayerMipmapSlice lm) { var texSlot = TextureBindingStart; foreach (var texParam in parent.TextureParameters) { Device.Get().Compute.SetShaderResource(texSlot++, image.Images[texParam.Source].Image.GetSrView(lm)); } }
public void CopyPixels(LayerMipmapSlice lm, IntPtr destination, uint size) { // create staging texture using (var staging = GetStagingTexture(lm)) { // obtain data from staging resource Device.Get().GetData(staging, Format, 0, Size.GetMip(lm.Mipmap), destination, size); } }
private void RenderStructure(ImagesCorrelationStats src, ITexture dst, LayerMipmapSlice lm) { structureShader.Run(new [] { src.Image1.Variance, src.Image2.Variance, src.Correlation }, dst, lm, models.SharedModel.Upload); }
public Color[] GetPixelColors(LayerMipmapSlice lm) { // create staging texture using (var staging = GetStagingTexture(lm)) { // obtain data from staging resource return(Device.Get().GetColorData(staging, Format, 0, Size.GetMip(lm.Mipmap))); } }
public void Run(ITexture orgTex, ITexture dstTex, ITexture tmpTex, LayerMipmapSlice lm, UploadBuffer uploadBuffer) { Debug.Assert(dstTex.Format == Format.R8_UInt); Debug.Assert(tmpTex.Format == Format.R8_UInt); var size = orgTex.Size.GetMip(lm.Mipmap); var dev = Device.Get(); // remember for debugging var originalDst = dstTex; initTexShader.Run(orgTex, dstTex, lm, uploadBuffer); initTexShader.Run(orgTex, tmpTex, lm, uploadBuffer); dev.Compute.Set(compute.Compute); ImageFramework.DirectX.Query.SyncQuery syncQuery = new ImageFramework.DirectX.Query.SyncQuery(); //var watch = new Stopwatch(); //watch.Start(); for (int i = 0; i < 127; i++) { BindAndSwapTextures(ref dstTex, ref tmpTex, lm); Dispatch(new Int3(1, 0, 0), i, size, uploadBuffer); BindAndSwapTextures(ref dstTex, ref tmpTex, lm); Dispatch(new Int3(0, 1, 0), i, size, uploadBuffer); BindAndSwapTextures(ref dstTex, ref tmpTex, lm); Dispatch(new Int3(0, 0, 1), i, size, uploadBuffer); #if DEBUG if (i % 8 == 0) { syncQuery.Set(); syncQuery.WaitForGpu(); Console.WriteLine("Iteration: " + i); } #endif } /*syncQuery.Set(); * syncQuery.WaitForGpu(); * watch.Stop(); * * Console.WriteLine($"Time: {watch.ElapsedMilliseconds}ms"); */ // unbind dev.Compute.SetShaderResource(0, null); dev.Compute.SetUnorderedAccessView(0, null); dev.Compute.Set(null); Debug.Assert(ReferenceEquals(originalDst, tmpTex)); endShader.Run(dstTex, tmpTex, lm, uploadBuffer); syncQuery?.Dispose(); }
public override void Render(LayerMipmapSlice lm, Size3 size) { Debug.Assert(HasWork); UpdateData(lm.Mipmap); Shader.Bind(new VertexBufferBinding(positionBuffer.Handle, 2 * sizeof(float), 0)); Shader.Draw(Boxes, cbuffer, lm.Mipmap, size.XY); Shader.Unbind(); }
public unsafe byte[] GetBytes(LayerMipmapSlice lm, uint size) { byte[] res = new byte[size]; fixed(byte *ptr = res) { CopyPixels(lm, new IntPtr(ptr), size); } return(res); }
/// <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 MipInfo GetMipmap(LayerMipmapSlice lm) { var res = new MipInfo(); Dll.image_info_mipmap(Resource.Id, lm.Mipmap, out res.Size.X, out res.Size.Y, out res.Size.Z); #if DEBUG var expected = Size.GetMip(lm.Mipmap); Debug.Assert(expected.Width == res.Size.Width); Debug.Assert(expected.Height == res.Size.Height); Debug.Assert(expected.Depth == res.Size.Depth); #endif res.Bytes = Dll.image_get_mipmap(Resource.Id, lm.Layer, lm.Mipmap, out res.ByteSize); return(res); }
/// <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 MipInfo GetMipmap(LayerMipmapSlice lm) { // calc offset uint mipOffset = 0; // offset for previous layers for (int i = 0; i < lm.Mipmap; ++i) { // add mipmap size * layers mipOffset += (uint)Size.GetMip(i).Product *Format.PixelSize *(uint)LayerMipmap.Layers; } // offset from current layer var res = new MipInfo(); res.Size = Size.GetMip(lm.Mipmap); res.ByteSize = (uint)res.Size.Product * Format.PixelSize; mipOffset += res.ByteSize * (uint)lm.Layer; res.Bytes = ptr + (int)mipOffset; return(res); }
/// <summary> /// copies a single mip from one layer of a texture to another layer of a texture. The formats don't have to match /// </summary> /// <param name="src">source texture</param> /// <param name="dst">destination texture</param> public void CopyLayer(ITexture src, LayerMipmapSlice srcLm, ITexture dst, LayerMipmapSlice dstLm) { Debug.Assert(src.Size == dst.Size); var dev = DirectX.Device.Get(); quad.Bind(src.Is3D); if (src.Is3D) { dev.Pixel.Set(convert3D.Pixel); } else { dev.Pixel.Set(convert2D.Pixel); } dev.Pixel.SetShaderResource(0, src.View); cbuffer.SetData(new LayerLevelOffsetData { Layer = srcLm.Layer, Level = srcLm.Mipmap, Xoffset = 0, Yoffset = 0, Multiplier = 1.0f, UseOverlay = 0, Scale = 1 }); var dim = dst.Size.GetMip(dstLm.Mipmap); dev.Pixel.SetConstantBuffer(0, cbuffer.Handle); dev.OutputMerger.SetRenderTargets(dst.GetRtView(dstLm)); dev.SetViewScissors(dim.Width, dim.Height); dev.DrawFullscreenTriangle(dim.Depth); // remove bindings dev.Pixel.SetShaderResource(0, null); dev.OutputMerger.SetRenderTargets((RenderTargetView)null); quad.Unbind(); }
private void RenderImagesCorrelation(ITexture src1, ITexture src2, ImagesCorrelationStats dst, LayerMipmapSlice lm) { // calc expected value and variance RenderImageVariance(src1, dst.Image1, lm); RenderImageVariance(src2, dst.Image2, lm); // calc correlation coefficient var lumaMult = dst.Cache.GetTexture(); multiplyShader.Run(new [] { dst.Image1.Luma, dst.Image2.Luma }, lumaMult, lm, models.SharedModel.Upload); // blur result var lumaBlur = dst.Cache.GetTexture(); gaussShader.Run(lumaMult, lumaBlur, lm, models.SharedModel.Upload, dst.Cache); // calc correlation with blurred(luma1*luma2) - mu1*mu2 subtractProductShader.Run(new [] { lumaBlur, dst.Image1.Expected, dst.Image2.Expected }, dst.Correlation, lm, models.SharedModel.Upload); dst.Cache.StoreTexture(lumaMult); dst.Cache.StoreTexture(lumaBlur); }
public void Run(ITexture[] sources, ITexture dst, LayerMipmapSlice lm, UploadBuffer upload) { Debug.Assert(sources.Length == inputs.Length); foreach (var src in sources) { Debug.Assert(src.HasSameDimensions(dst)); } var size = sources[0].Size.GetMip(lm.SingleMipmap); upload.SetData(new BufferData { Layer = lm.SingleLayer, Size = size }); var dev = Device.Get(); var builder = sources[0].Is3D ? ShaderBuilder.Builder3D : ShaderBuilder.Builder2D; dev.Compute.Set(sources[0].Is3D ? Shader3D.Compute : Shader.Compute); dev.Compute.SetConstantBuffer(0, upload.Handle); for (var i = 0; i < sources.Length; i++) { var src = sources[i]; dev.Compute.SetShaderResource(i, src.GetSrView(lm)); } dev.Compute.SetUnorderedAccessView(0, dst.GetUaView(lm.SingleMipmap)); 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 < sources.Length; i++) { dev.Compute.SetShaderResource(i, null); } dev.Compute.SetUnorderedAccessView(0, null); }
/// <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>()); }
private void RenderImageVariance(ITexture src, ImageVarianceStats dst, LayerMipmapSlice lm) { // luma values lumaTransformShader.Run(src, dst.Luma, lm, models.SharedModel.Upload); // expected value gaussShader.Run(dst.Luma, dst.Expected, lm, models.SharedModel.Upload, dst.Cache); // calculate luma squared var lumaSq = dst.Cache.GetTexture(); multiplyShader.Run(new [] { dst.Luma, dst.Luma }, lumaSq, lm, models.SharedModel.Upload); // blur luma squared var lumaBlur = dst.Cache.GetTexture(); gaussShader.Run(lumaSq, lumaBlur, lm, models.SharedModel.Upload, dst.Cache); // calc variance with: blurred(luma^2) - mu^2 subtractProductShader.Run(new [] { lumaBlur, dst.Expected, dst.Expected }, dst.Variance, lm, models.SharedModel.Upload); dst.Cache.StoreTexture(lumaSq); dst.Cache.StoreTexture(lumaBlur); }
protected abstract Resource GetStagingTexture(LayerMipmapSlice lm);
protected int GetSubresourceIndex(LayerMipmapSlice lm) { Debug.Assert(lm.IsIn(LayerMipmap)); return(lm.Layer * LayerMipmap.Mipmaps + lm.Mipmap); }
public RenderTargetView GetRtView(LayerMipmapSlice lm) { Debug.Assert(rtViews != null); return(rtViews[GetSubresourceIndex(lm)]); }
public ShaderResourceView GetSrView(LayerMipmapSlice lm) { return(views[GetSubresourceIndex(lm)]); }
private void RenderSSIM(ImagesCorrelationStats src, ITexture dst, LayerMipmapSlice lm) { ssimShader2.Run(new [] { src.Image1.Expected, src.Image2.Expected, src.Image1.Variance, src.Image2.Variance, src.Correlation }, dst, lm, models.SharedModel.Upload); }
public void Run(ITexture src, ITexture dst, LayerMipmapSlice lm, UploadBuffer upload) { Run(new[] { src }, dst, lm, upload); }
/// <inheritdoc cref="PixelValueShader.Run"/> public Color GetPixelValue(ITexture image, Size3 coord, LayerMipmapSlice lm, int radius = 0) { return(PixelValueShader.Run(image, coord, lm, radius)); }