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

Fix shader preprocessor cyclic include handling #77608

Merged
merged 1 commit into from
May 30, 2023
Merged
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
16 changes: 8 additions & 8 deletions scene/resources/shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void Shader::set_include_path(const String &p_path) {
}

void Shader::set_code(const String &p_code) {
for (Ref<ShaderInclude> E : include_dependencies) {
for (const Ref<ShaderInclude> &E : include_dependencies) {
E->disconnect(SNAME("changed"), callable_mp(this, &Shader::_dependency_changed));
}

Expand All @@ -83,8 +83,6 @@ void Shader::set_code(const String &p_code) {
code = p_code;
String pp_code = p_code;

HashSet<Ref<ShaderInclude>> new_include_dependencies;

{
String path = get_path();
if (path.is_empty()) {
Expand All @@ -93,14 +91,16 @@ void Shader::set_code(const String &p_code) {
// Preprocessor must run here and not in the server because:
// 1) Need to keep track of include dependencies at resource level
// 2) Server does not do interaction with Resource filetypes, this is a scene level feature.
HashSet<Ref<ShaderInclude>> new_include_dependencies;
ShaderPreprocessor preprocessor;
preprocessor.preprocess(p_code, path, pp_code, nullptr, nullptr, nullptr, &new_include_dependencies);
Error result = preprocessor.preprocess(p_code, path, pp_code, nullptr, nullptr, nullptr, &new_include_dependencies);
if (result == OK) {
// This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower)
include_dependencies = new_include_dependencies;
}
}

// This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower)
include_dependencies = new_include_dependencies;

for (Ref<ShaderInclude> E : include_dependencies) {
for (const Ref<ShaderInclude> &E : include_dependencies) {
E->connect(SNAME("changed"), callable_mp(this, &Shader::_dependency_changed));
}

Expand Down
15 changes: 8 additions & 7 deletions scene/resources/shader_include.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,9 @@ void ShaderInclude::_dependency_changed() {
}

void ShaderInclude::set_code(const String &p_code) {
HashSet<Ref<ShaderInclude>> new_dependencies;
code = p_code;

for (Ref<ShaderInclude> E : dependencies) {
for (const Ref<ShaderInclude> &E : dependencies) {
E->disconnect(SNAME("changed"), callable_mp(this, &ShaderInclude::_dependency_changed));
}

Expand All @@ -51,14 +50,16 @@ void ShaderInclude::set_code(const String &p_code) {
}

String pp_code;
HashSet<Ref<ShaderInclude>> new_dependencies;
ShaderPreprocessor preprocessor;
preprocessor.preprocess(p_code, path, pp_code, nullptr, nullptr, nullptr, &new_dependencies);
Error result = preprocessor.preprocess(p_code, path, pp_code, nullptr, nullptr, nullptr, &new_dependencies);
if (result == OK) {
// This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower)
dependencies = new_dependencies;
}
}

// This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower)
dependencies = new_dependencies;

for (Ref<ShaderInclude> E : dependencies) {
for (const Ref<ShaderInclude> &E : dependencies) {
E->connect(SNAME("changed"), callable_mp(this, &ShaderInclude::_dependency_changed));
}

Expand Down
5 changes: 3 additions & 2 deletions servers/rendering/shader_preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) {
if (!included.is_empty()) {
uint64_t code_hash = included.hash64();
if (state->cyclic_include_hashes.find(code_hash)) {
set_error(RTR("Cyclic include found."), line);
set_error(RTR("Cyclic include found") + ": " + path, line);
return;
}
}
Expand Down Expand Up @@ -733,7 +733,7 @@ void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) {

FilePosition fp;
fp.file = state->current_filename;
fp.line = line;
fp.line = line + 1;
state->include_positions.push_back(fp);

String result;
Expand Down Expand Up @@ -1157,6 +1157,7 @@ void ShaderPreprocessor::set_error(const String &p_error, int p_line) {
if (state->error.is_empty()) {
state->error = p_error;
FilePosition fp;
fp.file = state->current_filename;
fp.line = p_line + 1;
state->include_positions.push_back(fp);
}
Expand Down