public void Step(float stepSize) { // Load the next vector fields to device memory. LoadNextField(); _cudaDxMapper.MapAllResources(); CudaArray2D lastFlowMap = _cudaDxMapper[0].GetMappedArray2D(0, 0); // Advect from each member to each member. In each block, the same configuration is choosen. dim3 grid = new dim3((int)((float)_width / BLOCK_SIZE + 0.5f), (int)((float)_height / BLOCK_SIZE + 0.5f), _numMembers); // Advect a block in each member-member combination. dim3 threads = new dim3(BLOCK_SIZE, BLOCK_SIZE); _advectParticlesKernel.GridDimensions = grid; _advectParticlesKernel.BlockDimensions = threads; // (float* mapT1, const int width, const int height, const int numMembers, /*float timeScale, */ float stepSize, float minDensity, float invalid) _advectParticlesKernel.Run(_pongFlowMap.DevicePointer, _width, _height, _numMembers, stepSize, 0.000001f, _texInvalidValue); // Swap the Texture2D handles. CudaSurfObject surf = new CudaSurfObject(lastFlowMap); grid.z = 1; _copyMapDataKernel.GridDimensions = grid; _copyMapDataKernel.BlockDimensions = threads; _copyMapDataKernel.Run(surf.SurfObject, _pongFlowMap.DevicePointer, _width, _height); _cudaDxMapper.UnmapAllResources(); }
private void display() { stopwatch.Start(); advectVelocity(g_dvfield, g_vxfield, g_vyfield, DIM, RPADW, DIM, DT, g_tPitch); { g_planr2c.Exec(g_vxfield.DevicePointer); g_planr2c.Exec(g_vyfield.DevicePointer); diffuseProject(g_vxfield, g_vyfield, CPADW, DIM, DT, VIS, g_tPitch); g_planc2r.Exec(g_vxfield.DevicePointer); g_planc2r.Exec(g_vyfield.DevicePointer); } updateVelocity(g_dvfield, g_vxfield, g_vyfield, DIM, RPADW, DIM, g_tPitch); // Map D3D9 vertex buffer to CUDA { graphicsres.MapAllResources(); g_mparticles = graphicsres[0].GetMappedPointer <vertex>(); advectParticles(g_mparticles, g_dvfield, DIM, DIM, DT, g_tPitch); graphicsres.UnmapAllResources(); } device.Clear(ClearFlags.Target, new Color4(0.0f, 0, 0), 0.0f, 0); device.SetRenderState(RenderState.ZWriteEnable, false); device.SetRenderState(RenderState.AlphaBlendEnable, true); device.SetRenderState(RenderState.SourceBlend, Blend.One); device.SetRenderState(RenderState.DestinationBlend, Blend.One); device.SetRenderState(RenderState.PointSpriteEnable, true); float size = 16.0f; device.SetRenderState(RenderState.PointSize, size); device.SetTexture(0, g_pTexture); if (device.BeginScene().IsSuccess) { Result res; //Draw particles res = device.SetStreamSource(0, g_pVB, 0, Marshal.SizeOf(typeof(vertex))); device.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse; res = device.DrawPrimitives(PrimitiveType.PointList, 0, DS); device.EndScene(); } stopwatch.Stop(); device.Present(); fpsCount++; if (fpsCount == fpsLimit) { float ifps = 1.0f / (stopwatch.GetElapsedTime() / 1000.0f); string fps = string.Format(System.Globalization.CultureInfo.InvariantCulture, "CUDA/D3D9 Stable Fluids ({0} x {1}): {2} fps", DIM, DIM, ifps); this.Text = fps; fpsCount = 0; fpsLimit = (int)Math.Max(ifps, 1.0f); } }
void advectParticles(uint vbo, CudaPitchedDeviceVariable <cData> v, int dx, int dy, float dt, SizeT tPitch) { dim3 grid = new dim3((uint)((dx / TILEX) + (!(dx % TILEX != 0) ? 0 : 1)), (uint)((dy / TILEY) + (!(dy % TILEY != 0) ? 0 : 1)), 1); dim3 tids = new dim3(TIDSX, TIDSY, 1); cuda_vbo_resource.MapAllResources(); CUdeviceptr p = cuda_vbo_resource[0].GetMappedPointer(); advectParticles_k.GridDimensions = grid; advectParticles_k.BlockDimensions = tids; advectParticles_k.Run(p, v.DevicePointer, dx, dy, dt, TILEY / TIDSY, tPitch); cuda_vbo_resource.UnmapAllResources(); }
/// <summary> /// Setup as empty map with only one value at 1. /// </summary> /// <param name="pos"></param> /// <param name="fieldEnsemble"></param> /// <param name="startTime"></param> /// <param name="endTime"></param> public void SetupPoint(Int2 pos, int startTime) { // ~~~~~~~~~~~~~~ Copy relevant data ~~~~~~~~~~~~~~ \\ // Count up when advection was executed. CurrentTime = startTime; _startTime = startTime; // ~~~~~~~~~~~~ Load ensemble ~~~~~~~~~~~~ \\ // Load fields first to get the grid size. //Loader ncFile = new Loader(RedSea.Singleton.DataFolder + (_startTime + 1) + RedSea.Singleton.FileName); //ScalarField t0X = ncFile.LoadFieldSlice(_ensembleRanges[0]); //ScalarField t0Y = ncFile.LoadFieldSlice(_ensembleRanges[1]); //ncFile.Close(); LoaderNCF ncFile = RedSea.Singleton.GetLoaderNCF(_startTime); ScalarField t1X = ncFile.LoadFieldSlice(_ensembleRanges[0]); ScalarField t1Y = ncFile.LoadFieldSlice(_ensembleRanges[1]); ncFile.Close(); // ~~~~~~~~~~~~~~ Copy relevant data ~~~~~~~~~~~~~~ \\ // Keep for plane creation and size reference. _ensembleGrid = t1X.Grid as RectlinearGrid; // Mapper for binding the SlimDX texture to CUDA easily. _cudaDxMapper = new CudaGraphicsInteropResourceCollection(); // Tell CUDA which value is a border. _texInvalidValue = t1X.InvalidValue ?? float.MaxValue; // ~~~~~~~~~~~~ Fill CUDA resources ~~~~~~~~~~~~ \\ // All members are above each other. int vHeight = _height * _numMembers; //// vX, t=0 //_t0X = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One); //_t0X.CopyFromHostToThis<float>(t0X.Data); //new CudaTextureArray2D(_advectParticlesKernel, "vX_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0X); //// vY, t=0 //_t0Y = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One); //_t0Y.CopyFromHostToThis<float>(t0Y.Data); //new CudaTextureArray2D(_advectParticlesKernel, "vY_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0Y); // vX, t=1 _t1X = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One); _t1X.CopyFromHostToThis <float>(t1X.Data); new CudaTextureArray2D(_advectParticlesKernel, "vX_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1X); // vY, t=1 _t1Y = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One); _t1Y.CopyFromHostToThis <float>(t1Y.Data); new CudaTextureArray2D(_advectParticlesKernel, "vY_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1Y); // ~~~~~~~~~~~~~ Create texture ~~~~~~~~~~~~~~~~~~~~ \\ // Create texture. Completely zero, except for one point. Texture2DDescription desc = new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Format = Format.R32_Float, Width = _width, Height = _height, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; // Put field data into stream/rectangle object float[] zeros = new float[_width * _height]; Array.Clear(zeros, 0, zeros.Length); // Fill the empty texture. DataRectangle texData = new DataRectangle(_width * sizeof(float), new DataStream(zeros, true, true)); _pongFlowMap = new CudaDeviceVariable <float>(_width * _height);//new Texture2D(_device, desc, texData); // Magically, copy to device happens here. _pongFlowMap = zeros; // Add one pixel for integration. zeros[pos.X + pos.Y * _width] = 1; texData = new DataRectangle(_width * sizeof(float), new DataStream(zeros, true, true)); // Create texture. FlowMap = new Texture2D(_device, desc, texData); // ~~~~~~~~~ Make textures mappable to CUDA ~~~~~~~~~~ \\ _cudaDxMapper.Add(new CudaDirectXInteropResource(FlowMap.ComPointer, CUGraphicsRegisterFlags.None, CudaContext.DirectXVersion.D3D11)); _cudaDxMapper.MapAllResources(); CudaArray2D lastFlowMap = _cudaDxMapper[0].GetMappedArray2D(0, 0); new CudaTextureArray2D(_advectParticlesKernel, "flowMap", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, lastFlowMap); _cudaDxMapper.UnmapAllResources(); }
private void Image_MouseMove(object sender, MouseEventArgs e) { System.Windows.Point position = GetPositionWithDpi(e); int pX = (int)position.X; int pY = (int)position.Y; Point pixel = GetImagePixelFromMouseCoordinate(position); uchar4[] p = new uchar4[1]; if (!double.IsInfinity(pixel.X) && !double.IsInfinity(pixel.Y)) { d3dimage.Lock(); _graphicsres.MapAllResources(); CudaArray2D arr = _graphicsres[0].GetMappedArray2D(0, 0); CUDAMemCpy2D copy = new CUDAMemCpy2D(); GCHandle handle = GCHandle.Alloc(p, GCHandleType.Pinned); copy.dstHost = handle.AddrOfPinnedObject(); copy.srcArray = arr.CUArray; copy.srcMemoryType = CUMemoryType.Array; copy.dstMemoryType = CUMemoryType.Host; copy.Height = 1; copy.WidthInBytes = 4; copy.srcXInBytes = (int)pixel.X * 4; copy.srcY = (int)pixel.Y; arr.CopyData(copy); _graphicsres.UnmapAllResources(); arr.Dispose(); handle.Free(); d3dimage.Unlock(); } SetValue(ColorOfPixelProperty, Color.FromArgb(p[0].w, p[0].z, p[0].y, p[0].x)); SetValue(PixelCoordinateProperty, pixel); if (_clicked) { _viewShiftX += (-_lastX + pX) / _scaleFac * _projFac; _viewShiftY += (-_lastY + pY) / _scaleFac * _projFac; _lastX = pX; _lastY = pY; SlimDX.Matrix matScale = SlimDX.Matrix.Scaling(_scaleFac, _scaleFac, 1); float shiftScale = Math.Min((float)ActualWidthDpi, (float)ActualHeightDpi); SlimDX.Matrix matTrans = SlimDX.Matrix.Translation(_viewShiftX / shiftScale * _scaleFac, _viewShiftY / shiftScale * _scaleFac, 0); SlimDX.Matrix mat = matScale * matTrans; SlimDX.Matrix rotMat = new SlimDX.Matrix(); switch (_rotation) { case Rotation._0: rotMat = SlimDX.Matrix.RotationZ(0); break; case Rotation._90: rotMat = SlimDX.Matrix.RotationZ((float)(90.0 / 180.0 * Math.PI)); break; case Rotation._180: rotMat = SlimDX.Matrix.RotationZ((float)(180.0 / 180.0 * Math.PI)); break; case Rotation._270: rotMat = SlimDX.Matrix.RotationZ((float)(270.0 / 180.0 * Math.PI)); break; } _device.SetTransform(TransformState.View, rotMat * mat); updateFrame(); } }