summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/physics_server_3d.cpp2
-rw-r--r--servers/rendering/rasterizer_rd/shader_compiler_rd.cpp29
-rw-r--r--servers/rendering/shader_language.cpp256
-rw-r--r--servers/rendering/shader_language.h5
-rw-r--r--servers/rendering_server.cpp12
-rw-r--r--servers/rendering_server.h4
6 files changed, 287 insertions, 21 deletions
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index 2dd8ea3edb..9668358710 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -295,7 +295,7 @@ Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryPar
Array PhysicsDirectSpaceState3D::_cast_motion(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, const Vector3 &p_motion) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
- float closest_safe, closest_unsafe;
+ float closest_safe = 1.0f, closest_unsafe = 1.0f;
bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
if (!res) {
return Array();
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
index 32321164a1..79bb990649 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
@@ -711,6 +711,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
gcode += _typestr(cnode.type);
}
gcode += " " + _mkid(String(cnode.name));
+ if (cnode.array_size > 0) {
+ gcode += "[";
+ gcode += itos(cnode.array_size);
+ gcode += "]";
+ }
gcode += "=";
gcode += _dump_node_code(cnode.initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
gcode += ";\n";
@@ -988,7 +993,29 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
} break;
case SL::Node::TYPE_CONSTANT: {
SL::ConstantNode *cnode = (SL::ConstantNode *)p_node;
- return get_constant_text(cnode->datatype, cnode->values);
+
+ if (cnode->array_size == 0) {
+ return get_constant_text(cnode->datatype, cnode->values);
+ } else {
+ if (cnode->get_datatype() == SL::TYPE_STRUCT) {
+ code += _mkid(cnode->struct_name);
+ } else {
+ code += _typestr(cnode->datatype);
+ }
+ code += "[";
+ code += itos(cnode->array_size);
+ code += "]";
+ code += "(";
+ for (int i = 0; i < cnode->array_size; i++) {
+ if (i > 0) {
+ code += ",";
+ } else {
+ code += "";
+ }
+ code += _dump_node_code(cnode->array_declarations[0].initializer[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ }
+ code += ")";
+ }
} break;
case SL::Node::TYPE_OPERATOR: {
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 2ec65b7ea8..a3fef10cc0 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -1014,6 +1014,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
if (r_data_type) {
*r_data_type = shader->constants[p_identifier].type;
}
+ if (r_array_size) {
+ *r_array_size = shader->constants[p_identifier].array_size;
+ }
if (r_type) {
*r_type = IDENTIFIER_CONSTANT;
}
@@ -3064,7 +3067,7 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
} else if (p_node->type == Node::TYPE_ARRAY) {
ArrayNode *arr = static_cast<ArrayNode *>(p_node);
- if (arr->is_const) {
+ if (shader->constants.has(arr->name) || arr->is_const) {
if (r_message) {
*r_message = RTR("Constants cannot be modified.");
}
@@ -4976,7 +4979,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
DataType type2;
- String struct_name2 = "";
+ StringName struct_name2 = "";
if (shader->structs.has(tk.text)) {
type2 = TYPE_STRUCT;
@@ -6445,38 +6448,253 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.type_str = struct_name;
constant.precision = precision;
constant.initializer = nullptr;
+ constant.array_size = 0;
- if (tk.type == TK_OP_ASSIGN) {
- if (!is_constant) {
- _set_error("Expected 'const' keyword before constant definition");
+ bool unknown_size = false;
+
+ if (tk.type == TK_BRACKET_OPEN) {
+ if (RenderingServer::get_singleton()->is_low_end()) {
+ _set_error("Global const arrays are supported only on high-end platform!");
return ERR_PARSE_ERROR;
}
- //variable created with assignment! must parse an expression
- Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>());
- if (!expr) {
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_CLOSE) {
+ unknown_size = true;
+ tk = _get_token();
+ } else if (tk.type == TK_INT_CONSTANT && ((int)tk.constant) > 0) {
+ constant.array_size = (int)tk.constant;
+ tk = _get_token();
+ if (tk.type != TK_BRACKET_CLOSE) {
+ _set_error("Expected ']'");
+ return ERR_PARSE_ERROR;
+ }
+ tk = _get_token();
+ } else {
+ _set_error("Expected integer constant > 0 or ']'");
return ERR_PARSE_ERROR;
}
- if (expr->type == Node::TYPE_OPERATOR && ((OperatorNode *)expr)->op == OP_CALL) {
- _set_error("Expected constant expression after '='");
+ }
+
+ if (tk.type == TK_OP_ASSIGN) {
+ if (!is_constant) {
+ _set_error("Expected 'const' keyword before constant definition");
return ERR_PARSE_ERROR;
}
- constant.initializer = static_cast<ConstantNode *>(expr);
+ if (constant.array_size > 0 || unknown_size) {
+ bool full_def = false;
+
+ ArrayDeclarationNode::Declaration decl;
+ decl.name = name;
+ decl.size = constant.array_size;
- if (is_struct) {
- if (expr->get_datatype_name() != struct_name) {
- _set_error("Invalid assignment of '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' to '" + struct_name + "'");
+ tk = _get_token();
+
+ if (tk.type != TK_CURLY_BRACKET_OPEN) {
+ if (unknown_size) {
+ _set_error("Expected '{'");
+ return ERR_PARSE_ERROR;
+ }
+
+ full_def = true;
+
+ DataPrecision precision2 = PRECISION_DEFAULT;
+ if (is_token_precision(tk.type)) {
+ precision2 = get_token_precision(tk.type);
+ tk = _get_token();
+ if (!is_token_nonvoid_datatype(tk.type)) {
+ _set_error("Expected datatype after precision");
+ return ERR_PARSE_ERROR;
+ }
+ }
+
+ StringName struct_name2;
+ DataType type2;
+
+ if (shader->structs.has(tk.text)) {
+ type2 = TYPE_STRUCT;
+ struct_name2 = tk.text;
+ } else {
+ if (!is_token_variable_datatype(tk.type)) {
+ _set_error("Invalid data type for array");
+ return ERR_PARSE_ERROR;
+ }
+ type2 = get_token_datatype(tk.type);
+ }
+
+ int array_size2 = 0;
+
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_OPEN) {
+ TkPos pos2 = _get_tkpos();
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_CLOSE) {
+ array_size2 = constant.array_size;
+ tk = _get_token();
+ } else {
+ _set_tkpos(pos2);
+
+ Node *n = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
+ if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
+ _set_error("Expected single integer constant > 0");
+ return ERR_PARSE_ERROR;
+ }
+
+ ConstantNode *cnode = (ConstantNode *)n;
+ if (cnode->values.size() == 1) {
+ array_size2 = cnode->values[0].sint;
+ if (array_size2 <= 0) {
+ _set_error("Expected single integer constant > 0");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ _set_error("Expected single integer constant > 0");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+ if (tk.type != TK_BRACKET_CLOSE) {
+ _set_error("Expected ']");
+ return ERR_PARSE_ERROR;
+ } else {
+ tk = _get_token();
+ }
+ }
+ } else {
+ _set_error("Expected '[");
+ return ERR_PARSE_ERROR;
+ }
+
+ if (constant.precision != precision2 || constant.type != type2 || struct_name != struct_name2 || constant.array_size != array_size2) {
+ String error_str = "Cannot convert from '";
+ if (type2 == TYPE_STRUCT) {
+ error_str += struct_name2;
+ } else {
+ if (precision2 != PRECISION_DEFAULT) {
+ error_str += get_precision_name(precision2);
+ error_str += " ";
+ }
+ error_str += get_datatype_name(type2);
+ }
+ error_str += "[";
+ error_str += itos(array_size2);
+ error_str += "]'";
+ error_str += " to '";
+ if (type == TYPE_STRUCT) {
+ error_str += struct_name;
+ } else {
+ if (precision != PRECISION_DEFAULT) {
+ error_str += get_precision_name(precision);
+ error_str += " ";
+ }
+ error_str += get_datatype_name(type);
+ }
+ error_str += "[";
+ error_str += itos(constant.array_size);
+ error_str += "]'";
+ _set_error(error_str);
+ return ERR_PARSE_ERROR;
+ }
+ }
+
+ bool curly = tk.type == TK_CURLY_BRACKET_OPEN;
+
+ if (unknown_size) {
+ if (!curly) {
+ _set_error("Expected '{'");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ if (full_def) {
+ if (curly) {
+ _set_error("Expected '('");
+ return ERR_PARSE_ERROR;
+ }
+ }
+ }
+
+ if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
+ while (true) {
+ Node *n = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
+ if (!n) {
+ return ERR_PARSE_ERROR;
+ }
+
+ if (n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) {
+ _set_error("Expected constant expression");
+ return ERR_PARSE_ERROR;
+ }
+
+ if (constant.type != n->get_datatype() || n->get_datatype_name() != struct_name) {
+ _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (is_struct ? String(struct_name) : get_datatype_name(constant.type)) + "'");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+ if (tk.type == TK_COMMA) {
+ decl.initializer.push_back(n);
+ continue;
+ } else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) {
+ decl.initializer.push_back(n);
+ break;
+ } else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) {
+ decl.initializer.push_back(n);
+ break;
+ } else {
+ if (curly)
+ _set_error("Expected '}' or ','");
+ else
+ _set_error("Expected ')' or ','");
+ return ERR_PARSE_ERROR;
+ }
+ }
+ if (unknown_size) {
+ decl.size = decl.initializer.size();
+ constant.array_size = decl.initializer.size();
+ } else if (decl.initializer.size() != constant.array_size) {
+ _set_error("Array size mismatch");
+ return ERR_PARSE_ERROR;
+ }
+ }
+
+ ConstantNode *expr = memnew(ConstantNode);
+
+ expr->datatype = constant.type;
+
+ expr->struct_name = constant.type_str;
+
+ expr->array_size = constant.array_size;
+
+ expr->array_declarations.push_back(decl);
+
+ constant.initializer = static_cast<ConstantNode *>(expr);
+ } else {
+ //variable created with assignment! must parse an expression
+ Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>());
+ if (!expr)
+ return ERR_PARSE_ERROR;
+ if (expr->type == Node::TYPE_OPERATOR && ((OperatorNode *)expr)->op == OP_CALL) {
+ _set_error("Expected constant expression after '='");
+ return ERR_PARSE_ERROR;
+ }
+
+ constant.initializer = static_cast<ConstantNode *>(expr);
+
+ if (type != expr->get_datatype() || expr->get_datatype_name() != struct_name) {
+ _set_error("Invalid assignment of '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' to '" + (is_struct ? String(struct_name) : get_datatype_name(type)) + "'");
return ERR_PARSE_ERROR;
}
- } else if (type != expr->get_datatype()) {
- _set_error("Invalid assignment of '" + get_datatype_name(expr->get_datatype()) + "' to '" + get_datatype_name(type) + "'");
- return ERR_PARSE_ERROR;
}
tk = _get_token();
} else {
- _set_error("Expected initialization of constant");
- return ERR_PARSE_ERROR;
+ if (constant.array_size > 0 || unknown_size) {
+ _set_error("Expected array initialization");
+ return ERR_PARSE_ERROR;
+ } else {
+ _set_error("Expected initialization of constant");
+ return ERR_PARSE_ERROR;
+ }
}
shader->constants[name] = constant;
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index 020a5e3e6f..bc8f03774a 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -453,6 +453,8 @@ public:
struct ConstantNode : public Node {
DataType datatype = TYPE_VOID;
+ String struct_name = "";
+ int array_size = 0;
union Value {
bool boolean;
@@ -462,7 +464,9 @@ 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; }
ConstantNode() :
Node(TYPE_CONSTANT) {}
@@ -573,6 +577,7 @@ public:
StringName type_str;
DataPrecision precision;
ConstantNode *initializer;
+ int array_size;
};
struct Function {
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 4f12ec5b02..7edab1418d 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -1895,6 +1895,10 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_os_feature", "feature"), &RenderingServer::has_os_feature);
ClassDB::bind_method(D_METHOD("set_debug_generate_wireframes", "generate"), &RenderingServer::set_debug_generate_wireframes);
+ ClassDB::bind_method(D_METHOD("is_render_loop_enabled"), &RenderingServer::is_render_loop_enabled);
+ ClassDB::bind_method(D_METHOD("set_render_loop_enabled", "enabled"), &RenderingServer::set_render_loop_enabled);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_loop_enabled"), "set_render_loop_enabled", "is_render_loop_enabled");
+
BIND_CONSTANT(NO_INDEX_ARRAY);
BIND_CONSTANT(ARRAY_WEIGHTS_SIZE);
BIND_CONSTANT(CANVAS_ITEM_Z_MIN);
@@ -2286,6 +2290,14 @@ RID RenderingServer::instance_create2(RID p_base, RID p_scenario) {
return instance;
}
+bool RenderingServer::is_render_loop_enabled() const {
+ return render_loop_enabled;
+}
+
+void RenderingServer::set_render_loop_enabled(bool p_enabled) {
+ render_loop_enabled = p_enabled;
+}
+
RenderingServer::RenderingServer() {
//ERR_FAIL_COND(singleton);
singleton = this;
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 3ce63585a8..56a8325630 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -47,6 +47,7 @@ class RenderingServer : public Object {
static RenderingServer *singleton;
int mm_policy;
+ bool render_loop_enabled = true;
void _camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far);
void _canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector<float> &p_margins, const Color &p_modulate = Color(1, 1, 1));
@@ -1229,6 +1230,9 @@ public:
virtual bool is_low_end() const = 0;
+ bool is_render_loop_enabled() const;
+ void set_render_loop_enabled(bool p_enabled);
+
RenderingServer();
virtual ~RenderingServer();
};