public void Render(ComputeMemory buffer, ComputeCommandQueue queue) { if (_doingScreenshot || _kernels == null) { return; } if (VideoRenderer.CheckForVideo(this)) { return; } CoreRender(buffer, queue, _kernels, new Vector4((Vector3)_input.Camera.Position), new Vector4((Vector3)_input.Camera.Lookat), new Vector4((Vector3)_input.Camera.Up), _input.Camera.Frame, _input.Camera.Fov, 1, _input.Camera.FocalDistance, _width, _height, _globalSize, _localSize); _input.Frame++; if (_input.CheckForScreenshot()) { _doingScreenshot = true; ThreadPool.QueueUserWorkItem(o => { Screenshot(); _doingScreenshot = false; }); } if (_input.CheckForGif()) { _doingScreenshot = true; ThreadPool.QueueUserWorkItem(o => { GifRenderer.RenderGif(this); _doingScreenshot = false; }); } }
private static void CoreRender(ComputeMemory buffer, ComputeCommandQueue queue, IEnumerable <ComputeKernel> kernels, Vector4 position, Vector4 lookat, Vector4 up, int frame, float fov, int slowRenderCount, float focalDistance, int width, int height, long[] globalSize, long[] localSize) { foreach (var kernel in kernels) { kernel.SetMemoryArgument(0, buffer); kernel.SetValueArgument(1, width); kernel.SetValueArgument(2, height); kernel.SetValueArgument(3, position); kernel.SetValueArgument(4, lookat); kernel.SetValueArgument(5, up); kernel.SetValueArgument(6, frame); kernel.SetValueArgument(7, fov); kernel.SetValueArgument(8, slowRenderCount); kernel.SetValueArgument(9, focalDistance); queue.Execute(kernel, LaunchSize, globalSize, localSize, null); } }
void Setargument(ComputeKernel kernel, int index, object arg) { if (arg == null) { throw new ArgumentException("Argument " + index + " is null"); } Type argtype = arg.GetType(); if (argtype.IsArray) { ComputeMemory messageBuffer = (ComputeMemory)Activator.CreateInstance(typeof(ComputeBuffer <>).MakeGenericType(argtype.GetElementType()), new object[] { context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.UseHostPointer, arg }); kernel.SetMemoryArgument(index, messageBuffer); // set the array } else { try { typeof(ComputeKernel).GetMethod("SetValueArgument").MakeGenericMethod(argtype).Invoke(kernel, new object[] { index, arg }); } catch (Exception) { try { kernel.SetValueArgument(index, Convert.ToByte(arg)); } catch (Exception) { try { kernel.SetValueArgument(index, Convert.ToSingle(arg)); } catch (Exception) { kernel.SetValueArgument(index, Convert.ToDouble(arg)); } } } } }
void DestroyClBuffers() { if (clImage != null) { clImage.Dispose(); clImage = null; } if (result != null) { result.Dispose(); result = null; } if (cmap != null) { cmap.Dispose(); cmap = null; } if (clCommands != null) { clCommands.Dispose(); clCommands = null; } if (clKernel != null) { clKernel.Dispose(); clKernel = null; } if (clProgram != null) { clProgram.Dispose(); clProgram = null; } clDirty = true; }
/// <summary> /// Sets a <c>T*</c>, <c>image2d_t</c> or <c>image3d_t</c> argument of the kernel. /// </summary> /// <param name="index"> The argument index. </param> /// <param name="memObj"> The memory that is passed as the argument. </param> /// <remarks> This method will automatically track <paramref name="memObj"/> to prevent it from being collected by the GC.<br/> Arguments to the kernel are referred by indices that go from 0 for the leftmost argument to n-1, where n is the total number of arguments declared by the kernel. </remarks> public void SetMemoryArgument(int index, ComputeMemory memObj) { SetValueArgument <CLMemoryHandle>(index, memObj.Handle); }
/// <summary> /// Prepare OpenCL program, data buffers, etc. /// </summary> public void PrepareClBuffers(bool dirty = true) { clDirty = clDirty || dirty; if (texName == 0 || !checkOpenCL.Checked) { DestroyClBuffers(); return; } if (!clDirty) { return; } DestroyClBuffers(); if (clContext == null) { SetupClContext(); } if (clContext == null) // to be sure { Util.Log("OpenCL error"); clImage = null; clDirty = true; return; } GL.BindTexture(TextureTarget.Texture2D, 0); GL.Finish(); try { // OpenCL C source: string src = ClInfo.ReadSourceFile(CanUseDouble ? "mandel.cl" : "mandelSingle.cl", "090opencl"); if (string.IsNullOrEmpty(src)) { return; } // program & kernel: clProgram = new ComputeProgram(clContext, src); clProgram.Build(clContext.Devices, null, null, IntPtr.Zero); clKernel = clProgram.CreateKernel((checkDouble.Checked && CanUseDouble) ? "mandelDouble" : "mandelSingle"); clCommands = new ComputeCommandQueue(clContext, clContext.Devices[0], ComputeCommandQueueFlags.None); globalWidth = (texWidth + groupSize - 1) & -groupSize; globalHeight = (texHeight + groupSize - 1) & -groupSize; // buffers: // 1. colormap array cmap = new ComputeBuffer <byte>(clContext, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, colormap); bool interopOk = checkInterop.Checked; if (interopOk) { // 2. CL image for OpenGL interop clImage = ComputeImage2D.CreateFromGLTexture2D(clContext, ComputeMemoryFlags.ReadWrite, (int)TextureTarget.Texture2D, 0, texName); if (clImage == null) { Util.Log("OpenCL cannot reference OpenGL texture!"); interopOk = false; } } // 3. CL output array result = new ComputeBuffer <byte>(clContext, ComputeMemoryFlags.ReadWrite, texWidth * texHeight * 4); // synced.. clDirty = false; } catch (Exception exc) { Util.LogFormat("OpenCL build error: {0}", exc.Message); clImage = null; clDirty = true; } }
public void setMemoryArgument(int k, int index, ComputeMemory memObj) { _kernels[k].SetMemoryArgument(index, memObj); }