summaryrefslogtreecommitdiff
path: root/servers/rendering/shader_language.h
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/shader_language.h')
-rw-r--r--servers/rendering/shader_language.h137
1 files changed, 118 insertions, 19 deletions
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index 14594b039c..a91fa57a8e 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -39,6 +39,10 @@
#include "core/typedefs.h"
#include "core/variant/variant.h"
+#ifdef DEBUG_ENABLED
+#include "shader_warnings.h"
+#endif // DEBUG_ENABLED
+
class ShaderLanguage {
public:
struct TkPos {
@@ -331,6 +335,17 @@ public:
MAX_INSTANCE_UNIFORM_INDICES = 16
};
+ struct VaryingFunctionNames {
+ StringName fragment;
+ StringName vertex;
+ StringName light;
+ VaryingFunctionNames() {
+ fragment = "fragment";
+ vertex = "vertex";
+ light = "light";
+ }
+ };
+
struct Node {
Node *next = nullptr;
@@ -354,6 +369,8 @@ public:
virtual DataType get_datatype() const { return TYPE_VOID; }
virtual String get_datatype_name() const { return ""; }
+ virtual int get_array_size() const { return 0; }
+ virtual bool is_indexed() const { return false; }
Node(Type t) :
type(t) {}
@@ -373,11 +390,15 @@ public:
struct OperatorNode : public Node {
DataType return_cache = TYPE_VOID;
DataPrecision return_precision_cache = PRECISION_DEFAULT;
+ int return_array_size = 0;
Operator op = OP_EQUAL;
StringName struct_name;
Vector<Node *> arguments;
- virtual DataType get_datatype() const { return return_cache; }
- virtual String get_datatype_name() const { return String(struct_name); }
+
+ virtual DataType get_datatype() const override { return return_cache; }
+ virtual String get_datatype_name() const override { return String(struct_name); }
+ virtual int get_array_size() const override { return return_array_size; }
+ virtual bool is_indexed() const override { return op == OP_INDEX; }
OperatorNode() :
Node(TYPE_OPERATOR) {}
@@ -387,10 +408,11 @@ public:
DataType datatype_cache = TYPE_VOID;
StringName name;
StringName struct_name;
- virtual DataType get_datatype() const { return datatype_cache; }
- virtual String get_datatype_name() const { return String(struct_name); }
bool is_const = false;
+ virtual DataType get_datatype() const override { return datatype_cache; }
+ virtual String get_datatype_name() const override { return String(struct_name); }
+
VariableNode() :
Node(TYPE_VARIABLE) {}
};
@@ -405,9 +427,9 @@ public:
StringName name;
Node *initializer;
};
-
Vector<Declaration> declarations;
- virtual DataType get_datatype() const { return datatype; }
+
+ virtual DataType get_datatype() const override { return datatype; }
VariableDeclarationNode() :
Node(TYPE_VARIABLE_DECLARATION) {}
@@ -421,9 +443,12 @@ public:
Node *call_expression = nullptr;
Node *assign_expression = nullptr;
bool is_const = false;
+ int array_size = 0;
- virtual DataType get_datatype() const { return datatype_cache; }
- virtual String get_datatype_name() const { return String(struct_name); }
+ virtual DataType get_datatype() const override { return datatype_cache; }
+ virtual String get_datatype_name() const override { return String(struct_name); }
+ virtual int get_array_size() const override { return (index_expression || call_expression) ? 0 : array_size; }
+ virtual bool is_indexed() const override { return index_expression != nullptr; }
ArrayNode() :
Node(TYPE_ARRAY) {}
@@ -434,6 +459,10 @@ public:
String struct_name;
Vector<Node *> initializer;
+ virtual DataType get_datatype() const override { return datatype; }
+ virtual String get_datatype_name() const override { return struct_name; }
+ virtual int get_array_size() const override { return initializer.size(); }
+
ArrayConstructNode() :
Node(TYPE_ARRAY_CONSTRUCT) {}
};
@@ -449,10 +478,11 @@ public:
StringName name;
uint32_t size;
Vector<Node *> initializer;
+ bool single_expression;
};
-
Vector<Declaration> declarations;
- virtual DataType get_datatype() const { return datatype; }
+
+ virtual DataType get_datatype() const override { return datatype; }
ArrayDeclarationNode() :
Node(TYPE_ARRAY_DECLARATION) {}
@@ -472,8 +502,10 @@ public:
Vector<Value> values;
Vector<ArrayDeclarationNode::Declaration> array_declarations;
- virtual DataType get_datatype() const { return datatype; }
- virtual String get_datatype_name() const { return struct_name; }
+
+ virtual DataType get_datatype() const override { return datatype; }
+ virtual String get_datatype_name() const override { return struct_name; }
+ virtual int get_array_size() const override { return array_size; }
ConstantNode() :
Node(TYPE_CONSTANT) {}
@@ -535,10 +567,13 @@ public:
Node *owner = nullptr;
Node *index_expression = nullptr;
Node *assign_expression = nullptr;
+ Node *call_expression = nullptr;
bool has_swizzling_duplicates = false;
- virtual DataType get_datatype() const { return datatype; }
- virtual String get_datatype_name() const { return String(struct_name); }
+ virtual DataType get_datatype() const override { return datatype; }
+ virtual String get_datatype_name() const override { return String(struct_name); }
+ virtual int get_array_size() const override { return array_size; }
+ virtual bool is_indexed() const override { return index_expression != nullptr || call_expression != nullptr; }
MemberNode() :
Node(TYPE_MEMBER) {}
@@ -564,6 +599,7 @@ public:
bool tex_builtin_check;
StringName tex_builtin;
bool is_const;
+ int array_size;
Map<StringName, Set<int>> tex_argument_connect;
};
@@ -572,10 +608,15 @@ public:
DataType return_type = TYPE_VOID;
StringName return_struct_name;
DataPrecision return_precision = PRECISION_DEFAULT;
+ int return_array_size = 0;
Vector<Argument> arguments;
BlockNode *body = nullptr;
bool can_discard = false;
+ virtual DataType get_datatype() const override { return return_type; }
+ virtual String get_datatype_name() const override { return String(return_struct_name); }
+ virtual int get_array_size() const override { return return_array_size; }
+
FunctionNode() :
Node(TYPE_FUNCTION) {}
};
@@ -737,6 +778,7 @@ public:
static uint32_t get_type_size(DataType p_type);
static void get_keyword_list(List<String> *r_keywords);
+ static bool is_control_flow_keyword(String p_keyword);
static void get_builtin_funcs(List<String> *r_keywords);
struct BuiltInInfo {
@@ -769,7 +811,8 @@ public:
Map<StringName, BuiltInInfo> built_ins;
Map<StringName, StageFunctionInfo> stage_functions;
- bool can_discard;
+ bool can_discard = false;
+ bool main_function = false;
};
static bool has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name);
@@ -789,12 +832,49 @@ private:
String error_str;
int error_line;
+#ifdef DEBUG_ENABLED
+ struct Usage {
+ int decl_line;
+ bool used = false;
+ Usage(int p_decl_line = -1) {
+ decl_line = p_decl_line;
+ }
+ };
+
+ Map<StringName, Usage> used_constants;
+ Map<StringName, Usage> used_varyings;
+ Map<StringName, Usage> used_uniforms;
+ Map<StringName, Usage> used_functions;
+ Map<StringName, Usage> used_structs;
+ Map<ShaderWarning::Code, Map<StringName, Usage> *> warnings_check_map;
+
+ Map<StringName, Map<StringName, Usage>> used_local_vars;
+ Map<ShaderWarning::Code, Map<StringName, Map<StringName, Usage>> *> warnings_check_map2;
+
+ List<ShaderWarning> warnings;
+
+ bool check_warnings = false;
+ uint32_t warning_flags;
+
+ void _add_line_warning(ShaderWarning::Code p_code, const StringName &p_subject = "") {
+ warnings.push_back(ShaderWarning(p_code, tk_line, p_subject));
+ }
+ void _add_warning(ShaderWarning::Code p_code, int p_line, const StringName &p_subject = "") {
+ warnings.push_back(ShaderWarning(p_code, p_line, p_subject));
+ }
+ void _check_warning_accums();
+#endif // DEBUG_ENABLED
+
String code;
int char_idx;
int tk_line;
StringName current_function;
bool last_const = false;
+ bool pass_array = false;
+ StringName last_name;
+
+ VaryingFunctionNames varying_function_names;
TkPos _get_tkpos() {
TkPos tkp;
@@ -833,12 +913,18 @@ private:
IDENTIFIER_LOCAL_VAR,
IDENTIFIER_BUILTIN_VAR,
IDENTIFIER_CONSTANT,
+ IDENTIFIER_MAX,
};
+ IdentifierType last_type = IDENTIFIER_MAX;
+
bool _find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr, StringName *r_struct_name = nullptr, ConstantNode::Value *r_constant_value = nullptr);
+#ifdef DEBUG_ENABLED
+ void _parse_used_identifier(const StringName &p_identifier, IdentifierType p_type, const StringName &p_function);
+#endif // DEBUG_ENABLED
bool _is_operator_assign(Operator p_op) const;
bool _validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message = nullptr);
- bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr);
+ bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr, int *r_ret_size = nullptr);
struct BuiltinFuncDef {
enum { MAX_ARGS = 5 };
@@ -869,7 +955,8 @@ private:
static const BuiltinFuncOutArgs builtin_func_out_args[];
Error _validate_datatype(DataType p_type);
- bool _compare_datatypes_in_nodes(Node *a, Node *b) const;
+ bool _compare_datatypes(DataType p_datatype_a, String p_datatype_name_a, int p_array_size_a, DataType p_datatype_b, String p_datatype_name_b, int p_array_size_b);
+ bool _compare_datatypes_in_nodes(Node *a, Node *b);
bool _validate_function_call(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str);
bool _parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg = nullptr);
@@ -877,8 +964,10 @@ private:
bool _propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin);
bool _validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message);
bool _validate_varying_using(ShaderNode::Varying &p_varying, String *r_message);
+ bool _check_node_constness(const Node *p_node) const;
Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
+ Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info);
Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size);
ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);
@@ -893,13 +982,23 @@ private:
Error _find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op);
public:
+#ifdef DEBUG_ENABLED
+ List<ShaderWarning>::Element *get_warnings_ptr();
+
+ void enable_warning_checking(bool p_enabled);
+ bool is_warning_checking_enabled() const;
+
+ void set_warning_flags(uint32_t p_flags);
+ uint32_t get_warning_flags() const;
+#endif // DEBUG_ENABLED
+
//static void get_keyword_list(ShaderType p_type,List<String> *p_keywords);
void clear();
static String get_shader_type(const String &p_code);
- Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func);
- Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint);
+ Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func);
+ Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint);
String get_error_text();
int get_error_line();