예제 #1
0
        public async System.Threading.Tasks.Task <bool> Init(CRenderContext rc)
        {
            if (CEngine.Instance.MaterialManager.DefaultMaterial == null ||
                CEngine.Instance.ShadingEnvManager.DefaultShadingEnv == null)
            {
                return(false);
            }
            var desc = CGfxEffectDesc.CreateDesc(CEngine.Instance.MaterialManager.DefaultMaterial,
                                                 new Mesh.CGfxMdfQueue(),
                                                 CEngine.Instance.ShadingEnvManager.DefaultShadingEnv.EnvCode);

            mDefaultEffect = GetEffect(rc, desc);
            await mDefaultEffect.AwaitLoad();

            if (mDefaultEffect.CacheData.CBID_View == UInt32.MaxValue)
            {
                Profiler.Log.WriteLine(Profiler.ELogTag.Fatal, "Shader", $"DefaultEffect({desc.EnvShaderPatch.ShaderName}) CBID_View is invalid");
                return(false);
            }
            if (mDefaultEffect.CacheData.CBID_Camera == UInt32.MaxValue)
            {
                Profiler.Log.WriteLine(Profiler.ELogTag.Fatal, "Shader", $"DefaultEffect({desc.EnvShaderPatch.ShaderName}) CBID_Camera is invalid");
                return(false);
            }
            return(true);
        }
예제 #2
0
 public CGfxEffect GetEffect(CRenderContext rc, CGfxEffectDesc desc)
 {
     lock (Effects)
     {
         CGfxEffect result;
         var        saved = desc.String;
         var        hash  = desc.GetHash64();
         if (Effects.TryGetValue(hash, out result) == true)
         {
             if (hash != result.Desc.GetHash64())
             {
                 Effects.Remove(hash);
                 hash          = result.Desc.GetHash64();
                 Effects[hash] = result;
                 //System.Diagnostics.Debug.Assert(false);
             }
             return(result);
         }
         else
         {
             result = new CGfxEffect(desc);
             result.PreUse();
             Effects.Add(desc.GetHash64(), result);
             return(result);
         }
     }
 }
예제 #3
0
        private static void CollectShaderInfoImpl(CGfxEffectDesc desc, int index)
        {
            var cloneDesc = desc.CloneEffectDesc();
            GfxEnvShaderCode shadingEnv = cloneDesc.EnvShaderPatch;

            if (index >= shadingEnv.MacroDefines.Count)
            {
                return;
            }

            for (int i = index; i < shadingEnv.MacroDefines.Count; i++)
            {
                var values = shadingEnv.GetMacroValues(shadingEnv.MacroDefines[i].Name);
                if (values == null)
                {
                    continue;
                }
                for (int j = 0; j < values.Count; j++)
                {
                    if (shadingEnv.SetMacroDefineValue(i, values[j]))
                    {
                        cloneDesc.UpdateHash64(true);
                        Hash64 hash;
                        hash = cloneDesc.GetHash64();
                        var file = CGfxEffectDesc.GetShaderInfoFileName(hash);
                        if (CEngine.Instance.FileManager.FileExists(file) == false)
                        {
                            cloneDesc.SaveXML(null, hash);
                        }

                        CollectShaderInfoImpl(cloneDesc, i + 1);
                    }
                }
            }
        }
예제 #4
0
        public static void CollectShaderInfo(CGfxEffectDesc desc)
        {
            if (desc.EnvShaderPatch.GetMacroValues == null)
            {
                return;
            }

            CollectShaderInfoImpl(desc, 0);
        }
예제 #5
0
        public CGfxEffectDesc CloneEffectDesc()
        {
            CGfxEffectDesc result = new CGfxEffectDesc();

            result.MtlShaderPatch      = MtlShaderPatch;
            result.MdfQueueShaderPatch = MdfQueueShaderPatch.CloneMdfQueue(CEngine.Instance.RenderContext, null);
            result.EnvShaderPatch      = EnvShaderPatch.CloneEnvShaderCode();
            result.UpdateHash64(true);
            return(result);
        }
예제 #6
0
        public static CGfxEffectDesc CreateDesc(CGfxMaterial mtl, Mesh.CGfxMdfQueue mdf, GfxEnvShaderCode shadingenv)
        {
            CGfxEffectDesc result = new CGfxEffectDesc();

            result.MtlShaderPatch      = mtl;
            result.MdfQueueShaderPatch = mdf.CloneMdfQueue(CEngine.Instance.RenderContext, null);
            result.EnvShaderPatch      = shadingenv;
            //result.EnvShaderPatch = shadingenv.CloneShadingEnv();
            result.UpdateHash64(true);
            return(result);
        }
예제 #7
0
        public static async System.Threading.Tasks.Task BuildCachesWhenCleaned(CRenderContext rc)
        {
            var sm         = CRenderContext.ShaderModelString;
            var shaderPath = CEngine.Instance.FileManager.DDCDirectory + sm + "/";
            var shaders    = CEngine.Instance.FileManager.GetFiles(shaderPath, "*.shader");

            if (shaders != null && shaders.Count > 0)
            {
                return;
            }
            var t1 = Support.Time.HighPrecision_GetTickCount();

            Profiler.Log.WriteLine(Profiler.ELogTag.Info, "BuildShaderCache", "Begin Shader Cache");
            var path  = CEngine.Instance.FileManager.DDCDirectory + "shaderinfo";
            var files = CEngine.Instance.FileManager.GetFiles(path, "*.xml");
            var descs = new List <CGfxEffectDesc>(files.Count);

            foreach (var i in files)
            {
                using (var xml = IO.XmlHolder.LoadXML(i))
                {
                    CGfxEffectDesc desc = await CGfxEffectDesc.LoadEffectDescFromXml(rc, xml.RootNode);

                    if (desc != null && desc.MdfQueueShaderPatch != null)
                    {
                        descs.Add(desc);
                    }
                }
            }

            if (MultiThreadCompile == false)
            {
                foreach (var i in descs)
                {
                    CGfxEffect effect = new CGfxEffect(i);
                    if (effect.CreateEffectByD11Editor(rc, i, EPlatformType.PLATFORM_WIN))
                    {
                        CEngine.Instance.EffectManager.RegEffect(i.GetHash64(), effect);
                    }
                }
            }
            else
            {
                var DescNum = new Thread.ThreadSafeNumber(descs.Count);
                await CEngine.Instance.EventPoster.AwaitMTS_Foreach(descs.Count, (idx, smp) =>
                {
                    var remain        = DescNum.Release();
                    CGfxEffect effect = new CGfxEffect(descs[idx]);
                    if (effect.CreateEffectByD11Editor(rc, descs[idx], EPlatformType.PLATFORM_WIN))
                    {
                        Profiler.Log.WriteLine(Profiler.ELogTag.Info, "BuildShaderCache", $"CacheShader = {descs[idx].GetHash64()}; Remain = {remain}");
                        CEngine.Instance.EffectManager.RegEffect(descs[idx].GetHash64(), effect);
                    }
                    else
                    {
                        Profiler.Log.WriteLine(Profiler.ELogTag.Info, "BuildShaderCache", $"CacheShader Failed = {descs[idx].GetHash64()}; Remain = {remain}");
                    }
                });
            }
            var t2 = Support.Time.HighPrecision_GetTickCount();

            Profiler.Log.WriteLine(Profiler.ELogTag.Info, "BuildShaderCache", $"End Shader Cache, Times = {(t2 - t1) / 1000} ms");
            System.GC.Collect();
        }
예제 #8
0
        public static async System.Threading.Tasks.Task <CGfxEffectDesc> LoadEffectDescFromXml(CRenderContext rc, IO.XmlNode node, bool testHash = true)
        {
            var result = new CGfxEffectDesc();

            if (node == null)
            {
                return(result);
            }
            RName.enRNameType rNameType = RName.enRNameType.Game;
            var attr = node.FindAttrib("Material_RNameType");

            if (attr != null)
            {
                rNameType = (RName.enRNameType)System.Convert.ToInt32(attr.Value);
            }
            attr = node.FindAttrib("Material");
            if (attr != null)
            {
                result.MtlShaderPatch = await CEngine.Instance.MaterialManager.GetMaterialAsync(rc, RName.GetRName(attr.Value, rNameType));

                if (result.MtlShaderPatch == null)
                {
                    return(null);
                }
            }

            attr = node.FindAttrib("ShadingEnv");
            string shadingEnvName = null;

            if (attr != null)
            {
                result.mEnvShaderPatch = new Graphics.GfxEnvShaderCode();
                shadingEnvName         = attr.Value;

                var attr1 = node.FindAttrib("ShadingEnvType");
                if (attr1 != null)
                {
                    var envType = Rtti.RttiHelper.GetTypeFromSaveString(attr1.Value);
                    var envTemp = Rtti.RttiHelper.CreateInstance(envType) as CGfxShadingEnv;
                    if (envTemp != null)
                    {
                        envTemp.InitCodeOnce(result.mEnvShaderPatch);
                    }
                }
                var LoadDefs = new List <CShaderDefinitions.MacroDefine>();
                var defs     = node.FindNode("EnvMacro");
                if (defs != null)
                {
                    var macroAttrs = defs.GetAttribs();
                    for (int i = 0; i < macroAttrs.Count; i++)
                    {
                        result.mEnvShaderPatch.SetMacroDefineValue(macroAttrs[i].Name, macroAttrs[i].Value);
                    }
                }
            }

            result.MdfQueueShaderPatch = new Mesh.CGfxMdfQueue();
            var mdf = node.FindNode("MdfQueue").GetNodes();

            foreach (var i in mdf)
            {
                var type = Rtti.RttiHelper.GetTypeFromSaveString(i.Name);
                var om   = System.Activator.CreateInstance(type) as EngineNS.Graphics.Mesh.CGfxModifier;
                if (om == null)
                {
                    continue;
                }
                result.MdfQueueShaderPatch.AddModifier(om);
            }
            result.UpdateMacroArray();
            result.UpdateHash64(false);

            if (testHash)
            {
                attr = node.FindAttrib("HLSLHashCode");
                if (attr != null)
                {
                    result.HLSLHashCode = attr.Value;
                    var hlslDesc = CEngine.Instance.FileManager.HLSLFileDescManager.FindFileDesc(RName.GetRName(shadingEnvName, RName.enRNameType.Engine).Address);
                    if (hlslDesc != null && hlslDesc.HashWithDepends.ToString() != result.HLSLHashCode)
                    {
                        Profiler.Log.WriteLine(Profiler.ELogTag.Warning, "Shaders", $"effect {shadingEnvName} need recompile");
                        return(null);
                    }
                }
            }
            return(result);
        }
예제 #9
0
 public CGfxEffect(CGfxEffectDesc desc)
 {
     mDesc = desc;
 }