예제 #1
0
 public ConvertPolarShader(QuadShader quad)
 {
     this.quad = quad;
     toCube    = new DirectX.Shader(DirectX.Shader.Type.Pixel, GetCubeSource(), "ConvertToCube");
     toLatLong = new DirectX.Shader(DirectX.Shader.Type.Pixel, GetLatLongSource(), "CovertToLatLong");
     sampler   = new SamplerState(Device.Get().Handle, new SamplerStateDescription
     {
         AddressU          = TextureAddressMode.Wrap,
         AddressV          = TextureAddressMode.Wrap,
         AddressW          = TextureAddressMode.Wrap,
         Filter            = SharpDX.Direct3D11.Filter.Anisotropic,
         MaximumAnisotropy = 16
     });
 }
        public TextureArray2D ConvertToArray(Texture3D src, int fixedAxis1, int fixedAxis2, UploadBuffer cbuffer, int startLayer = 0, int numLayers = -1)
        {
            Debug.Assert(fixedAxis1 >= 0 && fixedAxis1 <= 2);
            Debug.Assert(fixedAxis2 >= 0 && fixedAxis2 <= 2);
            var dim       = src.Size;
            var layerAxis = 3 - fixedAxis1 - fixedAxis2;

            if (numLayers < 0)
            {
                numLayers = dim[layerAxis] - startLayer;
            }

            var dst = new TextureArray2D(
                new LayerMipmapCount(numLayers, 1),
                new Size3(dim[fixedAxis1], dim[fixedAxis2]),
                Format.R32G32B32A32_Float, false
                );

            var data = new LayerBufferData
            {
                XAxis = fixedAxis1,
                YAxis = fixedAxis2
            };

            var dev = Device.Get();

            quad.Bind(false);
            dev.Pixel.Set(shaderLayer.Pixel);
            dev.Pixel.SetShaderResource(0, src.GetSrView(0));
            dev.SetViewScissors(dst.Size.Width, dst.Size.Height);

            foreach (var lm in dst.LayerMipmap.Range)
            {
                data.ZValue = lm.Layer + startLayer;
                cbuffer.SetData(data);
                dev.Pixel.SetConstantBuffer(0, cbuffer.Handle);
                dev.OutputMerger.SetRenderTargets(dst.GetRtView(lm));

                dev.DrawFullscreenTriangle(1);
            }

            quad.Unbind();
            dev.Pixel.SetShaderResource(0, null);
            dev.OutputMerger.SetRenderTargets((RenderTargetView)null);

            return(dst);
        }
예제 #3
0
        public void Run(UploadBuffer buffer, Matrix projection, Matrix model, float multiplier,
                        bool useAbs, ShaderResourceView texture, SamplerState sampler, Size3 imgSize)
        {
            // determine which axis should be used for slices
            var zDir = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);

            Vector4.Transform(ref zDir, ref model, out var outDir);
            int fixedAxis = 0;

            for (int i = 1; i < 3; ++i)
            {
                if (Math.Abs(outDir[i]) > Math.Abs(outDir[fixedAxis]))
                {
                    fixedAxis = i;
                }
            }

            buffer.SetData(new ViewBufferData
            {
                Transform    = model * projection,
                UseAbs       = useAbs?1:0,
                Multiplier   = multiplier,
                FixedAxis    = fixedAxis,
                FixedAxisDim = imgSize[fixedAxis],
                Aspects      = new Vector2(imgSize.X / (float)imgSize.Y, imgSize.Z / (float)imgSize.Y)
            });

            // bind resources
            var dev = Device.Get();

            BindShader(dev);

            dev.Vertex.SetConstantBuffer(0, buffer.Handle);
            dev.Pixel.SetConstantBuffer(0, buffer.Handle);

            dev.Pixel.SetShaderResource(0, texture);
            dev.Pixel.SetSampler(0, sampler);

            dev.DrawQuad(imgSize[fixedAxis]);

            // unbind
            dev.Pixel.SetShaderResource(0, null);
            UnbindShader(dev);
        }
예제 #4
0
        public void Draw(ObservableCollection <BoxOverlay.Box> boxes, UploadBuffer upload, int mipmap, Size2 dim)
        {
            var    dev  = Device.Get();
            IntBox ibox = new IntBox();

            for (var i = 0; i < boxes.Count; i++)
            {
                var box = boxes[i];
                ibox.Color  = box.Color;
                ibox.Border = Math.Max(box.Border >> mipmap, 1);
                // calc integer start and end
                ibox.Start = box.Start.ToPixels(dim);
                ibox.End   = box.End.ToPixels(dim);

                upload.SetData(ibox);
                dev.Pixel.SetConstantBuffer(0, upload.Handle);
                dev.ContextHandle.DrawInstanced(4, 1, i * 4, 0);
            }
        }
예제 #5
0
        /// <summary>
        /// checks if this graphics card supports the relevant features
        /// </summary>
        private void CheckDeviceCapabilities()
        {
            var dev = Device.Get();

            // check supported format capabilities
            foreach (var f in IO.SupportedFormats)
            {
                var sup = dev.CheckFormatSupport(f);

                // TODO this should depend on the type
                if ((sup & FormatSupport.Texture2D) == 0)
                {
                    throw new Exception($"Texture2D support for {f} is required");
                }
                if ((sup & FormatSupport.Texture3D) == 0)
                {
                    throw new Exception($"Texture3D support for {f} is required");
                }

                // TODO this can be optional
                if ((sup & FormatSupport.MipAutogen) == 0)
                {
                    throw new Exception($"MipAutogen support for {f} is required");
                }

                if ((sup & FormatSupport.RenderTarget) == 0)
                {
                    throw new Exception($"RenderTarget support for {f} is required");
                }

                if (f == Format.R32G32B32A32_Float)
                {
                    if ((sup & FormatSupport.TypedUnorderedAccessView) == 0)
                    {
                        throw new Exception($"TypesUnorderedAccess support for {f} is required");
                    }
                    if ((sup & FormatSupport.TextureCube) == 0)
                    {
                        throw new Exception($"TextureCube support for {f} is required");
                    }
                }
            }
        }
예제 #6
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);
        }
        public Texture3D ConvertTo3D(TextureArray2D src)
        {
            var dst = new Texture3D(1, new Size3(src.Size.X, src.Size.Y, src.NumLayers), Format.R32G32B32A32_Float,
                                    false);

            var dev = Device.Get();

            quad.Bind(true);
            dev.Pixel.Set(shader3D.Pixel);

            dev.Pixel.SetShaderResource(0, src.View);
            dev.OutputMerger.SetRenderTargets(dst.GetRtView(LayerMipmapSlice.Mip0));
            dev.SetViewScissors(dst.Size.Width, dst.Size.Height);
            dev.DrawFullscreenTriangle(dst.Size.Z);

            dev.Pixel.SetShaderResource(0, null);
            dev.OutputMerger.SetRenderTargets((RenderTargetView)null);
            quad.Unbind();

            return(dst);
        }
예제 #8
0
        public ThumbnailModel(QuadShader quad)
        {
            this.quad = quad;
            convert2D = new DirectX.Shader(DirectX.Shader.Type.Pixel, GetSource(ShaderBuilder.Builder2D), "ThumbnailPixelShader2D");
            convert3D = new DirectX.Shader(DirectX.Shader.Type.Pixel, GetSource(ShaderBuilder.Builder3D), "ThumbnailPixelShader3D");
            var samplerDesc = new SamplerStateDescription
            {
                AddressU           = TextureAddressMode.Clamp,
                AddressV           = TextureAddressMode.Clamp,
                AddressW           = TextureAddressMode.Clamp,
                BorderColor        = new RawColor4(),
                ComparisonFunction = Comparison.Never,
                Filter             = SharpDX.Direct3D11.Filter.MinLinearMagMipPoint,
                MaximumAnisotropy  = 1,
                MaximumLod         = float.MaxValue,
                MinimumLod         = 0,
                MipLodBias         = 0
            };

            sampler = new SamplerState(Device.Get().Handle, samplerDesc);
        }
예제 #9
0
        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);
                }
            }
        }
예제 #10
0
 public PaddingShader()
 {
     shader   = new DirectX.Shader(DirectX.Shader.Type.Pixel, GetSource(ShaderBuilder.Builder2D), "PaddingShader");
     shader3D = new DirectX.Shader(DirectX.Shader.Type.Pixel, GetSource(ShaderBuilder.Builder3D), "PaddingShader3D");
     sampler  = new SamplerState[]
     {
         new SamplerState(Device.Get().Handle, new SamplerStateDescription
         {
             AddressU    = TextureAddressMode.Border,
             AddressV    = TextureAddressMode.Border,
             AddressW    = TextureAddressMode.Border,
             BorderColor = new RawColor4(0.0f, 0.0f, 0.0f, 1.0f),
             Filter      = SharpDX.Direct3D11.Filter.MinMagMipPoint
         }),
         new SamplerState(Device.Get().Handle, new SamplerStateDescription
         {
             AddressU    = TextureAddressMode.Border,
             AddressV    = TextureAddressMode.Border,
             AddressW    = TextureAddressMode.Border,
             BorderColor = new RawColor4(1.0f, 1.0f, 1.0f, 1.0f),
             Filter      = SharpDX.Direct3D11.Filter.MinMagMipPoint
         }),
         new SamplerState(Device.Get().Handle, new SamplerStateDescription
         {
             AddressU    = TextureAddressMode.Border,
             AddressV    = TextureAddressMode.Border,
             AddressW    = TextureAddressMode.Border,
             BorderColor = new RawColor4(0.0f, 0.0f, 0.0f, 0.0f),
             Filter      = SharpDX.Direct3D11.Filter.MinMagMipPoint
         }),
         new SamplerState(Device.Get().Handle, new SamplerStateDescription
         {
             AddressU = TextureAddressMode.Clamp,
             AddressV = TextureAddressMode.Clamp,
             AddressW = TextureAddressMode.Clamp,
             Filter   = SharpDX.Direct3D11.Filter.MinMagMipPoint
         }),
     };
 }
예제 #11
0
        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;

            ShaderResourceView overlay = null;

            if (models.Overlay.Overlay != null)
            {
                overlay = ((TextureArray2D)models.Overlay.Overlay).GetCubeView(models.Display.ActiveMipmap);
            }
            shader.Run(GetTransform(), CalcFarplane(), ((TextureArray2D)texture).GetCubeView(models.Display.ActiveMipmap), overlay);

            dev.OutputMerger.BlendState = models.ViewData.DefaultBlendState;
        }
예제 #12
0
        public virtual void Dispose()
        {
            Progress?.Dispose();
            thumbnail?.Dispose();
            stats?.Dispose();
            gif?.Dispose();
            scaling?.Dispose();
            overlay?.Dispose();
            ssim?.Dispose();

            Images?.Dispose();
            Filter?.Dispose();
            polarConvertShader?.Dispose();
            convertTo3DShader?.Dispose();
            foreach (var imagePipeline in pipelines)
            {
                imagePipeline.Dispose();
            }
            pixelValueShader?.Dispose();
            SharedModel?.Dispose();

            // finally, destroy directx resources
            Device.Get().Dispose();
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="transform">transformation matrix from camera space to image space (pixel coordinates)</param>
        /// <param name="screenAspect">screen aspect ratio</param>
        /// <param name="texture"></param>
        /// <param name="emptySpaceTex"></param>
        public void Run(Matrix transform, ShaderResourceView texture, ShaderResourceView emptySpaceTex)
        {
            var v = models.ViewData;

            v.Buffer.SetData(GetCommonData(transform, models.Display.ClientAspectRatioScalar));

            var dev = Device.Get();

            BindShader(dev);

            dev.Vertex.SetConstantBuffer(0, v.Buffer.Handle);
            dev.Pixel.SetConstantBuffer(0, v.Buffer.Handle);

            dev.Pixel.SetShaderResource(0, texture);
            dev.Pixel.SetSampler(0, sampler);
            dev.Pixel.SetShaderResource(1, emptySpaceTex);

            dev.DrawQuad();

            // unbind
            dev.Pixel.SetShaderResource(0, null);
            dev.Pixel.SetShaderResource(1, null);
            UnbindShader(dev);
        }
예제 #14
0
        // base function: sin(pi * x * stretch) * sin(pi * x), x in [-1, 1]
        // stretch values in [1, 3]

        // kaiser (alpha=4) ~ lanzos (alpha=1)
        // see: https://www.wolframalpha.com/input/?i=plot+I_0%284*sqrt%281-x%5E2%29%29%2FI_0%284%29%2C+sin%28PI*x%29%2F%28PI*x%29%2C+x%3D0+to+1

        // for: sin(pi * x)^2
        // approximation of the integral from -1 to x: 0.89734 + x - x^3 / 9
        // integral is very similar to a linear function (box scaling shader)

        // for stretch = 3 (x will still be in [-1, 1]): sinc(pi * x * 3) * sinc(pi * x)
        // aprox. integral is given in s_values (128 values between -1 and 1)
        public unsafe LanzosScalingShader() : base(@"
return valueTex.SampleLevel(valueSampler, x * 0.5 + 0.5, 0).x; 
", 3)
        {
            // pin s_values
            fixed(float *pValues = s_values)
            {
                var ptr = new IntPtr(pValues);

                valueTex = new Texture1D(Device.Get().Handle, new Texture1DDescription
                {
                    ArraySize      = 1,
                    BindFlags      = BindFlags.ShaderResource,
                    CpuAccessFlags = CpuAccessFlags.None,
                    Format         = Format.R32_Float,
                    MipLevels      = 1,
                    OptionFlags    = ResourceOptionFlags.None,
                    Usage          = ResourceUsage.Default,
                    Width          = s_values.Length
                }, ptr);
            }

            valueTexView = new ShaderResourceView(Device.Get().Handle, valueTex);
            valueSampler = new SamplerState(Device.Get().Handle, new SamplerStateDescription
            {
                AddressU = TextureAddressMode.Clamp,
                AddressV = TextureAddressMode.Clamp,
                AddressW = TextureAddressMode.Clamp,
                Filter   = SharpDX.Direct3D11.Filter.MinMagLinearMipPoint
            });

            AdditionalBindings = @"
Texture1D valueTex : register(t1);
SamplerState valueSampler : register(s0);
";
        }
예제 #15
0
 private void UnbindResources(Device dev)
 {
     dev.Compute.SetShaderResource(0, null);
     dev.Compute.SetUnorderedAccessView(0, null);
 }
예제 #16
0
        /// <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="shared">common utilities</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>
        /// <param name="numMipmaps">number of mipmaps to apply the filter on (starting with most detailed mip)</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, SharedModel shared, int iteration, int numMipmaps)
        {
            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);
            dev.Compute.SetSampler(0, shared.LinearSampler);
            dev.Compute.SetSampler(1, shared.PointSampler);

            for (int curMipmap = 0; curMipmap < 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(new LayerMipmapSlice(curLayer, curMipmap)));
                    BindTextureParameters(image, new LayerMipmapSlice(curLayer, curMipmap));

                    shared.Upload.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, shared.Upload.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);
            UnbindTextureParameters();
        }
예제 #17
0
        public void Dds3DDirectXCompability()
        {
            var model = new Models(1);

            model.AddImageFromFile(TestData.Directory + "checkers3d.dds");
            model.Apply();
            var origTex    = (Texture3D)model.Pipelines[0].Image;
            var origColors = origTex.GetPixelColors(LayerMipmapSlice.Mip0);

            Color[] newColors = null;

            // colors multiplied by 100 for integer precision formats
            model.Pipelines[0].Color.Formula = "I0 * 100";
            model.Apply();
            var integerTex    = (Texture3D)model.Pipelines[0].Image;
            var origColors100 = integerTex.GetPixelColors(LayerMipmapSlice.Mip0);

            var    eFmt      = ExportDescription.GetExportFormat("dds");
            string errors    = "";
            int    numErrors = 0;
            int    nFormats  = 0;

            foreach (var format in eFmt.Formats)
            {
                if (format.IsExcludedFrom3DExport())
                {
                    continue;
                }
                nFormats++;
                try
                {
                    // export to dds
                    var isIntegerPrecision = IsIntegerPrecisionFormat(format);
                    var desc = new ExportDescription(origTex, ExportDir + "tmp", "dds");
                    desc.FileFormat = format;
                    desc.Quality    = 100;
                    if (isIntegerPrecision)
                    {
                        desc.Multiplier = 100.0f;
                    }
                    model.Export.Export(desc);

                    // load with directx dds loader
                    DDSTextureLoader.CreateDDSTextureFromFile(Device.Get().Handle, Device.Get().ContextHandle, ExportDir + "tmp.dds",
                                                              out var resource, out var resourceView, 0, out var alphaMode);

                    // convert to obtain color data
                    using (var newTex = model.SharedModel.Convert.ConvertFromRaw3D(resourceView, origTex.Size, Format.R32G32B32A32_Float, isIntegerPrecision))
                    {
                        resourceView.Dispose();
                        resource.Dispose();

                        newColors = newTex.GetPixelColors(LayerMipmapSlice.Mip0);
                        // only compare with red channel since some formats only store red
                        if (isIntegerPrecision)
                        {
                            TestData.CompareColors(origColors100, newColors, Color.Channel.R, 1.0f);
                        }
                        else
                        {
                            TestData.CompareColors(origColors, newColors, Color.Channel.R, 0.1f);
                        }
                    }
                }
                catch (Exception e)
                {
                    errors += $"{format}: {e.Message}\n";
                    ++numErrors;
                }
            }

            if (errors.Length > 0)
            {
                throw new Exception($"directX compability failed for {numErrors}/{nFormats} formats:\n" + errors);
            }
        }
예제 #18
0
        /// <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);
        }
        /// <summary>
        /// draws the active view
        /// </summary>
        /// <param name="size">actual size in pixel, not dpi independent size</param>
        public void Repaint(Size size)
        {
            var dev = Device.Get();

            var visible = models.GetEnabledPipelines();

            var scissorsPos = new Point(mousePosition.X, mousePosition.Y);

            if (visible.Count < 2)
            {
                fixedMousePosition = null;
            }
            if (fixedMousePosition != null)
            {
                scissorsPos = new Point(fixedMousePosition.Value.X, fixedMousePosition.Value.Y);
            }

            if (visible.Count == 1)
            {
                // draw single image
                currentView.Draw(models.Pipelines[visible[0]].Image);
            }
            else if (visible.Count == 2)
            {
                // draw two images in split view

                scissorsPos.X = Math.Min(size.Width - 1, Math.Max(0, scissorsPos.X));
                scissorsPos.Y = Math.Min(size.Height - 1, Math.Max(0, scissorsPos.Y));

                if (models.Display.Split == DisplayModel.SplitMode.Vertical)
                {
                    dev.Rasterizer.SetScissorRectangle(0, 0, scissorsPos.X, size.Height);
                }
                else
                {
                    dev.Rasterizer.SetScissorRectangle(0, 0, size.Width, scissorsPos.Y);
                }

                // first image
                currentView.Draw(models.Pipelines[visible[0]].Image);

                if (models.Display.Split == DisplayModel.SplitMode.Vertical)
                {
                    dev.Rasterizer.SetScissorRectangle(scissorsPos.X, 0, size.Width, size.Height);
                }
                else
                {
                    dev.Rasterizer.SetScissorRectangle(0, scissorsPos.Y, size.Width, size.Height);
                }

                // second image
                currentView.Draw(models.Pipelines[visible[1]].Image);
            }
            else if (visible.Count == 3 || visible.Count == 4)
            {
                scissorsPos.X = Math.Min(size.Width - 1, Math.Max(0, scissorsPos.X));
                scissorsPos.Y = Math.Min(size.Height - 1, Math.Max(0, scissorsPos.Y));

                // upper left
                dev.Rasterizer.SetScissorRectangle(0, 0, scissorsPos.X, scissorsPos.Y);
                currentView.Draw(models.Pipelines[visible[0]].Image);

                // upper right
                dev.Rasterizer.SetScissorRectangle(scissorsPos.X, 0, size.Width, scissorsPos.Y);
                currentView.Draw(models.Pipelines[visible[1]].Image);

                // draw third texture (entire bottom if only 3 are visible, lower left if 4 are visible)
                dev.Rasterizer.SetScissorRectangle(0, scissorsPos.Y, visible.Count == 3 ? size.Width : scissorsPos.X, size.Height);
                currentView.Draw(models.Pipelines[visible[2]].Image);

                if (visible.Count == 4)
                {
                    dev.Rasterizer.SetScissorRectangle(scissorsPos.X, scissorsPos.Y, size.Width, size.Height);
                    currentView.Draw(models.Pipelines[visible[3]].Image);
                }
            }
        }
예제 #20
0
 protected virtual void UnbindAdditionalResources(Device dev)
 {
 }
예제 #21
0
        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();
        }
예제 #22
0
 protected override void BindAdditionalResources(Device dev)
 {
     dev.Compute.SetShaderResource(1, valueTexView);
     dev.Compute.SetSampler(0, valueSampler);
 }
예제 #23
0
        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);
            }
        }
예제 #24
0
 protected override void UnbindAdditionalResources(Device dev)
 {
     dev.Compute.SetShaderResource(1, null);
     dev.Compute.SetSampler(0, null);
 }