Exemplo n.º 1
0
            private T InitRR <T>(T rr, MyMemoryBlock <float> targetMemBlock, MyMemoryBlock <float> targetDepthMemBlock, Action <T> initializer = null)
                where T : class, IRenderRequestBase
            {
                if (initializer != null)
                {
                    initializer.Invoke(rr);
                }

                rr.FlipYAxis = true;


                targetMemBlock.ExternalPointer = 0; // first reset ExternalPointer

                // Setup image copying from RR through Cpu
                if (Owner.CopyDataThroughCPU)
                {
                    ImageSettings imageSettings = new ImageSettings(RenderRequestImageCopyingMode.Cpu)
                    {
                        CopyDepth = Owner.CopyDepthData && targetDepthMemBlock != null,
                    };

                    imageSettings.OnSceneBufferPrepared += (request, data, depthData) =>
                    {
                        int width  = rr.Resolution.Width;
                        int stride = width * sizeof(uint);
                        int lines  = data.Length / width;

                        for (int i = 0; i < lines; ++i)
                        {
                            Buffer.BlockCopy(data, i * stride, targetMemBlock.Host, i * width * sizeof(uint), stride);
                        }

                        if (imageSettings.CopyDepth)
                        {
                            for (int i = 0; i < lines; ++i)
                            {
                                Buffer.BlockCopy(depthData, i * stride, targetDepthMemBlock.Host, i * width * sizeof(float), stride);
                            }
                        }

                        // targetMemBlock.SafeCopyToDevice(); this needs to be called on the BrainSim thread
                        // targetDepthMemBlock.SafeCopyToDevice(); this needs to be called on the BrainSim thread
                    };

                    rr.Image = imageSettings;
                    return(rr);
                }


                // Setup image copying from RR through Pbo
                ImageSettings image = new ImageSettings(RenderRequestImageCopyingMode.OpenglPbo)
                {
                    CopyDepth = Owner.CopyDepthData && targetDepthMemBlock != null,
                };

                // Setup data copying to our unmanaged memblocks
                uint renderTextureHandle      = 0;
                uint depthRenderTextureHandle = 0;
                CudaOpenGLBufferInteropResource renderResource      = null;
                CudaOpenGLBufferInteropResource depthRenderResource = null;

                image.OnPreRenderingEvent += (sender, vbo, depthVbo) =>
                {
                    if (renderResource != null && renderResource.IsMapped)
                    {
                        renderResource.UnMap();
                    }

                    if (image.CopyDepth)
                    {
                        if (depthRenderResource != null && depthRenderResource.IsMapped)
                        {
                            depthRenderResource.UnMap();
                        }
                    }
                };

                image.OnPostRenderingEvent += (sender, vbo, depthVbo) =>
                {
                    // Vbo can be allocated during drawing, create the resource after that (post-rendering)
                    MyKernelFactory.Instance.GetContextByGPU(Owner.GPU).SetCurrent();

                    // Fill color memblock
                    if (renderResource == null || vbo != renderTextureHandle)
                    {
                        if (renderResource != null)
                        {
                            renderResource.Dispose();
                        }

                        renderTextureHandle = vbo;
                        try
                        {
                            renderResource = new CudaOpenGLBufferInteropResource(renderTextureHandle,
                                                                                 image.CopyDepth ? CUGraphicsRegisterFlags.None : CUGraphicsRegisterFlags.ReadOnly); // Read only by CUDA
                        }
                        catch (Exception e)
                        {
                            MyLog.ERROR.WriteLine("calling CudaOpenGLBufferInteropResource returns " + e +
                                                  ". Go to World properties and in Runtime section set Copy data through CPU to True");
                            throw e;
                        }
                    }

                    renderResource.Map();
                    targetMemBlock.ExternalPointer = renderResource.GetMappedPointer <uint>().DevicePointer.Pointer;
                    targetMemBlock.FreeDevice();
                    targetMemBlock.AllocateDevice();

                    // Fill depth memblock
                    if (image.CopyDepth)
                    {
                        if (depthRenderResource == null || depthVbo != depthRenderTextureHandle)
                        {
                            if (depthRenderResource != null)
                            {
                                depthRenderResource.Dispose();
                            }

                            depthRenderTextureHandle = depthVbo;
                            depthRenderResource      = new CudaOpenGLBufferInteropResource(
                                depthRenderTextureHandle,
                                CUGraphicsRegisterFlags.ReadOnly); // Read only by CUDA
                        }

                        depthRenderResource.Map();
                        targetDepthMemBlock.ExternalPointer = depthRenderResource.GetMappedPointer <float>().DevicePointer.Pointer;
                        targetDepthMemBlock.FreeDevice();
                        targetDepthMemBlock.AllocateDevice();
                    }
                };

                rr.Image = image;


                // Initialize the target memory block
                // Use a dummy number that will get replaced on first Execute call to suppress MemBlock error during init
                targetMemBlock.ExternalPointer = 1;

                if (targetDepthMemBlock != null)
                {
                    targetDepthMemBlock.ExternalPointer = 1;
                }

                return(rr);
            }