/// <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); }
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"))); }
/// <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(); }
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); }
/// <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); }
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(); }
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); }
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); }
// 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); }
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"))); }
/// <summary> /// puts statistic data of all pixels into the buffer /// </summary> /// <param name="lm">range with single mipmap</param> /// <param name="offset">offset in each direction</param> /// <param name="source"></param> /// <param name="buffer"></param> internal void CopyToBuffer(ITexture source, GpuBuffer buffer, LayerMipmapRange lm, Size3 offset) { Debug.Assert(lm.IsSingleMipmap); // copy pixels from the source image into a texture from the texture cache var dev = Device.Get(); if (source.Is3D) { dev.Compute.Set(shader3d.Compute); } else { dev.Compute.Set(shader.Compute); } var dim = source.Size.GetMip(lm.Mipmap); AdjustDim(ref dim, ref offset, source.Is3D); var numLayers = source.LayerMipmap.Layers; var curData = new BufferData { Level = lm.Mipmap, TrueBool = true, Offset = offset, Size = dim }; if (lm.AllLayer) { dev.Compute.SetShaderResource(0, source.View); } else { // single layer dev.Compute.SetShaderResource(0, source.GetSrView(lm.Single)); curData.Level = 0; // view with single level numLayers = 1; } cbuffer.SetData(curData); // buffer big enough? Debug.Assert(buffer.ElementCount >= dim.Product * numLayers); dev.Compute.SetUnorderedAccessView(0, buffer.View); dev.Compute.SetConstantBuffer(0, cbuffer.Handle); dev.Dispatch(Utility.Utility.DivideRoundUp(dim.Width, LocalSizeX), Utility.Utility.DivideRoundUp(dim.Height, LocalSizeY), Math.Max(dim.Depth, numLayers)); dev.Compute.SetUnorderedAccessView(0, null); dev.Compute.SetShaderResource(0, null); }
/// <summary> /// copies a single mip from one layer of a texture to another layer of a texture. The formats don't have to match /// </summary> /// <param name="src">source texture</param> /// <param name="dst">destination texture</param> public void CopyLayer(ITexture src, LayerMipmapSlice srcLm, ITexture dst, LayerMipmapSlice dstLm) { Debug.Assert(src.Size == dst.Size); var dev = DirectX.Device.Get(); quad.Bind(src.Is3D); if (src.Is3D) { dev.Pixel.Set(convert3D.Pixel); } else { dev.Pixel.Set(convert2D.Pixel); } dev.Pixel.SetShaderResource(0, src.View); cbuffer.SetData(new LayerLevelOffsetData { Layer = srcLm.Layer, Level = srcLm.Mipmap, Xoffset = 0, Yoffset = 0, Multiplier = 1.0f, UseOverlay = 0, Scale = 1 }); var dim = dst.Size.GetMip(dstLm.Mipmap); dev.Pixel.SetConstantBuffer(0, cbuffer.Handle); dev.OutputMerger.SetRenderTargets(dst.GetRtView(dstLm)); dev.SetViewScissors(dim.Width, dim.Height); dev.DrawFullscreenTriangle(dim.Depth); // remove bindings dev.Pixel.SetShaderResource(0, null); dev.OutputMerger.SetRenderTargets((RenderTargetView)null); quad.Unbind(); }
private void 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); }
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)); }
/// <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); }
/// <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); }
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); }
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)"))); }
/// <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); }
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); } }
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(); }
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); }
/// <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 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>()); }
/// <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); }