Blender V4.5
glsl_preprocess.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <fstream>
10#include <iostream>
11#include <regex>
12#include <string>
13
14#include "glsl_preprocess.hh"
15
16int main(int argc, char **argv)
17{
18 if (argc != 4) {
19 std::cerr << "Usage: glsl_preprocess <data_file_from> <data_file_to> <metadata_file_to>"
20 << std::endl;
21 exit(1);
22 }
23
24 const char *input_file_name = argv[1];
25 const char *output_file_name = argv[2];
26 const char *metadata_file_name = argv[3];
27
28 /* Open the input file for reading */
29 std::ifstream input_file(input_file_name);
30 if (!input_file) {
31 std::cerr << "Error: Could not open input file " << input_file_name << std::endl;
32 exit(1);
33 }
34
35 /* Open the output file for writing */
36 std::ofstream output_file(output_file_name, std::ofstream::out | std::ofstream::binary);
37 if (!output_file) {
38 std::cerr << "Error: Could not open output file " << output_file_name << std::endl;
39 input_file.close();
40 exit(1);
41 }
42
43 /* Open the output file for writing */
44 std::ofstream metadata_file(metadata_file_name, std::ofstream::out | std::ofstream::binary);
45 if (!output_file) {
46 std::cerr << "Error: Could not open output file " << metadata_file_name << std::endl;
47 input_file.close();
48 exit(1);
49 }
50
51 std::stringstream buffer;
52 buffer << input_file.rdbuf();
53
54 int error = 0;
55
56 auto count_lines = [](const std::string &str) {
57 size_t lines = 0;
58 for (char c : str) {
59 if (c == '\n') {
60 lines++;
61 }
62 }
63 return lines;
64 };
65
66 auto get_line = [&](size_t line) {
67 std::string src = buffer.str();
68 size_t start = 0, end;
69 for (; line > 1; line--) {
70 start = src.find('\n', start + 1);
71 }
72 end = src.find('\n', start + 1);
73 return src.substr(start + 1, end - (start + 1));
74 };
75
76 auto report_error = [&](const std::smatch &match, const char *err_msg) {
77 size_t remaining_lines = count_lines(match.suffix());
78 size_t total_lines = count_lines(buffer.str());
79
80 size_t err_line = 1 + total_lines - remaining_lines;
81 size_t err_char = (match.prefix().str().size() - 1) - match.prefix().str().rfind('\n');
82
83 std::cerr << input_file_name;
84 std::cerr << ':' << std::to_string(err_line) << ':' << std::to_string(err_char);
85 std::cerr << ": error: " << err_msg << std::endl;
86 std::cerr << get_line(err_line) << std::endl;
87 std::cerr << std::string(err_char, ' ') << '^' << std::endl;
88
89 error++;
90 };
91 std::string filename(output_file_name);
92 const bool is_info = filename.find("info.hh") != std::string::npos;
93 const bool is_glsl = filename.find(".glsl") != std::string::npos;
94 const bool is_shared = filename.find("shared.h") != std::string::npos;
95 const bool is_library = is_glsl &&
96 (filename.find("gpu_shader_material_") != std::string::npos ||
97 filename.find("gpu_shader_common_") != std::string::npos ||
98 filename.find("gpu_shader_compositor_") != std::string::npos);
99
100 if (is_info) {
101 std::cerr << "File " << output_file_name
102 << " is a create info file and should not be processed as glsl" << std::endl;
103 return 1;
104 }
105
106 using Preprocessor = blender::gpu::shader::Preprocessor;
107 Preprocessor processor;
108
109 Preprocessor::SourceLanguage language = Preprocessor::language_from_filename(filename);
110
111 if (language == Preprocessor::SourceLanguage::GLSL) {
112 /* All build-time GLSL files should be considered blender-GLSL. */
113 language = Preprocessor::SourceLanguage::BLENDER_GLSL;
114 }
115
117 output_file << processor.process(
118 language, buffer.str(), input_file_name, is_library, is_shared, report_error, metadata);
119
120 /* TODO(fclem): Don't use regex for that. */
121 std::string metadata_function_name = "metadata_" +
122 std::regex_replace(
123 filename, std::regex(R"((?:.*)\/(.*))"), "$1");
124 std::replace(metadata_function_name.begin(), metadata_function_name.end(), '.', '_');
125
126 metadata_file << metadata.serialize(metadata_function_name);
127
128 input_file.close();
129 output_file.close();
130 metadata_file.close();
131
132 return error;
133}
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define str(s)
#define main()
static void error(const char *str)
std::string serialize(const std::string &function_name) const