Beispiel #1
0
        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);
        }
Beispiel #2
0
 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);
 }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        /// <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));
        }
Beispiel #6
0
 private void RenderContrast(ImagesCorrelationStats src, ITexture dst, LayerMipmapSlice lm)
 {
     contrastShader.Run(new []
     {
         src.Image1.Variance,
         src.Image2.Variance
     }, dst, lm, models.SharedModel.Upload);
 }
Beispiel #7
0
 private void RenderLuminance(ImagesCorrelationStats src, ITexture dst, LayerMipmapSlice lm)
 {
     luminanceShader.Run(new []
     {
         src.Image1.Expected,
         src.Image2.Expected
     }, dst, lm, models.SharedModel.Upload);
 }
Beispiel #8
0
        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));
            }
        }
Beispiel #9
0
 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);
     }
 }
Beispiel #10
0
 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);
 }
Beispiel #11
0
 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)));
     }
 }
Beispiel #12
0
        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();
        }
Beispiel #13
0
        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();
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        /// <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;
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        /// <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);
        }
Beispiel #18
0
        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);
        }
Beispiel #19
0
        /// <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();
        }
Beispiel #20
0
        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);
        }
Beispiel #21
0
        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>());
        }
Beispiel #23
0
        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);
        }
Beispiel #24
0
 protected abstract Resource GetStagingTexture(LayerMipmapSlice lm);
Beispiel #25
0
        protected int GetSubresourceIndex(LayerMipmapSlice lm)
        {
            Debug.Assert(lm.IsIn(LayerMipmap));

            return(lm.Layer * LayerMipmap.Mipmaps + lm.Mipmap);
        }
Beispiel #26
0
 public RenderTargetView GetRtView(LayerMipmapSlice lm)
 {
     Debug.Assert(rtViews != null);
     return(rtViews[GetSubresourceIndex(lm)]);
 }
Beispiel #27
0
 public ShaderResourceView GetSrView(LayerMipmapSlice lm)
 {
     return(views[GetSubresourceIndex(lm)]);
 }
Beispiel #28
0
 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);
 }
Beispiel #29
0
 public void Run(ITexture src, ITexture dst, LayerMipmapSlice lm, UploadBuffer upload)
 {
     Run(new[] { src }, dst, lm, upload);
 }
Beispiel #30
0
 /// <inheritdoc cref="PixelValueShader.Run"/>
 public Color GetPixelValue(ITexture image, Size3 coord, LayerMipmapSlice lm, int radius = 0)
 {
     return(PixelValueShader.Run(image, coord, lm, radius));
 }