示例#1
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="srcLayer"></param>
        /// <param name="srcMip"></param>
        /// <param name="dst">destination texture</param>
        /// <param name="dstLayer"></param>
        /// <param name="dstMip"></param>
        public void CopyLayer(TextureArray2D src, int srcLayer, int srcMip, TextureArray2D dst, int dstLayer,
                              int dstMip)
        {
            Debug.Assert(src.Size == dst.Size);

            var dev = DirectX.Device.Get();

            quad.Bind(false);
            dev.Pixel.Set(convert2D.Pixel);

            dev.Pixel.SetShaderResource(0, src.View);


            cbuffer.SetData(new LayerLevelOffsetData
            {
                Layer      = srcLayer,
                Level      = srcMip,
                Xoffset    = 0,
                Yoffset    = 0,
                Multiplier = 1.0f
            });

            var dim = dst.Size.GetMip(dstMip);

            dev.Pixel.SetConstantBuffer(0, cbuffer.Handle);
            dev.OutputMerger.SetRenderTargets(dst.GetRtView(dstLayer, dstMip));
            dev.SetViewScissors(dim.Width, dim.Height);
            dev.DrawQuad();

            // remove bindings
            dev.Pixel.SetShaderResource(0, null);
            dev.OutputMerger.SetRenderTargets((RenderTargetView)null);
        }
示例#2
0
        public void TestNotSoSmallButStillSmall()
        {
            var upload = new UploadBuffer(4 * 13);

            upload.SetData(new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });
            Assert.AreEqual(13, Reduce <int>(upload, new ReduceShader(new UploadBuffer(256), "a+b", "0", "int")));

            upload.SetData(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 });
            Assert.AreEqual(91, Reduce <int>(upload, new ReduceShader(new UploadBuffer(256), "a+b", "0", "int")));
        }
示例#3
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);
        }
        private void Apply(TextureArray2D src, TextureArray2D dst, int dirX, int dirY)
        {
            quad.Bind(false);
            var dev = Device.Get();

            dev.Pixel.Set(shader.Pixel);

            cbuffer.SetData(new DirSizeData
            {
                DirX  = dirX,
                DirY  = dirY,
                SizeX = src.Size.Width,
                SizeY = src.Size.Height
            });

            dev.Pixel.SetConstantBuffer(0, cbuffer.Handle);
            dev.SetViewScissors(dst.Size.Width, dst.Size.Height);

            foreach (var lm in src.LayerMipmap.LayersOfMipmap(0))
            {
                dev.Pixel.SetShaderResource(0, src.GetSrView(lm));
                dev.OutputMerger.SetRenderTargets(dst.GetRtView(lm));
                dev.DrawQuad();
            }

            dev.Pixel.SetShaderResource(0, null);
            dev.OutputMerger.SetRenderTargets((RenderTargetView)null);
            quad.Unbind();
        }
示例#5
0
        public void Run(ImagesModel images, UploadBuffer constantBuffer, ITexture target)
        {
            var dev = Device.Get();

            dev.Compute.Set(shader.Compute);

            // src images
            for (int i = 0; i < images.NumImages; ++i)
            {
                dev.Compute.SetShaderResource(i, images.Images[i].Image.View);
            }

            for (int curMipmap = 0; curMipmap < images.NumMipmaps; ++curMipmap)
            {
                var size = images.GetSize(curMipmap);

                // dst image
                dev.Compute.SetUnorderedAccessView(0, target.GetUaView(curMipmap));

                for (int curLayer = 0; curLayer < images.NumLayers; ++curLayer)
                {
                    constantBuffer.SetData(new LayerLevelFilter {
                        Layer = curLayer, Level = curMipmap
                    });
                    dev.Compute.SetConstantBuffer(0, constantBuffer.Handle);
                    dev.Dispatch(
                        Utility.Utility.DivideRoundUp(size.Width, builder.LocalSizeX),
                        Utility.Utility.DivideRoundUp(size.Height, builder.LocalSizeY),
                        Utility.Utility.DivideRoundUp(size.Depth, builder.LocalSizeZ));
                }
            }

            // remove images from unordered acces view slots (otherwise they can't be bound as srv later)
            dev.Compute.SetUnorderedAccessView(0, null);
        }
示例#6
0
        /// <summary>
        /// performs a reduce on the buffer. The final value will be at buffer[0]
        /// </summary>
        /// <param name="numElements">number of elements for the reduce</param>
        public void Run(GpuBuffer buffer, int numElements)
        {
            Device.Get().Compute.Set(shader.Compute);
            Device.Get().Compute.SetUnorderedAccessView(0, buffer.View);

            while (numElements > 1)
            {
                int numGroups = Utility.Utility.DivideRoundUp(numElements, ElementsPerGroup);
                numBuffer.SetData(numElements);
                Device.Get().Compute.SetConstantBuffer(0, numBuffer.Handle);

                // test if numGroups > DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION
                var numSplits = Utility.Utility.DivideRoundUp(numGroups, Device.DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION);
                if (numSplits > 1)
                {
                    Device.Get().Dispatch(Device.DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION, numSplits);
                }
                else
                {
                    Device.Get().Dispatch(numGroups, 1);
                }

                numElements = numGroups;
            }

            Device.Get().Compute.Set(null);
        }
示例#7
0
        public void Run(ShaderResourceView left, ShaderResourceView right, RenderTargetView dst, int borderSize, int borderLocation, int width, int height)
        {
            Debug.Assert(borderLocation >= 0);
            Debug.Assert(borderLocation < width);

            quad.Bind(false);
            var dev = Device.Get();

            dev.Pixel.Set(pixel.Pixel);

            // update buffer
            cbuffer.SetData(new BufferData
            {
                BorderLocation = borderLocation,
                BorderSize     = borderSize
            });

            // bind and draw
            dev.Pixel.SetConstantBuffer(0, cbuffer.Handle);
            dev.Pixel.SetShaderResource(0, left);
            dev.Pixel.SetShaderResource(1, right);
            dev.OutputMerger.SetRenderTargets(dst);
            dev.SetViewScissors(width, height);
            dev.DrawQuad();

            // unbind
            dev.Pixel.SetShaderResource(0, null);
            dev.Pixel.SetShaderResource(1, null);
            dev.OutputMerger.SetRenderTargets((RenderTargetView)null);
            quad.Unbind();
        }
示例#8
0
        public void Run(UploadBuffer buffer, Matrix transform, Vector4 crop, float multiplier, bool useAbs,
                        ShaderResourceView texture, SamplerState sampler, int xaxis = 0, int yaxis = 1, int zvalue = 0)
        {
            buffer.SetData(new ViewBufferData
            {
                Transform  = transform,
                Crop       = crop,
                Multiplier = multiplier,
                UseAbs     = useAbs?1:0,
                XAxis      = xaxis,
                YAxis      = yaxis,
                ZValue     = zvalue
            });

            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();

            // unbind
            dev.Pixel.SetShaderResource(0, null);
            UnbindShader(dev);
        }
示例#9
0
        public void Run(UploadBuffer buffer, Matrix transform, float multiplier, float farplane, bool useAbs, ShaderResourceView texture, SamplerState sampler)
        {
            buffer.SetData(new ViewBufferData
            {
                Transform  = transform,
                Multiplier = multiplier,
                Farplane   = farplane,
                UseAbs     = useAbs ? 1 : 0
            });

            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();

            // unbind
            dev.Pixel.SetShaderResource(0, null);
            UnbindShader(dev);
        }
示例#10
0
        // 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);
        }
        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);
        }
示例#12
0
        public void TestSmall()
        {
            var upload = new UploadBuffer(4 * 4);

            upload.SetData(new int[] { 1, 2, 3, 4 });

            Assert.AreEqual(10, Reduce <int>(upload, new ReduceShader(new UploadBuffer(256), "a+b", "0", "int")));
        }
示例#13
0
        /// <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);
        }
示例#14
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();
        }
示例#15
0
        private void ExecuteDimension(ref BufferData bufferData, UploadBuffer buffer, bool is3D, int dim, Size3 srcSize, ShaderResourceView srcTexture, UnorderedAccessView dstTexture)
        {
            // filter x direction
            bufferData.Dir = new Size3(0, 0, 0)
            {
                [dim] = 1
            };
            bufferData.NumSrcPixelsTotal = srcSize[dim];

            var dev = Device.Get();

            var iFilterSize = srcSize[dim] / bufferData.DstSize[dim];

            if (srcSize[dim] == bufferData.DstSize[dim]) // same size
            {
                dev.Compute.Set(is3D ? CopyShader3D.Compute : CopyShader.Compute);

                // just copy
            }
            else if (srcSize[dim] % bufferData.DstSize[dim] == 0 && // integer division possible?
                     !(Odd(iFilterSize) && !Odd(kernelStretch)))    // stretch does not result in half samples?
            {
                bufferData.NumSrcPixels = iFilterSize;
                dev.Compute.Set(is3D ? FastShader3D.Compute : FastShader.Compute);
            }
            else
            {
                bufferData.FilterSize = srcSize[dim] / (float)bufferData.DstSize[dim];
                dev.Compute.Set(is3D ? SlowShader3D.Compute : SlowShader.Compute);
            }

            // bind stuff
            buffer.SetData(bufferData);
            dev.Compute.SetConstantBuffer(0, buffer.Handle);
            dev.Compute.SetShaderResource(0, srcTexture);
            dev.Compute.SetUnorderedAccessView(0, dstTexture);
            BindAdditionalResources(dev);

            var builder = is3D ? ShaderBuilder.Builder3D : ShaderBuilder.Builder2D;

            dev.Dispatch(
                Utility.Utility.DivideRoundUp(bufferData.DstSize.X, builder.LocalSizeX),
                Utility.Utility.DivideRoundUp(bufferData.DstSize.Y, builder.LocalSizeY),
                Utility.Utility.DivideRoundUp(bufferData.DstSize.Z, builder.LocalSizeZ)
                );

            // unbind stuff
            dev.Compute.SetShaderResource(0, null);
            dev.Compute.SetUnorderedAccessView(0, null);


            UnbindAdditionalResources(dev);
        }
示例#16
0
        private void Dispatch(Int3 direction, int iteration, Size3 size, UploadBuffer uploadBuffer)
        {
            var dev = Device.Get();

            uploadBuffer.SetData(new DirBufferData
            {
                dir       = direction,
                dim       = size,
                iteration = iteration
            });
            dev.Compute.SetConstantBuffer(0, uploadBuffer.Handle);
            dev.Dispatch(Utility.DivideRoundUp(size.X, workgroupSize.X), Utility.DivideRoundUp(size.Y, workgroupSize.Y), Utility.DivideRoundUp(size.Z, workgroupSize.Z));
        }
示例#17
0
        /// <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);
        }
示例#18
0
        /// <summary>
        /// reloads all values into the buffer
        /// </summary>
        internal void UpdateParamBuffer()
        {
            if (paramBuffer == null)
            {
                return;
            }

            var data = new int[parent.Parameters.Count];

            for (var i = 0; i < data.Length; ++i)
            {
                data[i] = parent.Parameters[i].StuffToInt();
            }

            paramBuffer.SetData(data);
        }
示例#19
0
        public void TestMultipleDispatch()
        {
            var upload = new UploadBuffer(4 * (ReduceShader.ElementsPerGroup + ReduceShader.ElementsPerGroup / 2 + 1));
            var count  = upload.ByteSize / 4;
            var data   = new int[count];

            for (int i = 0; i < data.Length; ++i)
            {
                data[i] = i + 1;
            }
            upload.SetData(data);

            int expected = (count * (count + 1)) / 2;

            Assert.AreEqual(expected, Reduce <int>(upload, new ReduceShader(new UploadBuffer(256), "a+b", "0", "int")));
        }
        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);
        }
示例#21
0
        public void VeryLarge()
        {
            // 400 mb of data
            var upload = new UploadBuffer(4 * 1024 * 1024 * 100);
            var count  = upload.ByteSize / 4;
            var data   = new float[count];

            for (int i = 0; i < count; ++i)
            {
                data[i] = (float)(i + 1);
            }
            upload.SetData(data);

            float expected = (float)count;

            Assert.AreEqual(expected, Reduce <float>(upload, new ReduceShader(new UploadBuffer(256), "max(a,b)")));
        }
示例#22
0
        /// <summary>
        /// performs a reduce on the buffer. The final value will be at buffer[0]
        /// </summary>
        /// <param name="numElements">number of elements for the reduce</param>
        public void Run(GpuBuffer buffer, int numElements)
        {
            Device.Get().Compute.Set(shader.Compute);
            Device.Get().Compute.SetUnorderedAccessView(0, buffer.View);

            while (numElements > 1)
            {
                int numGroups = Utility.Utility.DivideRoundUp(numElements, ElementsPerGroup);
                numBuffer.SetData(numElements);
                Device.Get().Compute.SetConstantBuffer(0, numBuffer.Handle);

                Device.Get().Dispatch(numGroups, 1);
                numElements = numGroups;
            }

            Device.Get().Compute.Set(null);
        }
示例#23
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);
        }
        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);
            }
        }
示例#25
0
        public void Run(UploadBuffer buffer, Matrix transform, SettingsModel.AlphaType background)
        {
            buffer.SetData(new BufferData
            {
                Transform  = transform,
                ThemeColor = themeColor,
                Type       = (int)background
            });

            var dev = Device.Get();

            dev.Vertex.Set(vertex.Vertex);
            dev.Pixel.Set(pixel.Pixel);

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

            dev.DrawQuad();
        }
示例#26
0
        private void UpdateData(int mipmap)
        {
            if (Boxes.Count == 0)
            {
                return;
            }

            int floatCount = Boxes.Count * 2 * 4; // each box has 4 edges with 2 float component

            if (positionBuffer == null || positionBuffer.ByteSize < floatCount * sizeof(float))
            {
                // resize buffer
                positionBuffer?.Dispose();
                positionBuffer = new UploadBuffer(floatCount * sizeof(float), BindFlags.VertexBuffer);
            }

            // fill buffer
            var data = new float[floatCount];
            var dim  = images.Size.GetMip(mipmap);
            // offset float coordinates by half a unit so the quad covers the area
            var offset = Size2.Zero.ToCoords(dim.XY);

            for (var i = 0; i < Boxes.Count; i++)
            {
                var box = Boxes[i];

                // top left
                data[i * 8]     = ToCanonical(box.Start.X - offset.X);
                data[i * 8 + 1] = ToCanonical(box.Start.Y - offset.Y);
                // top right
                data[i * 8 + 2] = ToCanonical(box.End.X + offset.X);
                data[i * 8 + 3] = ToCanonical(box.Start.Y - offset.Y);
                // bot left
                data[i * 8 + 4] = ToCanonical(box.Start.X - offset.X);
                data[i * 8 + 5] = ToCanonical(box.End.Y + offset.Y);
                // bot right
                data[i * 8 + 6] = ToCanonical(box.End.X + offset.X);
                data[i * 8 + 7] = ToCanonical(box.End.Y + offset.Y);
            }

            // upload buffer
            positionBuffer.SetData(data);
        }
示例#27
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);
        }
示例#28
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>());
        }
示例#30
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="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);
        }