Beispiel #1
0
        //[/GenericReduceSPUK]

        ///[genericReduceScalarProdUse]
        public T Apply(T[] values1, T[] values2)
        {
            var n         = values1.Length;
            var numSm     = GPUWorker.Device.Attributes.MULTIPROCESSOR_COUNT;
            var tup       = _plan.BlockRanges(numSm, n);
            var ranges    = tup.Item1;
            var numRanges = tup.Item2;
            var lpUpsweep = new LaunchParam(numRanges, _plan.NumThreads);
            var lpReduce  = new LaunchParam(1, _plan.NumThreadsReduction);

            using (var dRanges = GPUWorker.Malloc(ranges))
                using (var dRangeTotals = GPUWorker.Malloc <T>(numRanges))
                    using (var dValues1 = GPUWorker.Malloc(values1))
                        using (var dValues2 = GPUWorker.Malloc(values2))
                        {
                            // Launch range reduction kernel to calculate the totals per range.
                            GPUWorker.EvalAction(
                                () =>
                            {
                                GPULaunch(Upsweep, lpUpsweep, dValues1.Ptr, dValues2.Ptr, dRanges.Ptr, dRangeTotals.Ptr);
                                if (numRanges > 1)
                                {
                                    // Need to aggregate the block sums as well.
                                    GPULaunch(_reduce.ReduceRangeTotals, lpReduce, numRanges, dRangeTotals.Ptr);
                                }
                            });
                            return(dRangeTotals.Gather()[0]);
                        }
        }
Beispiel #2
0
        //[/cuRANDComputeValue]

        //[cuRANDPiEstimator]
        public double RunEstimation(int numSims, int threadBlockSize)
        {
            // Aim to launch around ten or more times as many blocks as there
            // are multiprocessors on the target device.
            const int blocksPerSm = 10;
            var       numSMs      = GPUWorker.Device.Attributes.MULTIPROCESSOR_COUNT;

            // Determine how to divide the work between cores
            var block = new dim3(threadBlockSize);
            var grid  = new dim3((numSims + threadBlockSize - 1) / threadBlockSize);

            while (grid.x > 2 * blocksPerSm * numSims)
            {
                grid.x >>= 1;
            }

            var n = 2 * numSims;

            using (var dPoints = GPUWorker.Malloc <double>(n))
                using (var dResults = GPUWorker.Malloc <double>(grid.x))
                {
                    // Generate random points in unit square
                    var curand = new CURAND(GPUWorker, CURANDInterop.curandRngType.CURAND_RNG_QUASI_SOBOL64);
                    curand.SetQuasiRandomGeneratorDimensions(2);
                    curand.SetGeneratorOrdering(CURANDInterop.curandOrdering.CURAND_ORDERING_QUASI_DEFAULT);
                    curand.GenerateUniformDouble(dPoints.Ptr, new IntPtr(n));

                    var lp = new LaunchParam(grid, block, block.x * sizeof(uint));
                    GPULaunch(ComputeValue, lp, dResults.Ptr, dPoints.Ptr, numSims);
                    var value = dResults.Gather().Sum();
                    return((value / numSims) * 4.0);
                }
        }
Beispiel #3
0
        //[/GenericScanDownsweepKernel]

        public T[] Apply(T[] input, bool inclusive)
        {
            var n         = input.Length;
            var numSm     = GPUWorker.Device.Attributes.MULTIPROCESSOR_COUNT;
            var tup       = Plan.BlockRanges(numSm, n);
            var ranges    = tup.Item1;
            var numRanges = tup.Item2;


            var lpUpsweep   = new LaunchParam(numRanges, Plan.NumThreads);
            var lpReduce    = new LaunchParam(1, Plan.NumThreadsReduction);
            var lpDownsweep = new LaunchParam(numRanges, Plan.NumThreads);
            var _inclusive  = inclusive ? 1 : 0;

            using (var dRanges = GPUWorker.Malloc(ranges))
                using (var dRangeTotals = GPUWorker.Malloc <T>(numRanges + 1))
                    using (var dInput = GPUWorker.Malloc(input))
                        using (var dOutput = GPUWorker.Malloc(input))
                        {
                            _reduceModule.Upsweep(lpUpsweep, dInput.Ptr, dRanges.Ptr, dRangeTotals.Ptr);
                            GPULaunch(ScanReduce, lpReduce, numRanges, dRangeTotals.Ptr);
                            GPULaunch(Downsweep, lpDownsweep, dInput.Ptr, dOutput.Ptr, dRangeTotals.Ptr, dRanges.Ptr, _inclusive);
                            return(dOutput.Gather());
                        }
        }
Beispiel #4
0
 public T[] Apply(T[] x)
 {
     using (var dx = GPUWorker.Malloc(x))
         using (var dy = GPUWorker.Malloc <T>(x.Length))
         {
             Apply(x.Length, dx.Ptr, dy.Ptr);
             return(dy.Gather());
         }
 }
    public void Test()
    {
        const int n  = 32;
        var       lp = new LaunchParam(1, n);

        using (var outputs = GPUWorker.Malloc <int>(n))
        {
            this.MyGPULaunch(Kernel, lp, outputs.Ptr, 1, 3);
            Console.WriteLine("{0}", (outputs.Gather())[4]);
        }
    }
        /// <summary>
        /// Create Soft Font, Soft Font Material, Soft Font Texture from SoftEffect Settings,
        /// </summary>
        /// <param name="font"></param>
        public override void AdjustTextureOnLine()
        {
            if (!eShader || eShader == null)
            {
                FindComputeShader();
            }
            if (!eShader || eShader == null)
            {
                return;
            }

            if (!SoftFont || !SoftFont.material)
            {
                if (SoftEffects.debuglog)
                {
                    Debug.LogError("SoftFont is missing. Create SoftFont bevore.");
                }
                return;
            }

            if (!faceOptions.mainTexture || faceOptions.mainTexture == null)
            {
                if (SoftEffects.debuglog)
                {
                    Debug.LogError("Edit texture is missing. Create or rebuild.");
                }
                return;
            }

            if (cb == null)
            {
                cb = new CBuffers();
            }
            if (gpuWorker == null)
            {
                gpuWorker = new GPUWorker(eShader);
            }

            RenderNewTextures(gpuWorker, false);

            //2 Set new gpu rendered texture to font
            GetComponent <Text>().material = null;
            GetComponent <Text>().material = SoftFont.material;
        }
 void ISimulatorTester.Integrate(float4[] pos, float4[] vel, int numBodies, float deltaTime,
                                 float softeningSquared, float damping, int steps)
 {
     using (var dpos0 = GPUWorker.Malloc <float4>(numBodies))
         using (var dpos1 = GPUWorker.Malloc(pos))
             using (var dvel = GPUWorker.Malloc(vel))
             {
                 var pos0 = dpos0.Ptr;
                 var pos1 = dpos1.Ptr;
                 for (var i = 0; i < steps; i++)
                 {
                     var tempPos = pos0;
                     pos0 = pos1;
                     pos1 = tempPos;
                     IntegrateNbodySystem(pos1, pos0, dvel.Ptr, numBodies, deltaTime, softeningSquared, damping);
                 }
                 GPUWorker.Gather(pos1, pos, FSharpOption <int> .None, FSharpOption <int> .None);
                 GPUWorker.Gather(dvel.Ptr, vel, FSharpOption <int> .None, FSharpOption <int> .None);
             }
 }
        public void Profile(int sizeX, int sizeY, Func <int, T[]> generateTestData)
        {
            if (sizeX % TileDim != 0 || sizeY % TileDim != 0 || sizeX != sizeY)
            {
                throw new Exception("matrix sizeX and sizeY must be equal and a multiple of tile dimension");
            }

            var size = sizeX * sizeY;
            var A    = generateTestData(size);

            using (var dA = GPUWorker.Malloc(A))
                using (var dAt = GPUWorker.Malloc <T>(size))
                {
                    GPUWorker.ProfilerStart();

                    Copy(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                    TransposeNaive(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                    TransposeCoalesced(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                    TransposeNoBankConflicts(sizeX, sizeY, dA.Ptr, dAt.Ptr);

                    GPUWorker.Synchronize();
                    GPUWorker.ProfilerStop();
                }
        }
        public void MeasurePerformance(int nIter, int sizeX, int sizeY, Func <int, T[]> generateTestData,
                                       Action <T[], T[]> validate)
        {
            if (sizeX % TileDim != 0 || sizeY % TileDim != 0 || sizeX != sizeY)
            {
                throw new Exception("matrix sizeX and sizeY must be equal and a multiple of tile dimension");
            }

            Console.WriteLine("Matrix Transpose Using CUDA - starting...");
            Console.WriteLine("GPU Device {0}: {1} with compute capability {2}.{3}\n",
                              GPUWorker.Device.ID, GPUWorker.Device.Name,
                              GPUWorker.Device.Arch.Major, GPUWorker.Device.Arch.Minor);
            Console.WriteLine("Matrix({0},{1})\n", sizeY, sizeX);

            var size    = sizeX * sizeY;
            var esize   = typeof(T) == typeof(double) ? 8 : 4; //sizeof<T> (T); // Bugbug Fix this
            var memSize = esize * size;
            var A       = generateTestData(size);
            var At      = Transpose(sizeX, sizeY, A);

            using (var dA = GPUWorker.Malloc(A))
                using (var dAt = GPUWorker.Malloc <T>(size))
                {
                    // warm up and validate
                    Copy(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                    TransposeNaive(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                    validate(dAt.Gather(), At);
                    TransposeCoalesced(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                    validate(dAt.Gather(), At);
                    TransposeNoBankConflicts(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                    validate(dAt.Gather(), At);

                    using (var startEvent = GPUWorker.CreateEvent())
                        using (var stopEvent = GPUWorker.CreateEvent())
                        {
                            double time;
                            startEvent.Record();
                            for (var i = 0; i < nIter; i++)
                            {
                                Copy(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                            }
                            stopEvent.Record();
                            stopEvent.Synchronize();
                            time = Event.ElapsedMilliseconds(startEvent, stopEvent) / nIter;
                            Console.WriteLine(
                                "copy\nthroughput = {0} Gb/s\nkernel time = {1} ms\nnum elements = {2}\nelement size = {3}\n",
                                MemoryBandwidth(memSize, time), time, (memSize / esize), esize);

                            startEvent.Record();
                            for (var i = 0; i < nIter; i++)
                            {
                                TransposeNaive(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                            }
                            stopEvent.Record();
                            stopEvent.Synchronize();
                            time = Event.ElapsedMilliseconds(startEvent, stopEvent) / nIter;
                            Console.WriteLine(
                                "naive transpose\nthroughput = {0} Gb/s\nkernel time = {1} ms\nnum elements = {2}\nelement size = {3}\n",
                                MemoryBandwidth(memSize, time), time, (memSize / esize), esize);

                            startEvent.Record();
                            for (var i = 0; i < nIter; i++)
                            {
                                TransposeCoalesced(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                            }
                            stopEvent.Record();
                            stopEvent.Synchronize();
                            time = Event.ElapsedMilliseconds(startEvent, stopEvent) / nIter;
                            Console.WriteLine(
                                "coalesced transpose\nthroughput = {0} Gb/s\nkernel time = {1} ms\nnum elements = {2}\nelement size = {3}\n",
                                MemoryBandwidth(memSize, time), time, (memSize / esize), esize);

                            startEvent.Record();
                            for (var i = 0; i < nIter; i++)
                            {
                                TransposeNoBankConflicts(sizeX, sizeY, dA.Ptr, dAt.Ptr);
                            }
                            stopEvent.Record();
                            stopEvent.Synchronize();
                            time = Event.ElapsedMilliseconds(startEvent, stopEvent) / nIter;
                            Console.WriteLine(
                                "coalesced no bank conflict transpose\nthroughput = {0} Gb/s\nkernel time = {1} ms\nnum elements = {2}\nelement size = {3}\n",
                                MemoryBandwidth(memSize, time), time, (memSize / esize), esize);
                        }
                }
        }
        /// <summary>
        /// Create Soft Font, Soft Font Material, Soft Font Texture from SoftEffect Settings,
        /// </summary>
        /// <param name="font"></param>
        private void CreateSoftFont(Font font, bool createNewFolder) // http://answers.unity3d.com/questions/485695/truetypefontimportergenerateeditablefont-does-not.html
        {
            //  Mkey.Utils.Measure("<<<<<<<<<<<<Summary CreateSoftFontTexture>>>>>>>>>>>>>>>: ", () => {
            gpuWorker = new GPUWorker(eShader);
            string dirPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(font));

            //1) load source font asset
            string path = AssetDatabase.GetAssetPath(font);
            Font   f    = font;

            if (SoftEffects.debuglog)
            {
                Debug.Log("Path to Source font: " + path);
            }

            font = (Font)AssetDatabase.LoadMainAssetAtPath(path);
            if (f && !font)
            {
                Debug.LogError("Can't use embedded font : " + f.name);
                return;
            }

            //2) Remove old Editable font
            if (SoftFont && !createNewFolder)
            {
                if (SoftEffects.debuglog)
                {
                    Debug.Log("EditableFont folder: " + Path.GetDirectoryName(AssetDatabase.GetAssetPath(SoftFont)));
                }
                if (SoftEffects.debuglog)
                {
                    Debug.Log("Remove old EditableFont: " + SoftFont.name);
                }
                if (SoftFont.material)
                {
                    AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(SoftFont.material.mainTexture));
                    AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(SoftFont.material));
                }
                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(SoftFont));
                AssetDatabase.Refresh();
            }

            //3) reimport source font as editable
            TrueTypeFontImporter fontImporter = AssetImporter.GetAtPath(path) as TrueTypeFontImporter;

            //source settings
            int sourceSize    = fontImporter.fontSize;
            int sourcePadding = fontImporter.characterPadding;
            int sourceSpacing = fontImporter.characterSpacing;

            FontTextureCase sourceCase = fontImporter.fontTextureCase;
            string          chars      = fontImporter.customCharacters;

            fontImporter.fontSize         = GetComponent <Text>().fontSize;
            fontImporter.characterPadding = Mathf.Clamp(faceOptions.extPixels, 1, 100);
            fontImporter.characterSpacing = 0;

            // Mkey.Utils.Measure("Summary PreCreateFontTexture: ", () =>  {
            //     Mkey.Utils.Measure("Reimport font: ", () => {
            if (SoftFontTextureCase == FontTextureCase.CustomSet)
            {
                if (customCharacters.Length == 0 || customCharacters == " ")
                {
                    Debug.LogError("Custom Characters string is empty. Set default string.");
                    customCharacters = GetComponent <Text>().text;
                    if (customCharacters.Length == 0 || customCharacters == " ")
                    {
                        customCharacters = "New txt";
                    }
                }
                fontImporter.customCharacters = customCharacters;
            }
            else if (SoftFontTextureCase == FontTextureCase.Dynamic)
            {
                SoftFontTextureCase = FontTextureCase.ASCII;
            }
            fontImporter.fontTextureCase = SoftFontTextureCase;
            fontImporter.SaveAndReimport();
            // });

            //  Mkey.Utils.Measure("GenerateEditableFont: ", () =>  {
            SoftFont = fontImporter.GenerateEditableFont(path);
            // });
            int maxSize = Mathf.Max(font.material.mainTexture.width, font.material.mainTexture.height);

            // Mkey.Utils.Measure("RenameAsset: ", () =>    {
            AssetDatabase.RenameAsset(AssetDatabase.GetAssetPath(SoftFont), font.name + key);
            AssetDatabase.RenameAsset(AssetDatabase.GetAssetPath(SoftFont.material), font.name + key + "_edit");
            AssetDatabase.RenameAsset(AssetDatabase.GetAssetPath(SoftFont.material.mainTexture), font.name + key);
            AssetDatabase.Refresh();
            //  });

            Shader softShader = Shader.Find("SoftEffects/SoftEditShader");

            SoftFont.material.shader = softShader;
            SoftMaterial             = SoftFont.material;

            if (SoftEffects.debuglog)
            {
                Debug.Log("Editable texture size: " + SoftFont.material.mainTexture.width + " x " + SoftFont.material.mainTexture.height);
            }
            // Mkey.Utils.Measure("Reimport texture: ", () =>  {
            //5) Reimport EditableFont texture as readable
            SoftFont.material.mainTexture.ReimportTexture(true, maxSize);
            if (SoftEffects.debuglog)
            {
                Debug.Log("Editable texture size after reimport: " + SoftFont.material.mainTexture.width + " x " + SoftFont.material.mainTexture.height);
            }
            // });

            // });

            //5) Generate new Texture for editable font
            // Mkey.Utils.Measure("faceOptions.RenderFontTexture: ", () =>  {
            faceOptions.RenderFontTexture(gpuWorker, SoftFont, cb);
            //});

            // Mkey.Utils.Measure("AfterCreateFontTexture: ", () =>  {
            faceOptions.CreateTextureFromRender_ARGB32(true, dirPath + "/" + font.name + key + "_edit" + ".png");

            AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(SoftFont.material.mainTexture));                           //  Remove old texture

            Texture2D t = (Texture2D)AssetDatabase.LoadMainAssetAtPath(dirPath + "/" + font.name + key + "_edit" + ".png"); // load new texture asset

            t.ReimportTexture(true);

            //6 extend verts and uvs
            // SoftFont.ExtendVertsAndUvs(faceOptions.extPixels);
            faceOptions.mainTexture = t;

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();


            // 9) remove editable font to unique folder
            string targetFolder = AssetDatabase.GUIDToAssetPath(FolderGUID);
            string fontPath     = AssetDatabase.GetAssetPath(SoftFont);
            string materialPath = AssetDatabase.GetAssetPath(SoftFont.material);
            string texturePath  = AssetDatabase.GetAssetPath(t);

            if (SoftEffects.debuglog)
            {
                Debug.Log("Move file: " + fontPath + " to : " + targetFolder + "/" + Path.GetFileName(fontPath));
            }
            AssetDatabase.MoveAsset(fontPath, targetFolder + "/" + Path.GetFileName(fontPath));// FileUtil.MoveFileOrDirectory(fontPath, targetFolder + "/"+  Path.GetFileName(fontPath));
            AssetDatabase.MoveAsset(materialPath, targetFolder + "/" + Path.GetFileName(materialPath));
            AssetDatabase.MoveAsset(texturePath, targetFolder + "/" + Path.GetFileName(texturePath));

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            faceOptions.IsCombinedDirty = true;
            RenderNewTextures(gpuWorker, true);
            /**/
            EditorGUIUtility.PingObject(SoftFont);
            EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());

            //revert source settings
            fontImporter                 = AssetImporter.GetAtPath(path) as TrueTypeFontImporter;
            fontImporter.fontSize        = sourceSize;
            fontImporter.fontTextureCase = sourceCase;
            // fontImporter.characterPadding = sourcePadding;
            // fontImporter.characterSpacing = sourceSpacing;

            fontImporter.characterPadding = 1;
            fontImporter.characterSpacing = 0;

            if (sourceCase == FontTextureCase.CustomSet)
            {
                fontImporter.customCharacters = chars;
            }
            fontImporter.SaveAndReimport();
            // });
            // });
        }
Beispiel #11
0
        internal void RenderNewTextures(GPUWorker gpuWorker, bool rebuild)
        {
            //  Mkey.Utils.Measure("RenderNewTextures measure: ", ()=>  {
            //0a) Create close shadow
            if (closeShadowOptions.use && (closeShadowOptions.IsDirty || rebuild || closeShadowOptions.NeedRebuild))
            {
                closeShadowOptions.RenderTexture_AR8(gpuWorker, faceOptions.mainTexture);
            }
            else
            {
                if (debuglog)
                {
                    Debug.Log("Close Shadow texture not need rendering");
                }
                closeShadowOptions.IsDirty = false;
            }

            //1a) Create close shadow
            if (closeShadowOptions_1.use && (closeShadowOptions_1.IsDirty || rebuild || closeShadowOptions_1.NeedRebuild))
            {
                closeShadowOptions_1.RenderTexture_AR8(gpuWorker, faceOptions.mainTexture);
            }
            else
            {
                if (debuglog)
                {
                    Debug.Log("Close Shadow(1) texture not need rendering");
                }
                closeShadowOptions_1.IsDirty = false;
            }

            //2a) Create blured texture
            if (shadowOptions.use && (shadowOptions.IsDirty || rebuild || shadowOptions.NeedRebuild))
            {
                shadowOptions.RenderTexture_AR8(gpuWorker, faceOptions.mainTexture);
            }
            else
            {
                if (debuglog)
                {
                    Debug.Log("Shadow texture not need rendering");
                }
                shadowOptions.IsDirty = false;
            }

            //b) Create antialiazed stroke texture from buffer
            if (strokeOptions.use && (strokeOptions.IsDirty || rebuild || strokeOptions.NeedRebuild))
            {
                strokeOptions.RenderTextureFromAAFEDTBuffer_AR8(gpuWorker, faceOptions.mainTexture, cb, rebuild);
            }
            else
            {
                if (SoftEffects.debuglog)
                {
                    Debug.Log("Stroke texture not need rendering");
                }
                strokeOptions.IsDirty = false;
            }

            //c) Create outer glow  dist map texture
            if (outerGlowOptions.use && (outerGlowOptions.IsDirty || rebuild || outerGlowOptions.NeedRebuild))
            {
                outerGlowOptions.RenderTextureFromAAFEDT_AR8(gpuWorker, faceOptions.mainTexture, cb, rebuild);
            }
            else
            {
                if (SoftEffects.debuglog)
                {
                    Debug.Log("Outer Glow texture not need rendering");
                }
                outerGlowOptions.IsDirty = false;
            }

            //d) Create bevel texture
            if (bevelOptions.use && (bevelOptions.IsDirty || rebuild || bevelOptions.NeedRebuild))
            {
                bevelOptions.RenderTexture(gpuWorker, faceOptions.mainTexture, cb, rebuild);
            }
            else
            {
                if (SoftEffects.debuglog)
                {
                    Debug.Log("Bevel texture not need rendering");
                }
                bevelOptions.IsDirty = false;
            }

            //e) Create inner glow  dist map texture
            if (innerGlowOptions.use && (innerGlowOptions.IsDirty || rebuild || innerGlowOptions.NeedRebuild))
            {
                innerGlowOptions.RenderTextureFromAAFEDT_AR8(gpuWorker, faceOptions.mainTexture, cb, rebuild);
            }
            else
            {
                if (SoftEffects.debuglog)
                {
                    Debug.Log("Inner Glow texture not need rendering");
                }
                innerGlowOptions.IsDirty = false;
            }

            //f) Create inner shadow
            if (innerShadowOptions.use && (innerShadowOptions.IsDirty || rebuild || innerShadowOptions.NeedRebuild))
            {
                innerShadowOptions.RenderTextureFromAAFEDT_AR8(gpuWorker, faceOptions.mainTexture, cb, rebuild);
            }
            else
            {
                if (SoftEffects.debuglog)
                {
                    Debug.Log("Inner Shadow texture not need rendering");
                }
                innerShadowOptions.IsDirty = false;
            }

            //g) Create face gradient
            if (faceGradientOptions.use && (faceGradientOptions.IsDirty || rebuild || faceGradientOptions.NeedRebuild))
            {
                faceGradientOptions.RenderTextureFromAAFEDTBuffer_AR8(gpuWorker, faceOptions.mainTexture, cb, rebuild);
            }
            else
            {
                if (SoftEffects.debuglog)
                {
                    Debug.Log("Face gradient texture not need rendering");
                }
                faceGradientOptions.IsDirty = false;
            }

            faceOptions.SetCloseShadowOptions(closeShadowOptions);
            faceOptions.SetCloseShadowOptions_1(closeShadowOptions_1);
            faceOptions.SetOuterGlowOptions(outerGlowOptions, cb);
            faceOptions.SetStrokeOptions(strokeOptions, cb);
            faceOptions.SetInnerGlowOptions(innerGlowOptions, cb);
            faceOptions.SetBevelOptions(bevelOptions);
            faceOptions.SetInnerShadowOptions(innerShadowOptions);
            faceOptions.SetFaceGradientOptions(faceGradientOptions, cb);
            faceOptions.SetFaceOptions();


            if (faceOptions.IsCombinedDirty)
            {
                //  Mkey.Utils.Measure("Render full face texture", () =>  {
                faceOptions.RenderCombineTexture(gpuWorker, cb);
                // });
            }
            else
            {
                if (SoftEffects.debuglog)
                {
                    Debug.Log("Face  not need rendering");
                }
            }

            // });// end measure

            SetShadowMaterialPoperty();
        }