예제 #1
0
        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();
        }
예제 #2
0
파일: Form1.cs 프로젝트: xiaotie/DNCCuda
        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);
            }
        }
예제 #3
0
파일: Form1.cs 프로젝트: xiaotie/DNCCuda
        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();
        }
예제 #4
0
        /// <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();
            }
        }