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); } }
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 } }