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)); }