Esempio n. 1
0
        public override void Process()
        {
            Logger.Log(LogType.Log, $"Running CL Kernel: {Kernel.Name}", MIN_INSTRUCTION_SEVERITY);

            ArgumentResult[] results = new ArgumentResult[Arguments.Count];
            Logger.Log(LogType.Log,
                       $"[{Kernel.Name}]Computing Kernel Arguments", MIN_INSTRUCTION_SEVERITY);
            for (int i = 0; i < Arguments.Count; i++)
            {
                results[i] = Compute(Arguments[i]);
            }

            for (int i = 0; i < results.Length; i++)
            {
                Logger.Log(LogType.Log,
                           $"[{Kernel.Name}]Setting Kernel Argument {Kernel.Parameter.First(x => x.Value.Id == i)}",
                           MIN_INSTRUCTION_SEVERITY + 1);
                int kernelArgIndex = i + FL_HEADER_ARG_COUNT;

                ArgumentResult arg = results[i];

                switch (arg.Type)
                {
                case FLInstructionArgumentType.Number:
                    Kernel.SetArg(kernelArgIndex, arg.Value);     //The Value is a Decimal
                    break;

                case FLInstructionArgumentType.Buffer:
                    FLBuffer bi = (FLBuffer)arg.Value;
                    Logger.Log(LogType.Log, $"[{Kernel.Name}]Argument Buffer{bi.DefinedBufferName}",
                               MIN_INSTRUCTION_SEVERITY + 2);
                    Kernel.SetBuffer(kernelArgIndex, bi.Buffer);
                    break;

                case FLInstructionArgumentType.Function:
                    FLBuffer funcBuffer = (FLBuffer)arg.Value;
                    Logger.Log(LogType.Log, $"[{Kernel.Name}]Argument Buffer{funcBuffer.DefinedBufferName}",
                               MIN_INSTRUCTION_SEVERITY + 2);
                    Kernel.SetBuffer(kernelArgIndex, funcBuffer.Buffer);
                    break;

                default:
                    throw new InvalidOperationException("Can not parse: " + arg.Value);
                }
            }

            CLAPI.Run(Root.Instance, Kernel, Root.ActiveBuffer.Buffer, Root.Dimensions, GenMaxSize,
                      Root.ActiveChannelBuffer, 4);
        }
        protected override void Arrange(byte[] newOrder)
        {
            MemoryBuffer newOrderBuffer =
                CLAPI.CreateBuffer(Root.Instance, newOrder, MemoryFlag.ReadOnly, "gpuarrange_neworder");

            //Copy Active Buffer
            MemoryBuffer source = CLAPI.Copy <byte>(Root.Instance, Root.ActiveBuffer.Buffer);


            ArrangeKernel.SetBuffer(0, Root.ActiveBuffer.Buffer);
            ArrangeKernel.SetBuffer(1, source);
            ArrangeKernel.SetArg(2, Root.ActiveChannels.Length);
            ArrangeKernel.SetBuffer(3, newOrderBuffer);
            CLAPI.Run(
                Root.Instance,
                ArrangeKernel,
                (int)Root.ActiveBuffer.Size /
                Root.ActiveChannels
                .Length
                );      //Only iterating through the length as if it only has one channel. The cl kernel implementation will deal with that
            newOrderBuffer.Dispose();
            source.Dispose();
        }
Esempio n. 3
0
        private FLLineAnalysisResult AnalyzeLine(FLInstructionData data)
        {
            if (data.InstructionType != FLInstructionType.FlFunction &&
                data.InstructionType != FLInstructionType.ClKernel)
            {
                return(FLLineAnalysisResult.ParseError);
            }

            if (leaveStack) //This keeps the stack when returning from a "function"
            {
                leaveStack = false;
            }
            else
            {
                currentArgStack = new Stack <object>();
            }

            FLLineAnalysisResult ret = FLLineAnalysisResult.IncreasePc;

            for (;
                 currentWord < data.Arguments.Count;
                 currentWord++) //loop through the words. start value can be != 0 when returning from a function specified as an argument to a kernel
            {
                if (data.Arguments[currentWord].argType == FLArgumentType.Function)
                {
                    bool keepBuffer = data.InstructionType == FLInstructionType.FlFunction &&
                                      ((FLInterpreterFunctionInfo)data.Instruction).LeaveStack;
                    JumpTo((int)data.Arguments[currentWord].value, keepBuffer);
                    ret = FLLineAnalysisResult.Jump; //We Jumped to another point in the code.
                    currentArgStack
                    .Push(null);                     //Push null to signal the interpreter that he returned before assigning the right value.
                    break;
                }

                if (data.Arguments[currentWord].argType != FLArgumentType.Unknown)
                {
                    currentArgStack.Push(data.Arguments[currentWord].value);
                }
            }


            if (currentWord == data.Arguments.Count && ret != FLLineAnalysisResult.Jump)
            {
                if (data.InstructionType == FLInstructionType.FlFunction)
                {
                    ((FLInterpreterFunctionInfo)data.Instruction).Run();
                    return(FLLineAnalysisResult.IncreasePc);
                }

                CLKernel k = (CLKernel)data.Instruction;
                if (k == null || data.Arguments.Count != k.Parameter.Count - FL_HEADER_ARG_COUNT)
                {
                    throw new FLInvalidFunctionUseException(this.data.Source[currentIndex],
                                                            "Not the right amount of arguments.");
                }

                //Execute filter
                for (int i = k.Parameter.Count - 1; i >= FL_HEADER_ARG_COUNT; i--)
                {
                    object obj = currentArgStack.Pop(); //Get the arguments and set them to the kernel
                    if (obj is CLBufferInfo buf)        //Unpack the Buffer from the CLBuffer Object.
                    {
                        obj = buf.Buffer;
                    }

                    k.SetArg(i, obj);
                }

                Logger.Log(DebugChannel.Log | DebugChannel.OpenFL, Verbosity.Level8, "Running kernel: " + k.Name);
                CLAPI.Run(instance, k, currentBuffer.Buffer, new int3(width, height, depth),
                          KernelParameter.GetDataMaxSize(kernelDb.GenDataType), activeChannelBuffer,
                          channelCount); //Running the kernel
            }

            return(ret);
        }
Esempio n. 4
0
        private LineAnalysisResult AnalyzeLine(FLInstructionData data)
        {
            if (data.InstructionType != FLInstructionType.FLFunction && data.InstructionType != FLInstructionType.CLKernel)
            {
                Logger.Crash(new FLParseError(Data.Source[_currentIndex]), true);
                return(LineAnalysisResult.ParseError);
            }

            if (_leaveStack) //This keeps the stack when returning from a "function"
            {
                _leaveStack = false;
            }
            else
            {
                _currentArgStack = new Stack <object>();
            }

            LineAnalysisResult ret = LineAnalysisResult.IncreasePC;

            for (;
                 _currentWord < data.Arguments.Count;
                 _currentWord++) //loop through the words. start value can be != 0 when returning from a function specified as an argument to a kernel
            {
                if (data.Arguments[_currentWord].argType == FLArgumentType.Function)
                {
                    bool KeepBuffer = data.InstructionType == FLInstructionType.FLFunction && ((FLFunctionInfo)data.Instruction).LeaveStack;
                    JumpTo((int)data.Arguments[_currentWord].value, KeepBuffer);
                    ret = LineAnalysisResult.Jump; //We Jumped to another point in the code.
                    _currentArgStack
                    .Push(null);                   //Push null to signal the interpreter that he returned before assigning the right value.
                    break;
                }
                if (data.Arguments[_currentWord].argType != FLArgumentType.Unknown)
                {
                    _currentArgStack.Push(data.Arguments[_currentWord].value);
                }
            }


            if (_currentWord == data.Arguments.Count && ret != LineAnalysisResult.Jump)
            {
                if (data.InstructionType == FLInstructionType.FLFunction)
                {
                    ((FLFunctionInfo)data.Instruction).Run();
                    return(LineAnalysisResult.IncreasePC);
                }

                CLKernel K = (CLKernel)data.Instruction;
                if (K == null || data.Arguments.Count != K.Parameter.Count - FLHeaderArgCount)
                {
                    Logger.Crash(new FLInvalidFunctionUseException(Data.Source[_currentIndex], "Not the right amount of arguments."),
                                 true);
                    return(LineAnalysisResult.ParseError);
                }

                //Execute filter
                for (int i = K.Parameter.Count - 1; i >= FLHeaderArgCount; i--)
                {
                    object obj = _currentArgStack.Pop(); //Get the arguments and set them to the kernel
                    if (obj is CLBufferInfo buf)         //Unpack the Buffer from the CLBuffer Object.
                    {
                        obj = buf.Buffer;
                    }

                    K.SetArg(i, obj);
                }

                Logger.Log("Running kernel: " + K.Name, DebugChannel.Log | DebugChannel.OpenFL, 8);
                CLAPI.Run(K, _currentBuffer.Buffer, new int3(_width, _height, _depth),
                          KernelParameter.GetDataMaxSize(_kernelDb.GenDataType), _activeChannelBuffer,
                          _channelCount); //Running the kernel
            }
            return(ret);
        }
Esempio n. 5
0
        protected override void InitializeScene()
        {
            Add(DebugConsoleComponent.CreateConsole());
            Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView(
                MathHelper.DegreesToRadians(75f), //Field of View Vertical
                16f / 9f,                         //Aspect Ratio
                0.1f,                             //Near Plane
                1000f);                           //Far Plane

            BasicCamera bc = new BasicCamera(proj, Vector3.Zero);

            Add(bc);       //Adding the BasicCamera(That is a gameobject under the hood) to the scene to receive events
            SetCamera(bc); //Sets the Camera as the "active" camera that the scene will be rendered from.


            //Image size in bytes(Width * Height * ChannelCount)
            int imageSize = 512 * 512 * 4;

            //Creating a Kernel Database that will load all the Kernels contained in the asset directory
            KernelDatabase db = new KernelDatabase(CLAPI.MainThread, "assets/test_kernel/", DataVectorTypes.Uchar1);

            //We try to get the kernel_red from the file assets/test_kernel/red.cl
            db.TryGetClKernel("kernel_red", out CLKernel redKernel);

            //Creating a MemoryBuffer with size of the image.
            //We are using the CLAPI instance of the main thread and specify that we`d like to read/write from the buffer
            MemoryBuffer imageBuffer = CLAPI.CreateEmpty <byte>(CLAPI.MainThread, imageSize, MemoryFlag.ReadWrite,
                                                                "CLMemoryBufferForBox");

            //With plain OpenCL you would need to Set the Arguments/Buffers by their argument index/types/size/yada yads,
            //thanks to the CL abstraction for the engine, we can just specify the argument name how we do in OpenGL Shaders(But Faster).
            redKernel.SetBuffer("imageData", imageBuffer);

            //Set Arg has the capabilities to automatically cast the value that is passed to the right type,
            //however this is not really fast and can be avoided by specifying the correct type directly.
            redKernel.SetArg("strength", 0.5f); //We directly pass a float, no casting required

            //When We pass something as byte(uchar in cl), we need to cast it.
            //If we dont the Engine OpenCL Wrapper will automatically convert the integer into a byte, but it will apply rescaling
            //  This takes over automatic type conversion from float(opengl) to byte(System.Bitmap/opencl)
            //  Calculation when not passed: (4 / Int32.MaxSize) * byte.MaxValue.
            redKernel.SetArg("channelCount", (byte)4);

            //This Line runs the kernel.
            CLAPI.Run(CLAPI.MainThread, redKernel, imageSize);

            //After the kernel ran, we can read the buffer we have passed to the kernel and Convert it into a OpenGL Texture.
            Texture tex = TextureLoader.BytesToTexture(CLAPI.ReadBuffer <byte>(CLAPI.MainThread, imageBuffer, imageSize),
                                                       512, 512, "BoxTexture");


            GameObject box = new GameObject(-Vector3.UnitZ * 4, "Box");  //Creating a new Empty GameObject
            LitMeshRendererComponent lmr = new LitMeshRendererComponent( //Creating a Renderer Component
                DefaultFilepaths.DefaultLitShader,                       //The OpenGL Shader used(Unlit and Lit shaders are provided)
                Prefabs.Cube,                                            //The Mesh that is going to be used by the MeshRenderer
                tex,                                                     //Diffuse Texture to put on the mesh
                1);                                                      //Render Mask (UI = 1 << 30)

            box.AddComponent(lmr);                                       //Attaching the Renderer to the GameObject
            box.AddComponent(new RotateSelfComponent());                 //Adding a component that rotates the Object on the Y-Axis
            Add(box);                                                    //Adding the Object to the Scene.
        }