private T Reduce <T>(UploadBuffer data, ReduceShader shader) where T : struct { Console.WriteLine("num groups: " + Utility.DivideRoundUp(data.ByteSize / 4, ReduceShader.ElementsPerGroup)); using (var buf = new GpuBuffer(4, data.ByteSize / 4)) { buf.CopyFrom(data); using (var timer = new GpuTimer()) { timer.Start(); //for(int i = 0; i < 100; ++i) shader.Run(buf, data.ByteSize / 4); timer.Stop(); Console.WriteLine(timer.GetDelta()); } using (var res = new DownloadBuffer(4)) { res.CopyFrom(buf, Marshal.SizeOf <T>()); var resData = res.GetData <T>(); return(resData); } } }
/// <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>()); }