mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
shader: reduce unnecessary newlines and #line in preprocessed GLSL
This is done by only writing out a #line when the first non-whitespace line is encountered; any blank lines before that are trimmed. This cuts down the size of the preprocessed shaders for a large project with many shader includes, such as the RenderPipeline.
This commit is contained in:
parent
f4a8e923f7
commit
c4f5ed308f
@ -2723,7 +2723,6 @@ r_preprocess_include(ostream &out, const Filename &fn,
|
||||
// would just be too long to display.
|
||||
_included_files.push_back(fn);
|
||||
|
||||
out << "#line 1 " << fileno << " // " << fn << "\n";
|
||||
if (shader_cat.is_debug()) {
|
||||
shader_cat.debug()
|
||||
<< "Preprocessing shader include " << fileno << ": " << fn << "\n";
|
||||
@ -2752,11 +2751,17 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
int ext_google_line = 0;
|
||||
bool had_include = false;
|
||||
int lineno = 0;
|
||||
bool write_line_directive = (fileno != 0);
|
||||
|
||||
while (std::getline(in, line)) {
|
||||
++lineno;
|
||||
|
||||
if (line.empty()) {
|
||||
out.put('\n');
|
||||
// We still write a newline to make sure the line numbering remains
|
||||
// consistent, unless we are about to write a #line directive anyway.
|
||||
if (!write_line_directive) {
|
||||
out.put('\n');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2768,7 +2773,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
|
||||
if (std::getline(in, line2)) {
|
||||
line += line2;
|
||||
out.put('\n');
|
||||
if (!write_line_directive) {
|
||||
out.put('\n');
|
||||
}
|
||||
++lineno;
|
||||
} else {
|
||||
break;
|
||||
@ -2796,7 +2803,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
while (block_end == string::npos) {
|
||||
// Didn't find it - look in the next line.
|
||||
if (std::getline(in, line2)) {
|
||||
out.put('\n');
|
||||
if (!write_line_directive) {
|
||||
out.put('\n');
|
||||
}
|
||||
++lineno;
|
||||
block_end = line2.find("*/");
|
||||
} else {
|
||||
@ -2814,10 +2823,21 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
line.resize(line.size() - 1);
|
||||
}
|
||||
|
||||
if (line.empty()) {
|
||||
if (!write_line_directive) {
|
||||
out.put('\n');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if this line contains a #directive.
|
||||
char directive[64];
|
||||
if (line.size() < 8 || sscanf(line.c_str(), " # %63s", directive) != 1) {
|
||||
// Nope. Just pass the line through unmodified.
|
||||
if (write_line_directive) {
|
||||
out << "#line " << lineno << " " << fileno << " // " << fn << "\n";
|
||||
write_line_directive = false;
|
||||
}
|
||||
out << line << "\n";
|
||||
continue;
|
||||
}
|
||||
@ -2862,8 +2882,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
}
|
||||
|
||||
// Restore the line counter.
|
||||
out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n";
|
||||
write_line_directive = true;
|
||||
had_include = true;
|
||||
continue;
|
||||
|
||||
} else if (strcmp(pragma, "once") == 0) {
|
||||
// Do a stricter syntax check, just to be extra safe.
|
||||
@ -2888,17 +2909,15 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
if (!full_fn.empty()) {
|
||||
once_files.insert(full_fn);
|
||||
}
|
||||
} else {
|
||||
// Forward it, the driver will ignore it if it doesn't know it.
|
||||
out << line << "\n";
|
||||
continue;
|
||||
}
|
||||
// Otherwise, just pass it through to the driver.
|
||||
|
||||
} else if (strcmp(directive, "endif") == 0) {
|
||||
// Check for an #endif after an include. We have to restore the line
|
||||
// number in case the include happened under an #if block.
|
||||
out << line << "\n";
|
||||
if (had_include) {
|
||||
out << "#line " << (lineno + 1) << " " << fileno << "\n";
|
||||
write_line_directive = true;
|
||||
}
|
||||
|
||||
} else if (strcmp(directive, "extension") == 0) {
|
||||
@ -2931,7 +2950,8 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
}
|
||||
ext_google_include = mode;
|
||||
ext_google_line = mode;
|
||||
out << line << "\n";
|
||||
// Still pass it through to the driver, so it can enable other
|
||||
// extensions.
|
||||
|
||||
} else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0) {
|
||||
// Enable the Google extension support for #include statements.
|
||||
@ -2939,14 +2959,12 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
// This matches the behavior of Khronos' glslang reference compiler.
|
||||
ext_google_include = mode;
|
||||
ext_google_line = mode;
|
||||
continue;
|
||||
|
||||
} else if (strcmp(extension, "GL_GOOGLE_cpp_style_line_directive") == 0) {
|
||||
// Enables strings in #line statements.
|
||||
ext_google_line = mode;
|
||||
|
||||
} else {
|
||||
// It's an extension the driver should worry about.
|
||||
out << line << "\n";
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
shader_cat.error()
|
||||
@ -2954,6 +2972,7 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
<< lineno << " of file " << fn << ":\n " << line << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (ext_google_include > 0 && strcmp(directive, "include") == 0) {
|
||||
// Warn about extension use if requested.
|
||||
if (ext_google_include == 1) {
|
||||
@ -2991,8 +3010,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
}
|
||||
|
||||
// Restore the line counter.
|
||||
out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n";
|
||||
write_line_directive = true;
|
||||
had_include = true;
|
||||
continue;
|
||||
|
||||
} else if (ext_google_line > 0 && strcmp(directive, "line") == 0) {
|
||||
// It's a #line directive. See if it uses a string instead of number.
|
||||
@ -3016,15 +3036,15 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
|
||||
_included_files.push_back(Filename(filestr));
|
||||
|
||||
out << "#line " << lineno << " " << fileno << " // " << filestr << "\n";
|
||||
|
||||
} else {
|
||||
// We couldn't parse the #line directive. Pass it through unmodified.
|
||||
out << line << "\n";
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Different directive (eg. #version). Leave it untouched.
|
||||
out << line << "\n";
|
||||
}
|
||||
|
||||
if (write_line_directive) {
|
||||
out << "#line " << lineno << " " << fileno << " // " << fn << "\n";
|
||||
write_line_directive = false;
|
||||
}
|
||||
out << line << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user