Пример #1
0
        static void InitBundle(MyMaterialShadersBundleId id)
        {
            Debug.Assert(m_vertexTemplateBase != null);
            Debug.Assert(m_pixelTemplateBase != null);

            var info = BundleInfo.Data[id.Index];

            PrefetchMaterialSources(info.Material);
            PrefetchPassSources(info.Pass);

            // vertex shader

            StringBuilder source = new StringBuilder();

            source.Append(MyRender11.GlobalShaderHeader);
            AddMaterialShaderFlagMacros(source, info.Flags);
            source.Append(m_vertexTemplateBase);
            source.Replace("__VERTEXINPUT_DECLARATIONS__",
                           info.Layout.Info.SourceDeclarations);
            source.Replace("__VERTEXINPUT_TRANSFER__",
                           info.Layout.Info.SourceDataMove);
            source.Replace("__MATERIAL_DECLARATIONS__",
                           MaterialSources[info.Material].Declarations);
            source.Replace("__MATERIAL_VERTEXPROGRAM__",
                           MaterialSources[info.Material].VertexShaderSource);
            source.AppendLine();
            source.AppendLine(MaterialPassSources[info.Pass].VertexStageTemplate);

            var vsName = String.Format("[{0}][{1}]_{2}_{3}", info.Pass.ToString(), info.Material.ToString(), "vs", info.Flags);

            var vsSource = source.ToString();

            source.Clear();

            // pixel shader

            source.Append(MyRender11.GlobalShaderHeader);
            AddMaterialShaderFlagMacros(source, info.Flags);
            source.Append(m_pixelTemplateBase);
            source.Replace("__MATERIAL_DECLARATIONS__", MaterialSources[info.Material].Declarations);
            source.Replace("__MATERIAL_PIXELPROGRAM__", MaterialSources[info.Material].PixelShaderSource);
            source.AppendLine();
            source.AppendLine(MaterialPassSources[info.Pass].PixelStageTemplate);


            var psName   = String.Format("[{0}][{1}]_{2}_{3}", info.Pass.ToString(), info.Material.ToString(), "ps", info.Flags);
            var psSource = source.ToString();


            var vsBytecode = MyShaders.Compile(vsSource, "__vertex_shader", "vs_5_0", vsName, false);
            var psBytecode = MyShaders.Compile(psSource, "__pixel_shader", "ps_5_0", psName, false);


            // input layous

            bool canChangeBundle = vsBytecode != null && psBytecode != null;

            if (canChangeBundle)
            {
                if (Bundles[id.Index].IL != null)
                {
                    Bundles[id.Index].IL.Dispose();
                    Bundles[id.Index].IL = null;
                }
                if (Bundles[id.Index].VS != null)
                {
                    Bundles[id.Index].VS.Dispose();
                    Bundles[id.Index].VS = null;
                }
                if (Bundles[id.Index].PS != null)
                {
                    Bundles[id.Index].PS.Dispose();
                    Bundles[id.Index].PS = null;
                }

                try
                {
                    Bundles[id.Index].VS = new VertexShader(MyRender11.Device, vsBytecode);
                    Bundles[id.Index].PS = new PixelShader(MyRender11.Device, psBytecode);
                    Bundles[id.Index].IL = info.Layout.Elements.Length > 0 ? new InputLayout(MyRender11.Device, vsBytecode, info.Layout.Elements) : null;
                }
                catch (SharpDXException e)
                {
                    vsBytecode = MyShaders.Compile(vsSource, "__vertex_shader", "vs_5_0", vsName, true);
                    psBytecode = MyShaders.Compile(psSource, "__pixel_shader", "ps_5_0", psName, true);

                    Bundles[id.Index].VS = new VertexShader(MyRender11.Device, vsBytecode);
                    Bundles[id.Index].PS = new PixelShader(MyRender11.Device, psBytecode);
                    Bundles[id.Index].IL = info.Layout.Elements.Length > 0 ? new InputLayout(MyRender11.Device, vsBytecode, info.Layout.Elements) : null;
                }
            }
            else if (Bundles[id.Index].VS == null && Bundles[id.Index].PS == null)
            {
                MyRender11.Log.WriteLine("Failed to compile material shader" + info.Name + " for vertex " + String.Join(", ", info.Layout.Info.Components.Select(x => x.ToString())));
                throw new MyRenderException("Failed to compile material shader" + info.Name, MyRenderExceptionEnum.Unassigned);
            }
        }
Пример #2
0
        static void InitBundle(MyMaterialShadersBundleId id, bool invalidateCache = false)
        {
            var info = BundleInfo.Data[id.Index];

            string vsSource;
            string psSource;
            var    macroList = GenerateMaterialShaderFlagMacros(info.Flags);

            for (int i = 0; i < MyRender11.GlobalShaderMacro.Length; i++)
            {
                macroList.Add(MyRender11.GlobalShaderMacro[i]);
            }
            ShaderMacro[] macros = macroList.ToArray();

            ProfilerShort.Begin("MyShaders.MaterialCompile");

            Preprocess(info.Material, info.Pass, info.Layout.Info, out vsSource, out psSource);

            var descriptor = String.Format("{0}_{1}_{2}", info.Material.ToString(), info.Pass.ToString(), info.Layout.Info.Components.GetString());

            byte[] vsBytecode = MyShaders.Compile(vsSource, macros, MyShadersDefines.Profiles.vs_5_0, descriptor, invalidateCache);
            byte[] psBytecode = MyShaders.Compile(psSource, macros, MyShadersDefines.Profiles.ps_5_0, descriptor, invalidateCache);

            ProfilerShort.End();

            // input layous
            bool canChangeBundle = vsBytecode != null && psBytecode != null;

            if (canChangeBundle)
            {
                if (Bundles[id.Index].IL != null)
                {
                    Bundles[id.Index].IL.Dispose();
                    Bundles[id.Index].IL = null;
                }
                if (Bundles[id.Index].VS != null)
                {
                    Bundles[id.Index].VS.Dispose();
                    Bundles[id.Index].VS = null;
                }
                if (Bundles[id.Index].PS != null)
                {
                    Bundles[id.Index].PS.Dispose();
                    Bundles[id.Index].PS = null;
                }

                try
                {
                    Bundles[id.Index].VS           = new VertexShader(MyRender11.Device, vsBytecode);
                    Bundles[id.Index].VS.DebugName = descriptor;
                    Bundles[id.Index].PS           = new PixelShader(MyRender11.Device, psBytecode);
                    Bundles[id.Index].PS.DebugName = descriptor;
                    Bundles[id.Index].IL           = info.Layout.Elements.Length > 0 ? new InputLayout(MyRender11.Device, vsBytecode, info.Layout.Elements) : null;
                }
                catch (SharpDXException e)
                {
                    if (!invalidateCache)
                    {
                        InitBundle(id, true);
                        return;
                    }
                    string message = "Failed to initialize material shader" + info.Name + " for vertex " + info.Layout.Info.Components.GetString();
                    MyRender11.Log.WriteLine(message);
                    throw new MyRenderException(message, MyRenderExceptionEnum.Unassigned);
                }
            }
            else //if (Bundles[id.Index].VS == null && Bundles[id.Index].PS == null)
            {
                string message = "Failed to compile material shader" + info.Name + " for vertex " + info.Layout.Info.Components.GetString();
                MyRender11.Log.WriteLine(message);
#if DEBUG
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                    ClearSources();
                    InitBundle(id, invalidateCache);
                }
#else
                if (Bundles[id.Index].VS == null && Bundles[id.Index].PS == null)
                {
                    throw new MyRenderException(message, MyRenderExceptionEnum.Unassigned);
                }
#endif
            }
        }
        static void InitBundle(MyMaterialShadersBundleId id, bool invalidateCache = false)
        {
            var info = BundleInfo.Data[id.Index];

            var macroList = new List <ShaderMacro>();

            macroList.Add(GetRenderingPassMacro(info.Pass.String));
            AddMaterialShaderFlagMacrosTo(macroList, info.Flags, info.TextureTypes);
            macroList.AddRange(info.Layout.Info.Macros);

            ProfilerShort.Begin("MyShaders.MaterialCompile");

            MyMaterialShaderInfo sources;

            GetMaterialSources(info.Material, out sources);

            ShaderMacro[] macros = macroList.ToArray();

            string vsDescriptor = GetShaderDescriptor(sources.VertexShaderFilename, info.Material.String, info.Pass.String, info.Layout);

            byte[] vsBytecode = MyShaders.Compile(sources.VertexShaderFilepath, macros, MyShaderProfile.vs_5_0, vsDescriptor, invalidateCache);

            string psDescriptor = GetShaderDescriptor(sources.PixelShaderFilename, info.Material.String, info.Pass.String, info.Layout);

            byte[] psBytecode = MyShaders.Compile(sources.PixelShaderFilepath, macros, MyShaderProfile.ps_5_0, psDescriptor, invalidateCache);

            ProfilerShort.End();

            // input layous
            bool canChangeBundle = vsBytecode != null && psBytecode != null;

            if (canChangeBundle)
            {
                if (Bundles[id.Index].IL != null)
                {
                    Bundles[id.Index].IL.Dispose();
                    Bundles[id.Index].IL = null;
                }
                if (Bundles[id.Index].VS != null)
                {
                    Bundles[id.Index].VS.Dispose();
                    Bundles[id.Index].VS = null;
                }
                if (Bundles[id.Index].PS != null)
                {
                    Bundles[id.Index].PS.Dispose();
                    Bundles[id.Index].PS = null;
                }

                try
                {
                    Bundles[id.Index].VS           = new VertexShader(MyRender11.Device, vsBytecode);
                    Bundles[id.Index].VS.DebugName = vsDescriptor;
                    Bundles[id.Index].PS           = new PixelShader(MyRender11.Device, psBytecode);
                    Bundles[id.Index].PS.DebugName = psDescriptor;
                    Bundles[id.Index].IL           = info.Layout.Elements.Length > 0 ? new InputLayout(MyRender11.Device, vsBytecode, info.Layout.Elements) : null;
                }
                catch (SharpDXException e)
                {
                    if (!invalidateCache)
                    {
                        InitBundle(id, true);
                        return;
                    }
                    string message = "Failed to initialize material shader" + info.Name + " for vertex " + info.Layout.Info.Components.GetString();
                    MyRender11.Log.WriteLine(message);
                    throw new MyRenderException(message, MyRenderExceptionEnum.Unassigned);
                }
            }
            else //if (Bundles[id.Index].VS == null && Bundles[id.Index].PS == null)
            {
                string message = "Failed to compile material shader" + info.Name + " for vertex " + info.Layout.Info.Components.GetString();
                MyRender11.Log.WriteLine(message);
#if DEBUG
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                    ClearSources();
                    InitBundle(id, invalidateCache);
                }
#else
                if (Bundles[id.Index].VS == null && Bundles[id.Index].PS == null)
                {
                    throw new MyRenderException(message, MyRenderExceptionEnum.Unassigned);
                }
#endif
            }
        }