Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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}");
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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));
        }
Example #6
0
        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}");
            }
        }