Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add is_equal_approx/is_zero_approx for floats to shading language #77239

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions servers/rendering/shader_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1148,12 +1148,23 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
const SL::VariableNode *vnode = static_cast<const SL::VariableNode *>(onode->arguments[0]);
const SL::FunctionNode *func = nullptr;
const bool is_internal_func = internal_functions.has(vnode->name);
bool is_global_func = false;

if (!is_internal_func) {
for (int i = 0; i < shader->functions.size(); i++) {
if (shader->functions[i].name == vnode->name) {
func = shader->functions[i].function;
break;
if (p_default_actions.global_functions.has(vnode->name)) {
is_global_func = true;

// Declare the global function.
if (!used_name_defines.has(vnode->name)) {
r_gen_code.defines.push_back(p_default_actions.global_functions[vnode->name]);
used_name_defines.insert(vnode->name);
}
} else {
for (int i = 0; i < shader->functions.size(); i++) {
if (shader->functions[i].name == vnode->name) {
func = shader->functions[i].function;
break;
}
}
}
}
Expand All @@ -1173,7 +1184,9 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
used_flag_pointers.insert(vnode->name);
}

if (is_internal_func) {
if (is_global_func) {
code += vnode->name;
} else if (is_internal_func) {
code += vnode->name;
is_texture_func = texture_functions.has(vnode->name);
texture_func_no_uv = (vnode->name == "textureSize" || vnode->name == "textureQueryLevels");
Expand Down Expand Up @@ -1583,6 +1596,19 @@ void ShaderCompiler::initialize(DefaultIdentifierActions p_actions) {
texture_functions.insert("textureQueryLod");
texture_functions.insert("textureQueryLevels");
texture_functions.insert("texelFetch");

// Global functions.

actions.global_functions["is_equal_approx"] = R"(
bool is_equal_approx(float a, float b) {
return abs(a - b) < 0.00001;
}
)";
actions.global_functions["is_zero_approx"] = R"(
bool is_zero_approx(float x) {
return abs(x) < 0.00001;
}
)";
}

ShaderCompiler::ShaderCompiler() {
Expand Down
1 change: 1 addition & 0 deletions servers/rendering/shader_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class ShaderCompiler {
HashMap<StringName, String> renames;
HashMap<StringName, String> render_mode_defines;
HashMap<StringName, String> usage_defines;
HashMap<StringName, String> global_functions;
HashMap<StringName, String> custom_samplers;
ShaderLanguage::TextureFilter default_filter;
ShaderLanguage::TextureRepeat default_repeat;
Expand Down
42 changes: 40 additions & 2 deletions servers/rendering/shader_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,21 @@ void ShaderLanguage::_parse_used_identifier(const StringName &p_identifier, Iden
#endif // DEBUG_ENABLED

bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name, ConstantNode::Value *r_constant_value) {
for (const KeyValue<StringName, StageFunctionInfo> &E : ShaderTypes::get_singleton()->get_functions()) {
if (E.key == p_identifier) {
if (r_data_type) {
*r_data_type = E.value.return_type;
}
if (r_is_const) {
*r_is_const = true;
}
if (r_type) {
*r_type = IDENTIFIER_FUNCTION;
}
return true;
}
}

if (is_shader_inc) {
for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
for (const KeyValue<StringName, FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i))) {
Expand Down Expand Up @@ -3082,9 +3097,19 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI

int argcount = args.size();

if (p_function_info.stage_functions.has(name)) {
HashMap<StringName, StageFunctionInfo> stage_functions;

for (const KeyValue<StringName, StageFunctionInfo> &E : ShaderTypes::get_singleton()->get_functions()) {
stage_functions[E.key] = E.value;
}
for (const KeyValue<StringName, StageFunctionInfo> &E : p_function_info.stage_functions) {
stage_functions[E.key] = E.value;
}

if (stage_functions.has(name)) {
//stage based function
const StageFunctionInfo &sf = p_function_info.stage_functions[name];
const StageFunctionInfo &sf = stage_functions[name];

if (argcount != sf.arguments.size()) {
_set_error(vformat(RTR("Invalid number of arguments when calling stage function '%s', which expects %d arguments."), String(name), sf.arguments.size()));
return false;
Expand Down Expand Up @@ -10235,6 +10260,10 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
}
}

for (const KeyValue<StringName, StageFunctionInfo> &E : ShaderTypes::get_singleton()->get_functions()) {
matches.insert(String(E.key), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
}

for (int i = 0; i < shader->functions.size(); i++) {
if (!shader->functions[i].callable || shader->functions[i].name == skip_function) {
continue;
Expand Down Expand Up @@ -10370,7 +10399,16 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
bool low_end = RenderingServer::get_singleton()->is_low_end();

if (stages && stages->has(block_function)) {
HashMap<StringName, StageFunctionInfo> stage_functions;

for (const KeyValue<StringName, StageFunctionInfo> &E : ShaderTypes::get_singleton()->get_functions()) {
stage_functions[E.key] = E.value;
}
for (const KeyValue<StringName, StageFunctionInfo> &E : (*stages)[block_function].stage_functions) {
stage_functions[E.key] = E.value;
}

for (const KeyValue<StringName, StageFunctionInfo> &E : stage_functions) {
if (completion_function == E.key) {
calltip += get_datatype_name(E.value.return_type);
calltip += " ";
Expand Down
17 changes: 17 additions & 0 deletions servers/rendering/shader_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
#include "shader_types.h"
#include "core/math/math_defs.h"

const HashMap<StringName, ShaderLanguage::StageFunctionInfo> &ShaderTypes::get_functions() const {
return global_functions;
}

const HashMap<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(RS::ShaderMode p_mode) const {
return shader_modes[p_mode].functions;
}
Expand All @@ -56,6 +60,19 @@ static ShaderLanguage::BuiltInInfo constt(ShaderLanguage::DataType p_type) {
ShaderTypes::ShaderTypes() {
singleton = this;

/*************** GLOBAL FUNCTIONS ***********************/

ShaderLanguage::StageFunctionInfo is_equal_approx_func;
is_equal_approx_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("a", ShaderLanguage::TYPE_FLOAT));
is_equal_approx_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("b", ShaderLanguage::TYPE_FLOAT));
is_equal_approx_func.return_type = ShaderLanguage::TYPE_BOOL;
global_functions["is_equal_approx"] = is_equal_approx_func;

ShaderLanguage::StageFunctionInfo is_zero_approx_func;
is_zero_approx_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("x", ShaderLanguage::TYPE_FLOAT));
is_zero_approx_func.return_type = ShaderLanguage::TYPE_BOOL;
global_functions["is_zero_approx"] = is_zero_approx_func;

/*************** SPATIAL ***********************/

shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
Expand Down
2 changes: 2 additions & 0 deletions servers/rendering/shader_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class ShaderTypes {
};

HashMap<RS::ShaderMode, Type> shader_modes;
HashMap<StringName, ShaderLanguage::StageFunctionInfo> global_functions;

static ShaderTypes *singleton;

Expand All @@ -51,6 +52,7 @@ class ShaderTypes {
public:
static ShaderTypes *get_singleton() { return singleton; }

const HashMap<StringName, ShaderLanguage::StageFunctionInfo> &get_functions() const;
const HashMap<StringName, ShaderLanguage::FunctionInfo> &get_functions(RS::ShaderMode p_mode) const;
const Vector<ShaderLanguage::ModeInfo> &get_modes(RS::ShaderMode p_mode) const;
const HashSet<String> &get_types() const;
Expand Down