private void LinkConstant(string cbName, Variable variable, LocalParameterKey parameterKey) { // If the constant buffer is not present, add it var constantBuffer = effectReflection.ConstantBuffers.FirstOrDefault(buffer => buffer.Name == cbName); if (constantBuffer == null) { constantBuffer = new EffectConstantBufferDescription() { Name = cbName, Type = ConstantBufferType.ConstantBuffer }; effectReflection.ConstantBuffers.Add(constantBuffer); var constantBufferBinding = new EffectResourceBindingDescription { KeyInfo = { KeyName = cbName }, Class = EffectParameterClass.ConstantBuffer, Type = EffectParameterType.ConstantBuffer, RawName = cbName, SlotStart = -1, SlotCount = 1, ResourceGroup = cbName }; effectReflection.ResourceBindings.Add(constantBufferBinding); valueBindings.Add(constantBuffer, new List <EffectValueDescription>()); } // Get the list of members of this constant buffer var members = valueBindings[constantBuffer]; var binding = new EffectValueDescription { KeyInfo = { KeyName = parameterKey.Name, }, LogicalGroup = (string)variable.GetTag(XenkoTags.LogicalGroup), Type = parameterKey.Type, RawName = variable.Name, }; members.Add(binding); }
private static ParameterKey FindOrCreateValueKey <T>(ref EffectValueDescription binding) where T : struct { var name = binding.KeyInfo.KeyName; var key = ParameterKeys.FindByName(name) as ValueParameterKey <T> ?? ParameterKeys.NewValue <T>(name: name); // Update the default value with the one from the shader if (binding.DefaultValue is T defaultValue) { key.DefaultValueMetadataT.DefaultValue = defaultValue; } return(key); }
private void ValidateConstantBufferReflection(ConstantBuffer constantBufferRaw, ref ConstantBufferDescription constantBufferRawDesc, EffectConstantBufferDescription constantBuffer, LoggerResult log) { switch (constantBufferRawDesc.Type) { case SharpDX.D3DCompiler.ConstantBufferType.ConstantBuffer: if (constantBuffer.Type != ConstantBufferType.ConstantBuffer) { log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.ConstantBuffer}"); } break; case SharpDX.D3DCompiler.ConstantBufferType.TextureBuffer: if (constantBuffer.Type != ConstantBufferType.TextureBuffer) { log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.TextureBuffer}"); } break; default: if (constantBuffer.Type != ConstantBufferType.Unknown) { log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.Unknown}"); } break; } // ConstantBuffers variables for (int i = 0; i < constantBufferRawDesc.VariableCount; i++) { var variable = constantBufferRaw.GetVariable(i); var variableType = variable.GetVariableType(); var variableDescription = variable.Description; var variableTypeDescription = variableType.Description; if (variableTypeDescription.Offset != 0) { log.Error($"Unexpected offset [{variableTypeDescription.Offset}] for variable [{variableDescription.Name}] in constant buffer [{constantBuffer.Name}]"); } var binding = constantBuffer.Members[i]; // Retrieve Link Member if (binding.RawName != variableDescription.Name) { log.Error($"Variable [{variableDescription.Name}] in constant buffer [{constantBuffer.Name}] has no link"); } else { var parameter = new EffectValueDescription() { Type = { Class = (EffectParameterClass)variableTypeDescription.Class, Type = ConvertVariableValueType(variableTypeDescription.Type, log), Elements = variableTypeDescription.ElementCount, RowCount = (byte)variableTypeDescription.RowCount, ColumnCount = (byte)variableTypeDescription.ColumnCount, }, RawName = variableDescription.Name, Offset = variableDescription.StartOffset, Size = variableDescription.Size, }; if (parameter.Offset != binding.Offset || parameter.Size != binding.Size || parameter.Type.Elements != binding.Type.Elements || ((parameter.Type.Class != EffectParameterClass.Struct) && // Ignore columns/rows if it's a struct (sometimes it contains weird data) (parameter.Type.RowCount != binding.Type.RowCount || parameter.Type.ColumnCount != binding.Type.ColumnCount))) { log.Error($"Variable [{variableDescription.Name}] in constant buffer [{constantBuffer.Name}] binding doesn't match what was expected"); } } } if (constantBuffer.Size != constantBufferRawDesc.Size) { log.Error($"Error precomputing buffer size for {constantBuffer.Name}: {constantBuffer.Size} instead of {constantBufferRawDesc.Size}"); } }
internal static void HashConstantBufferMember(ref ObjectIdBuilder hashBuilder, ref EffectValueDescription member, int baseOffset = 0) { hashBuilder.Write(member.KeyInfo.Key.Name); hashBuilder.Write(member.Offset - baseOffset); hashBuilder.Write(member.Size); HashType(ref hashBuilder, ref member.Type); }
private static ParameterKey FindOrCreateValueKey <T>(EffectValueDescription binding) where T : struct { var name = binding.KeyInfo.KeyName; return(ParameterKeys.FindByName(name) ?? ParameterKeys.NewValue <T>(default(T), name)); }
private static void UpdateValueBindingKey(ref EffectValueDescription binding) { switch (binding.Type.Class) { case EffectParameterClass.Scalar: switch (binding.Type.Type) { case EffectParameterType.Bool: binding.KeyInfo.Key = FindOrCreateValueKey <bool>(binding); break; case EffectParameterType.Int: binding.KeyInfo.Key = FindOrCreateValueKey <int>(binding); break; case EffectParameterType.UInt: binding.KeyInfo.Key = FindOrCreateValueKey <uint>(binding); break; case EffectParameterType.Float: binding.KeyInfo.Key = FindOrCreateValueKey <float>(binding); break; } break; case EffectParameterClass.Color: { var componentCount = binding.Type.RowCount != 1 ? binding.Type.RowCount : binding.Type.ColumnCount; switch (binding.Type.Type) { case EffectParameterType.Float: binding.KeyInfo.Key = componentCount == 4 ? FindOrCreateValueKey <Color4>(binding) : (componentCount == 3 ? FindOrCreateValueKey <Color3>(binding) : null); break; } } break; case EffectParameterClass.Vector: { var componentCount = binding.Type.RowCount != 1 ? binding.Type.RowCount : binding.Type.ColumnCount; switch (binding.Type.Type) { case EffectParameterType.Bool: case EffectParameterType.Int: binding.KeyInfo.Key = componentCount == 4 ? (ParameterKey)FindOrCreateValueKey <Int4>(binding) : (componentCount == 3 ? FindOrCreateValueKey <Int3>(binding) : null); break; case EffectParameterType.UInt: binding.KeyInfo.Key = componentCount == 4 ? FindOrCreateValueKey <UInt4>(binding) : null; break; case EffectParameterType.Float: binding.KeyInfo.Key = componentCount == 4 ? FindOrCreateValueKey <Vector4>(binding) : (componentCount == 3 ? (ParameterKey)FindOrCreateValueKey <Vector3>(binding) : (componentCount == 2 ? FindOrCreateValueKey <Vector2>(binding) : null)); break; } } break; case EffectParameterClass.MatrixRows: case EffectParameterClass.MatrixColumns: binding.KeyInfo.Key = FindOrCreateValueKey <Matrix>(binding); break; case EffectParameterClass.Struct: binding.KeyInfo.Key = ParameterKeys.FindByName(binding.KeyInfo.KeyName); break; } if (binding.KeyInfo.Key == null) { throw new InvalidOperationException(string.Format("Unable to find/generate key [{0}] with unsupported type [{1}/{2}]", binding.KeyInfo.KeyName, binding.Type.Class, binding.Type.Type)); } }
private void LinkConstant(string cbName, Variable variable, LocalParameterKey parameterKey) { // If the constant buffer is not present, add it var constantBuffer = effectReflection.ConstantBuffers.FirstOrDefault(buffer => buffer.Name == cbName); if (constantBuffer == null) { constantBuffer = new EffectConstantBufferDescription() {Name = cbName, Type = ConstantBufferType.ConstantBuffer}; effectReflection.ConstantBuffers.Add(constantBuffer); var constantBufferBinding = new EffectResourceBindingDescription { KeyInfo = { KeyName = cbName }, Class = EffectParameterClass.ConstantBuffer, Type = EffectParameterType.ConstantBuffer, RawName = cbName, SlotStart = -1, SlotCount = 1, ResourceGroup = cbName }; effectReflection.ResourceBindings.Add(constantBufferBinding); valueBindings.Add(constantBuffer, new List<EffectValueDescription>()); } // Get the list of members of this constant buffer var members = valueBindings[constantBuffer]; var binding = new EffectValueDescription { KeyInfo = { KeyName = parameterKey.Name, }, LogicalGroup = (string)variable.GetTag(XenkoTags.LogicalGroup), Type = parameterKey.Type, RawName = variable.Name, }; members.Add(binding); }
private void ValidateConstantBufferReflection(ConstantBuffer constantBufferRaw, ref ConstantBufferDescription constantBufferRawDesc, EffectConstantBufferDescription constantBuffer, LoggerResult log) { switch (constantBufferRawDesc.Type) { case SharpDX.D3DCompiler.ConstantBufferType.ConstantBuffer: if (constantBuffer.Type != ConstantBufferType.ConstantBuffer) log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.ConstantBuffer}"); break; case SharpDX.D3DCompiler.ConstantBufferType.TextureBuffer: if (constantBuffer.Type != ConstantBufferType.TextureBuffer) log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.TextureBuffer}"); break; default: if (constantBuffer.Type != ConstantBufferType.Unknown) log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.Unknown}"); break; } // ConstantBuffers variables for (int i = 0; i < constantBufferRawDesc.VariableCount; i++) { var variable = constantBufferRaw.GetVariable(i); var variableType = variable.GetVariableType(); var variableDescription = variable.Description; var variableTypeDescription = variableType.Description; if (variableTypeDescription.Offset != 0) { log.Error("Unexpected offset [{0}] for variable [{1}] in constant buffer [{2}]", variableTypeDescription.Offset, variableDescription.Name, constantBuffer.Name); } var binding = constantBuffer.Members[i]; // Retrieve Link Member if (binding.RawName != variableDescription.Name) { log.Error("Variable [{0}] in constant buffer [{1}] has no link", variableDescription.Name, constantBuffer.Name); } else { var parameter = new EffectValueDescription() { Type = { Class = (EffectParameterClass)variableTypeDescription.Class, Type = ConvertVariableValueType(variableTypeDescription.Type, log), Elements = variableTypeDescription.ElementCount, RowCount = (byte)variableTypeDescription.RowCount, ColumnCount = (byte)variableTypeDescription.ColumnCount, }, RawName = variableDescription.Name, Offset = variableDescription.StartOffset, Size = variableDescription.Size, }; if (parameter.Offset != binding.Offset || parameter.Size != binding.Size || parameter.Type.Elements != binding.Type.Elements || ((parameter.Type.Class != EffectParameterClass.Struct) && // Ignore columns/rows if it's a struct (sometimes it contains weird data) (parameter.Type.RowCount != binding.Type.RowCount || parameter.Type.ColumnCount != binding.Type.ColumnCount))) { log.Error("Variable [{0}] in constant buffer [{1}] binding doesn't match what was expected", variableDescription.Name, constantBuffer.Name); } } } if (constantBuffer.Size != constantBufferRawDesc.Size) { log.Error($"Error precomputing buffer size for {constantBuffer.Name}: {constantBuffer.Size} instead of {constantBufferRawDesc.Size}"); } }