Fix shader crash when using a varying in separate func before it defined
This commit is contained in:
parent
8e36f98ea5
commit
965b2f6ca4
|
@ -4664,9 +4664,18 @@ bool ShaderLanguage::_validate_restricted_func(const StringName &p_name, const C
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p_func_info->uses_restricted_functions.is_empty()) {
|
if (!p_func_info->uses_restricted_items.is_empty()) {
|
||||||
const Pair<StringName, TkPos> &first_element = p_func_info->uses_restricted_functions.get(0);
|
const Pair<StringName, CallInfo::Item> &first_element = p_func_info->uses_restricted_items.get(0);
|
||||||
_set_tkpos(first_element.second);
|
|
||||||
|
if (first_element.second.type == CallInfo::Item::ITEM_TYPE_VARYING) {
|
||||||
|
const ShaderNode::Varying &varying = shader->varyings[first_element.first];
|
||||||
|
|
||||||
|
if (varying.stage == ShaderNode::Varying::STAGE_VERTEX) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_set_tkpos(first_element.second.pos);
|
||||||
|
|
||||||
if (is_in_restricted_function) {
|
if (is_in_restricted_function) {
|
||||||
_set_error(vformat(RTR("'%s' cannot be used within the '%s' processor function."), first_element.first, "vertex"));
|
_set_error(vformat(RTR("'%s' cannot be used within the '%s' processor function."), first_element.first, "vertex"));
|
||||||
|
@ -5352,7 +5361,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
// Register usage of the restricted function.
|
// Register usage of the restricted function.
|
||||||
calls_info[current_function].uses_restricted_functions.push_back(Pair<StringName, TkPos>(name, _get_tkpos()));
|
calls_info[current_function].uses_restricted_items.push_back(Pair<StringName, CallInfo::Item>(name, CallInfo::Item(CallInfo::Item::ITEM_TYPE_BUILTIN, _get_tkpos())));
|
||||||
is_builtin = true;
|
is_builtin = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5469,10 +5478,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
||||||
|
|
||||||
if (shader->varyings.has(varname)) {
|
if (shader->varyings.has(varname)) {
|
||||||
switch (shader->varyings[varname].stage) {
|
switch (shader->varyings[varname].stage) {
|
||||||
case ShaderNode::Varying::STAGE_UNKNOWN: {
|
case ShaderNode::Varying::STAGE_UNKNOWN:
|
||||||
_set_error(vformat(RTR("Varying '%s' must be assigned in the 'vertex' or 'fragment' function first."), varname));
|
if (is_out_arg) {
|
||||||
return nullptr;
|
error = true;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT:
|
case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT:
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ShaderNode::Varying::STAGE_VERTEX:
|
case ShaderNode::Varying::STAGE_VERTEX:
|
||||||
|
@ -5672,6 +5682,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
||||||
_set_tkpos(prev_pos);
|
_set_tkpos(prev_pos);
|
||||||
|
|
||||||
ShaderNode::Varying &var = shader->varyings[identifier];
|
ShaderNode::Varying &var = shader->varyings[identifier];
|
||||||
|
calls_info[current_function].uses_restricted_items.push_back(Pair<StringName, CallInfo::Item>(identifier, CallInfo::Item(CallInfo::Item::ITEM_TYPE_VARYING, prev_pos)));
|
||||||
|
|
||||||
String error;
|
String error;
|
||||||
if (is_token_operator_assign(next_token.type)) {
|
if (is_token_operator_assign(next_token.type)) {
|
||||||
if (!_validate_varying_assign(shader->varyings[identifier], &error)) {
|
if (!_validate_varying_assign(shader->varyings[identifier], &error)) {
|
||||||
|
|
|
@ -917,8 +917,21 @@ private:
|
||||||
|
|
||||||
// Additional function information (eg. call hierarchy). No need to expose it to compiler.
|
// Additional function information (eg. call hierarchy). No need to expose it to compiler.
|
||||||
struct CallInfo {
|
struct CallInfo {
|
||||||
|
struct Item {
|
||||||
|
enum ItemType {
|
||||||
|
ITEM_TYPE_BUILTIN,
|
||||||
|
ITEM_TYPE_VARYING,
|
||||||
|
} type;
|
||||||
|
|
||||||
|
TkPos pos;
|
||||||
|
|
||||||
|
Item() {}
|
||||||
|
Item(ItemType p_type, TkPos p_pos) :
|
||||||
|
type(p_type), pos(p_pos) {}
|
||||||
|
};
|
||||||
|
|
||||||
StringName name;
|
StringName name;
|
||||||
List<Pair<StringName, TkPos>> uses_restricted_functions;
|
List<Pair<StringName, Item>> uses_restricted_items;
|
||||||
List<CallInfo *> calls;
|
List<CallInfo *> calls;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue