using System; using System.Collections.Generic; namespace BizHawk.Bizware.BizwareGL { /// /// WARNING! PLEASE SET THIS PIPELINE CURRENT BEFORE SETTING UNIFORMS IN IT! NOT TOO GREAT, I KNOW. /// public class Pipeline : IDisposable { public string Memo; public Pipeline(IGL owner, object opaque, bool available, VertexLayout vertexLayout, IEnumerable uniforms, string memo) { Memo = memo; Owner = owner; Opaque = opaque; VertexLayout = vertexLayout; Available = available; //create the uniforms from the info list we got if(!Available) return; UniformsDictionary = new SpecialWorkingDictionary(this); foreach (var ui in uniforms) { UniformsDictionary[ui.Name] = new PipelineUniform(this); } foreach (var ui in uniforms) { UniformsDictionary[ui.Name].AddUniformInfo(ui); } } /// /// Allows us to create PipelineUniforms on the fly, in case a non-existing one has been requested. /// Shader compilers will optimize out unused uniforms, and we wont have a record of it in the uniforms population loop /// class SpecialWorkingDictionary : Dictionary { public SpecialWorkingDictionary(Pipeline owner) { Owner = owner; } Pipeline Owner; public new PipelineUniform this[string key] { get { if (!TryGetValue(key, out var temp)) { var ui = new UniformInfo {Opaque = null}; temp = this[key] = new PipelineUniform(null); } return temp; } internal set => base[key] = value; } } readonly SpecialWorkingDictionary UniformsDictionary; IDictionary Uniforms => UniformsDictionary; public IEnumerable GetUniforms() => Uniforms.Values; public PipelineUniform TryGetUniform(string name) { Uniforms.TryGetValue(name, out var ret); return ret; } public PipelineUniform this[string key] => UniformsDictionary[key]; public IGL Owner { get; } public object Opaque { get; } public VertexLayout VertexLayout { get; } public bool Available { get; } public string Errors { get; set; } public void Dispose() { Owner.FreePipeline(this); } } }