Esempio n. 1
0
        public Variable AddUniform(SSLParser.UniformVariableContext ctx, SSLVisitor vis)
        {
            var v = Variable.FromContext(ctx, vis);

            var pre = FindGlobal(v.Name);

            if (pre != null)
            {
                vis.Error(ctx, $"A variable with the name '{v.Name}' already exists in the global {v.Scope} context.");
            }

            _uniforms.Add(v.Name, v);
            return(v);
        }
        internal static Variable FromContext(SSLParser.UniformVariableContext ctx, SSLVisitor vis)
        {
            var name = ctx.Name.Text;

            if (name[0] == '$')
            {
                vis.Error(ctx, "Cannot start a variable with the character '$', this is reserved for built-in variables.");
            }
            if (name.Length > 32)
            {
                vis.Error(ctx, "Uniform names cannot be longer than 32 characters.");
            }

            var type = ReflectionUtils.TranslateTypeContext(ctx.type());

            if (!type.HasValue)
            {
                vis.Error(ctx, $"Unable to convert variable '{name}' to internal type.");
            }
            if (type == ShaderType.Void)
            {
                vis.Error(ctx, $"The variable '{name}' cannot be of type 'void'.");
            }

            ImageFormat?ifmt = null;
            uint?       si   = null;

            if (type.Value.IsImageType())
            {
                if (ctx.Qualifier?.imageLayoutQualifier() == null)
                {
                    vis.Error(ctx, "Storage image types must have a format qualifier.");
                }
                ifmt = ReflectionUtils.TranslateImageFormat(ctx.Qualifier.imageLayoutQualifier());
            }
            else if (type.Value.IsSubpassInput())
            {
                if (ctx.Qualifier?.INTEGER_LITERAL() == null)
                {
                    vis.Error(ctx, "Subpass inputs must have an index qualifier.");
                }
                var pv = SSLVisitor.ParseIntegerLiteral(ctx.Qualifier.INTEGER_LITERAL().GetText(), out var isus, out var error);
                if (!pv.HasValue)
                {
                    vis.Error(ctx, error);
                }
                if (pv.Value < 0)
                {
                    vis.Error(ctx, "Subpass input index cannot be less than 0.");
                }
                if (pv.Value > 255)
                {
                    vis.Error(ctx, "Subpass input index cannot be greater than 255.");
                }
                si = (uint)pv.Value;
            }
            else
            {
                if (ctx.Qualifier?.imageLayoutQualifier() != null || ctx.Qualifier?.INTEGER_LITERAL() != null)
                {
                    vis.Error(ctx, $"The handle type '{type}' cannot have qualifiers.");
                }
            }

            return(new Variable(type.Value, name, VariableScope.Uniform, false, null, ifmt: ifmt, si: si));
        }