internal MyVertexInputLayout Append(MyVertexInputComponentType type, int slot = 0, MyVertexInputComponentFreq freq = MyVertexInputComponentFreq.PER_VERTEX) { MyVertexInputComponent component = new MyVertexInputComponent(); component.Type = type; component.Slot = slot; component.Freq = freq; int nextHash = MyHashHelper.Combine(m_hash, component.GetHashCode()); MyVertexInputLayout next; if (m_cached.TryGetValue(nextHash, out next)) { return(next); } next = new MyVertexInputLayout(); next.m_hash = nextHash; next.m_id = m_cached.Count; next.m_components = m_components.Concat(component.Yield()).ToArray(); next.Build(); m_cached[nextHash] = next; return(next); }
internal static MyMaterialShadersBundleId Get(MyStringId material, MyStringId materialPass, VertexLayoutId vertexLayout, MyShaderUnifiedFlags flags) { int hash = 0; MyHashHelper.Combine(ref hash, material.GetHashCode()); MyHashHelper.Combine(ref hash, materialPass.GetHashCode()); MyHashHelper.Combine(ref hash, vertexLayout.GetHashCode()); MyHashHelper.Combine(ref hash, unchecked ((int)flags)); if (HashIndex.ContainsKey(hash)) { return(HashIndex[hash]); } var id = new MyMaterialShadersBundleId { Index = BundleInfo.Allocate() }; MyArrayHelpers.Reserve(ref Bundles, id.Index + 1); HashIndex[hash] = id; BundleInfo.Data[id.Index] = new MyMaterialShadersInfo { Material = material, Pass = materialPass, Layout = vertexLayout, Flags = flags }; Bundles[id.Index] = new MyMaterialShadersBundle { }; InitBundle(id); return(id); }
internal static MyMaterialProxy Create(MyMaterialDescription?desc, string materialTag) { int key = desc.HasValue ? desc.Value.CalculateKey() : 0; key = MyHashHelper.Combine(key, materialTag.GetHashCode()); var proxy = m_proxies.SetDefault(key, null); if (proxy != null) { return(proxy); } proxy = MyShaderMaterialReflection.CreateBindings(materialTag); if (desc == null) { // TODO: change later desc = MyAssetMesh.GetDebugMaterialDescriptor(); } LoadTextures(proxy, desc.Value); proxy.RecalcConstantsHash(); m_proxies[key] = proxy; m_descriptors[key] = desc.Value; m_reverseMapping[proxy] = desc.Value; return(proxy); }
static MyMaterialProxy_2 CreateProxyWithPlaceholderdMaterialConstants(MyVoxelMaterialTriple triple) { var version = triple.I0.GetHashCode(); MyHashHelper.Combine(ref version, triple.I1.GetHashCode()); MyHashHelper.Combine(ref version, triple.I2.GetHashCode()); MySrvTable srvTable = new MySrvTable { BindFlag = MyBindFlag.BIND_PS, StartSlot = 0, Version = version, Srvs = new ISrvBindable[] { MyGlobalResources.FileArrayTextureVoxelCM, MyGlobalResources.FileArrayTextureVoxelNG, MyGlobalResources.FileArrayTextureVoxelExt, } }; return(new MyMaterialProxy_2 { MaterialConstants = new MyConstantsPack(), MaterialSrvs = srvTable }); }
internal void RecalcTexturesHash() { TexturesHash = 0; foreach (var t in SRVs) { TexturesHash = MyHashHelper.Combine(TexturesHash, t != null ? t.GetHashCode() : 0); } }
internal static int CalculateRK(ref MyMeshMaterialInfo desc) { var key = desc.ColorMetal_Texture.GetHashCode(); MyHashHelper.Combine(ref key, desc.NormalGloss_Texture.GetHashCode()); MyHashHelper.Combine(ref key, desc.Extensions_Texture.GetHashCode()); MyHashHelper.Combine(ref key, desc.Alphamask_Texture.GetHashCode()); MyHashHelper.Combine(ref key, desc.Technique.GetHashCode()); MyHashHelper.Combine(ref key, desc.Name.GetHashCode()); return(key); }
internal void RecalcConstantsHash() { ConstantsHash = 0; // kind of lame to iterate over bytes if (Constants == null) { return; } foreach (var b in Constants) { ConstantsHash = MyHashHelper.Combine(ConstantsHash, b.GetHashCode()); } }
internal int CalculateMergeHash() { var key = TextureColorMetalPath.GetHashCode(); MyHashHelper.Combine(ref key, TextureNormalGlossPath.GetHashCode()); MyHashHelper.Combine(ref key, TextureAmbientOcclusionPath.GetHashCode()); if (TextureAlphamaskPath != null) { MyHashHelper.Combine(ref key, TextureAlphamaskPath.GetHashCode()); } return(key); }
internal static VertexLayoutId GetLayout(params MyVertexInputComponent[] components) { if (components == null || components.Length == 0) { return(Empty); } var hash = 0; foreach (var c in components) { MyHashHelper.Combine(ref hash, c.GetHashCode()); } if (HashIndex.ContainsKey(hash)) { return(HashIndex[hash]); } var id = new VertexLayoutId { Index = Layouts.Allocate() }; HashIndex[hash] = id; var declarationBuilder = new StringBuilder(); var sourceBuilder = new StringBuilder(); var semanticDict = new Dictionary <string, int>(); // Might save some allocations when each AddComponent only adds one element as then we can use GetInternalArray and Capacity set does nothing var elementsList = new List <InputElement>(components.Length); foreach (var component in components) { MyVertexInputLayout.m_mapComponent[component.Type].AddComponent(component, elementsList, semanticDict, declarationBuilder, sourceBuilder); } elementsList.Capacity = elementsList.Count; Debug.Assert(elementsList.Count == elementsList.Capacity); Layouts.Data[id.Index] = new MyVertexLayoutInfo { Components = components, Elements = elementsList.GetInternalArray(), SourceDataMove = sourceBuilder.ToString(), SourceDeclarations = new StringBuilder().AppendFormat("struct __VertexInput {{ \n {0} \n }};", declarationBuilder.ToString()).ToString(), HasBonesInfo = components.Any(x => x.Type == MyVertexInputComponentType.BLEND_INDICES) }; return(id); }
static unsafe MyMaterialProxy_2 CreateProxy(MyVoxelMaterialTriple triple) { byte[] buffer; int size; System.Diagnostics.Debug.Assert(triple.I0 < Table.Length, "Index to table incorrect"); System.Diagnostics.Debug.Assert(triple.I1 < Table.Length, "Index to table incorrect"); System.Diagnostics.Debug.Assert(triple.I2 < Table.Length, "Index to table incorrect"); //TODO: This shouldnt happen if Table is created correctly if (triple.I0 >= Table.Length) { triple.I0 = 0; } if (triple.I1 >= Table.Length) { triple.I1 = -1; } if (triple.I2 >= Table.Length) { triple.I2 = -1; } //////end of hack bool singleMaterial = triple.I1 == -1 && triple.I2 == -1; if (singleMaterial) { size = sizeof(MyVoxelMaterialConstants); MyVoxelMaterialConstants constantsData = new MyVoxelMaterialConstants(); constantsData.DistancesAndScale = Table[triple.I0].DistanceAndScale; constantsData.DistancesAndScaleFar = Table[triple.I0].DistanceAndScaleFar; constantsData.DistancesAndScaleFar3 = Table[triple.I0].DistanceAndScaleFar3; constantsData.Far3Color = Table[triple.I0].Far3Color; constantsData.ExtensionDetailScale = Table[triple.I0].ExtensionDetailScale; buffer = new byte[size]; fixed(byte *dstPtr = buffer) { MyMemory.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), (uint)size); } } else { size = sizeof(MyVoxelMultiMaterialConstants); MyVoxelMultiMaterialConstants constantsData = new MyVoxelMultiMaterialConstants(); constantsData.DistancesAndScale0 = Table[triple.I0].DistanceAndScale; constantsData.DistancesAndScale1 = Table[triple.I1].DistanceAndScale; constantsData.DistancesAndScale2 = triple.I2 >= 0 ? Table[triple.I2].DistanceAndScale : Vector4.Zero; constantsData.DistancesAndScaleFar0 = Table[triple.I0].DistanceAndScaleFar; constantsData.DistancesAndScaleFar1 = Table[triple.I1].DistanceAndScaleFar; constantsData.DistancesAndScaleFar2 = triple.I2 >= 0 ? Table[triple.I2].DistanceAndScaleFar : Vector4.Zero; constantsData.DistancesAndScaleFar31 = new Vector4(Table[triple.I0].DistanceAndScaleFar3.X, Table[triple.I0].DistanceAndScaleFar3.Y, 0, 0); constantsData.DistancesAndScaleFar32 = new Vector4(Table[triple.I1].DistanceAndScaleFar3.X, Table[triple.I1].DistanceAndScaleFar3.Y, 0, 0); constantsData.DistancesAndScaleFar33 = triple.I2 >= 0 ? new Vector4(Table[triple.I2].DistanceAndScaleFar3.X, Table[triple.I2].DistanceAndScaleFar3.Y, 0, 0) : Vector4.Zero; constantsData.Far3Color1 = Table[triple.I0].Far3Color.ToVector4(); constantsData.Far3Color2 = Table[triple.I1].Far3Color.ToVector4(); constantsData.Far3Color3 = triple.I2 >= 0 ? Table[triple.I2].Far3Color.ToVector4() : Vector4.Zero; constantsData.ExtensionDetailScale0 = Table[triple.I0].ExtensionDetailScale; constantsData.ExtensionDetailScale1 = Table[triple.I1].ExtensionDetailScale; constantsData.ExtensionDetailScale2 = triple.I2 >= 0 ? Table[triple.I2].ExtensionDetailScale : 0; buffer = new byte[size]; fixed(byte *dstPtr = buffer) { MyMemory.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), (uint)size); } } var version = triple.I0.GetHashCode(); MyHashHelper.Combine(ref version, triple.I1.GetHashCode()); MyHashHelper.Combine(ref version, triple.I2.GetHashCode()); return(new MyMaterialProxy_2 { MaterialConstants = { BindFlag = MyBindFlag.BIND_PS, CB = MyCommon.GetMaterialCB(size), Version = version, Data = buffer }, MaterialSRVs = { // NOTE(AF) Adding BIND_VS here will interfere with shadows, causing flickering in the first cascade BindFlag = MyBindFlag.BIND_PS, StartSlot = 0, Version = version, SRVs = singleMaterial ? new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, Table[triple.I0].Near.ExtArray.ShaderView, Table[triple.I0].Far1.ExtArray.ShaderView, Table[triple.I0].Far2.ExtArray.ShaderView, } : ( triple.I2 == -1 ? new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I1].Near.ColorMetalArray.ShaderView, Table[triple.I1].Far1.ColorMetalArray.ShaderView, Table[triple.I1].Far2.ColorMetalArray.ShaderView, null, null, null, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, Table[triple.I1].Near.NormalGlossArray.ShaderView, Table[triple.I1].Far1.NormalGlossArray.ShaderView, Table[triple.I1].Far2.NormalGlossArray.ShaderView, null, null, null, Table[triple.I0].Near.ExtArray.ShaderView, Table[triple.I0].Far1.ExtArray.ShaderView, Table[triple.I0].Far2.ExtArray.ShaderView, Table[triple.I1].Near.ExtArray.ShaderView, Table[triple.I1].Far1.ExtArray.ShaderView, Table[triple.I1].Far2.ExtArray.ShaderView, null, null, null } : new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I1].Near.ColorMetalArray.ShaderView, Table[triple.I1].Far1.ColorMetalArray.ShaderView, Table[triple.I1].Far2.ColorMetalArray.ShaderView, Table[triple.I2].Near.ColorMetalArray.ShaderView, Table[triple.I2].Far1.ColorMetalArray.ShaderView, Table[triple.I2].Far2.ColorMetalArray.ShaderView, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, Table[triple.I1].Near.NormalGlossArray.ShaderView, Table[triple.I1].Far1.NormalGlossArray.ShaderView, Table[triple.I1].Far2.NormalGlossArray.ShaderView, Table[triple.I2].Near.NormalGlossArray.ShaderView, Table[triple.I2].Far1.NormalGlossArray.ShaderView, Table[triple.I2].Far2.NormalGlossArray.ShaderView, Table[triple.I0].Near.ExtArray.ShaderView, Table[triple.I0].Far1.ExtArray.ShaderView, Table[triple.I0].Far2.ExtArray.ShaderView, Table[triple.I1].Near.ExtArray.ShaderView, Table[triple.I1].Far1.ExtArray.ShaderView, Table[triple.I1].Far2.ExtArray.ShaderView, Table[triple.I2].Near.ExtArray.ShaderView, Table[triple.I2].Far1.ExtArray.ShaderView, Table[triple.I2].Far2.ExtArray.ShaderView, } ) } }); }
static unsafe MyMaterialProxy_2 CreateProxy(MyVoxelMaterialTriple triple) { byte[] buffer; int size; bool singleMaterial = triple.I1 == -1 && triple.I2 == -1; if (singleMaterial) { size = sizeof(MyVoxelMaterialConstants); MyVoxelMaterialConstants constantsData = new MyVoxelMaterialConstants(); constantsData.Scales = Table[triple.I0].ScaleFactors; buffer = new byte[size]; fixed(byte *dstPtr = buffer) { MyMemory.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), (uint)size); } } else { size = sizeof(MyVoxelMultiMaterialConstants); MyVoxelMultiMaterialConstants constantsData = new MyVoxelMultiMaterialConstants(); constantsData.Scales0 = Table[triple.I0].ScaleFactors; constantsData.Scales1 = Table[triple.I1].ScaleFactors; constantsData.Scales2 = triple.I2 >= 0 ? Table[triple.I2].ScaleFactors : Vector3.One; buffer = new byte[size]; fixed(byte *dstPtr = buffer) { MyMemory.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), (uint)size); } } var version = triple.I0.GetHashCode(); MyHashHelper.Combine(ref version, triple.I1.GetHashCode()); MyHashHelper.Combine(ref version, triple.I2.GetHashCode()); return(new MyMaterialProxy_2 { MaterialConstants = { BindFlag = MyBindFlag.BIND_PS, CB = MyCommon.GetMaterialCB(size), Version = version, Data = buffer }, MaterialSRVs = { BindFlag = MyBindFlag.BIND_PS, StartSlot = 0, Version = version, SRVs = singleMaterial ? new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, } : ( triple.I2 == -1 ? new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I1].Near.ColorMetalArray.ShaderView, Table[triple.I1].Far1.ColorMetalArray.ShaderView, Table[triple.I1].Far2.ColorMetalArray.ShaderView, null, null, null, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, Table[triple.I1].Near.NormalGlossArray.ShaderView, Table[triple.I1].Far1.NormalGlossArray.ShaderView, Table[triple.I1].Far2.NormalGlossArray.ShaderView, null, null, null, null, null, null, null, null, null, null, null, null } : new ShaderResourceView[] { Table[triple.I0].Near.ColorMetalArray.ShaderView, Table[triple.I0].Far1.ColorMetalArray.ShaderView, Table[triple.I0].Far2.ColorMetalArray.ShaderView, Table[triple.I1].Near.ColorMetalArray.ShaderView, Table[triple.I1].Far1.ColorMetalArray.ShaderView, Table[triple.I1].Far2.ColorMetalArray.ShaderView, Table[triple.I2].Near.ColorMetalArray.ShaderView, Table[triple.I2].Far1.ColorMetalArray.ShaderView, Table[triple.I2].Far2.ColorMetalArray.ShaderView, Table[triple.I0].Near.NormalGlossArray.ShaderView, Table[triple.I0].Far1.NormalGlossArray.ShaderView, Table[triple.I0].Far2.NormalGlossArray.ShaderView, Table[triple.I1].Near.NormalGlossArray.ShaderView, Table[triple.I1].Far1.NormalGlossArray.ShaderView, Table[triple.I1].Far2.NormalGlossArray.ShaderView, Table[triple.I2].Near.NormalGlossArray.ShaderView, Table[triple.I2].Far1.NormalGlossArray.ShaderView, Table[triple.I2].Far2.NormalGlossArray.ShaderView, null, null, null, null, null, null, null, null, null } ) } }); }
static unsafe MyMaterialProxy_2 CreateProxy(MyVoxelMaterialTriple triple) { byte[] buffer; int size; MyRenderProxy.Assert(triple.I0 < Table.Length, "Index to table incorrect"); MyRenderProxy.Assert(triple.I1 < Table.Length, "Index to table incorrect"); MyRenderProxy.Assert(triple.I2 < Table.Length, "Index to table incorrect"); //TODO: This shouldnt happen if Table is created correctly if (triple.I0 >= Table.Length) { triple.I0 = 0; } if (triple.I1 >= Table.Length) { triple.I1 = -1; } if (triple.I2 >= Table.Length) { triple.I2 = -1; } //////end of hack bool singleMaterial = triple.I1 == -1 && triple.I2 == -1; if (singleMaterial) { size = sizeof(MyVoxelMaterialConstants); MyVoxelMaterialConstants constantsData = new MyVoxelMaterialConstants(); FillVoxelMaterialEntry(ref constantsData.entry, ref Table[triple.I0]); buffer = new byte[size]; fixed(byte *dstPtr = buffer) { #if XB1 SharpDX.Utilities.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), size); #else // !XB1 MyMemory.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), (uint)size); #endif // !XB1 } } else { size = sizeof(MyVoxelMultiMaterialConstants); MyVoxelMultiMaterialConstants constantsData = new MyVoxelMultiMaterialConstants(); FillVoxelMaterialEntry(ref constantsData.entry0, ref Table[triple.I0]); FillVoxelMaterialEntry(ref constantsData.entry1, ref Table[triple.I1]); if (triple.I2 >= 0) { FillVoxelMaterialEntry(ref constantsData.entry2, ref Table[triple.I2]); } else { ResetVoxelMaterialEntry(out constantsData.entry2); } buffer = new byte[size]; fixed(byte *dstPtr = buffer) { #if XB1 SharpDX.Utilities.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), size); #else // !XB1 MyMemory.CopyMemory(new IntPtr(dstPtr), new IntPtr(&constantsData), (uint)size); #endif // !XB1 } } var version = triple.I0.GetHashCode(); MyHashHelper.Combine(ref version, triple.I1.GetHashCode()); MyHashHelper.Combine(ref version, triple.I2.GetHashCode()); MyConstantsPack materialConstants = new MyConstantsPack { BindFlag = MyBindFlag.BIND_PS, CB = MyCommon.GetMaterialCB(size), Version = version, Data = buffer }; MySrvTable srvTable = new MySrvTable { // NOTE(AF) Adding BIND_VS here will interfere with shadows, causing flickering in the first cascade BindFlag = MyBindFlag.BIND_PS, StartSlot = 0, Version = version, Srvs = new ISrvBindable[] { MyGlobalResources.FileArrayTextureVoxelCM, MyGlobalResources.FileArrayTextureVoxelNG, MyGlobalResources.FileArrayTextureVoxelExt, } }; return(new MyMaterialProxy_2 { MaterialConstants = materialConstants, MaterialSrvs = srvTable }); }