22#include "fmt/format.h"
33#define DEBUG_CONTEXT_LINES 0
38#define DEBUG_DEPENDENCIES 0
46 const char line_prefix[] =
" | ";
47 char err_col[] =
"\033[31;1m";
48 char warn_col[] =
"\033[33;1m";
49 char info_col[] =
"\033[0;2m";
50 char reset_col[] =
"\033[0;0m";
51 std::string sources_combined = fmt::to_string(fmt::join(sources,
""));
55 err_col[0] = warn_col[0] = info_col[0] = reset_col[0] =
'\0';
62 dynstr,
"%s%sIncluded files (in order):%s\n", info_col, line_prefix, reset_col);
67 int64_t cursor = 0, line_count = 0;
68 while ((cursor = src.find(
'\n', cursor) + 1)) {
71 if (sources_end_line.
is_empty() ==
false) {
72 line_count += sources_end_line.
last();
74 sources_end_line.
append(line_count);
79 dynstr,
"%s%s %s%s\n", info_col, line_prefix, filename.
c_str(), reset_col);
84 sources_end_line.
append(0);
87 const char *log_line =
log, *line_end;
91 bool found_line_id =
false;
92 while ((line_end = strchr(log_line,
'\n'))) {
94 if (line_end == log_line) {
101 if (logref.
endswith(
" shader failed to compile with the following errors:") ||
102 logref.
endswith(
" No code generated"))
104 log_line += size_t(line_end) - size_t(log_line);
109 log_line = parser->
parse_line(sources_combined.c_str(), log_line, log_item);
112 if ((log_item.
cursor.
row == -1) &&
ELEM(log_line[0],
'\n',
'\0')) {
126 found_line_id =
false;
129 const char *src_line = sources_combined.c_str();
144 const char *src_line_end;
145 found_line_id =
false;
147 int src_line_index = 1;
148 while ((src_line_end = strchr(src_line,
'\n'))) {
149 if (src_line_index >= log_item.
cursor.
row) {
150 found_line_id =
true;
158 src_line = src_line_end + 1;
181 src_line = src_line_end + 1;
183 while ((src_line_end = strchr(src_line,
'\n'))) {
190 src_line = src_line_end + 1;
200 if (source_index <= 0) {
202 if (log_item.
cursor.
row <= sources_end_line[
i]) {
208 if (source_index > 0) {
209 row_in_file -= sources_end_line[source_index - 1];
215 sizeof(name_buf) - 1);
219 else if (source_index > 0) {
221 sources[source_index]);
247 log_line = line_end + 1;
248 previous_location = log_item.
cursor;
267 const char *error_msg,
268 const char *warning_msg,
269 const char *note_msg)
const
271 if (
STREQLEN(log_line, error_msg, strlen(error_msg))) {
272 log_line += strlen(error_msg);
275 else if (
STREQLEN(log_line, warning_msg, strlen(warning_msg))) {
276 log_line += strlen(warning_msg);
279 else if (
STREQLEN(log_line, note_msg, strlen(note_msg))) {
280 log_line += strlen(note_msg);
288 while (
at_any(log_line, separators)) {
296 const char *cursor = log_line;
297 while (!
ELEM(cursor[0],
'\n',
'\0')) {
298 if (cursor[0] == stop_char) {
308 return log_line[0] >=
'0' && log_line[0] <=
'9';
318 return int(strtol(log_line,
const_cast<char **
>(r_new_position), 10));
324 size_t current_line = 1;
325 for (
char c : source_combined) {
326 if (current_line >= target_line) {
341 size_t nearest_line_directive = sub_str.
rfind(directive);
342 if (nearest_line_directive != std::string::npos) {
343 size_t start_of_file_name = nearest_line_directive + directive.
size();
344 size_t end_of_file_name = sub_str.
find(
'\"', start_of_file_name);
345 if (end_of_file_name != std::string::npos) {
346 return sub_str.
substr(start_of_file_name, end_of_file_name - start_of_file_name);
357 size_t nearest_line_directive = sub_str.
rfind(directive);
358 size_t line_count = 1;
359 if (nearest_line_directive != std::string::npos) {
360 sub_str = sub_str.
substr(nearest_line_directive + directive.
size());
361 line_count = std::stoll(sub_str) - 1;
363 return line_count + std::count(sub_str.
begin(), sub_str.
end(),
'\n');
373 if (ctx ==
nullptr) {
387 if (ctx ==
nullptr) {
399 uint32_t data_len =
data[0];
405 while (cursor < data_len + 1) {
406 uint32_t format_hash =
data[cursor++];
412 printf(
"Printf buffer overflow.\n");
417 switch (block.
type) {
422 printf(block.
fmt.c_str(), *
reinterpret_cast<uint32_t *
>(&
data[cursor++]));
428 printf(block.
fmt.c_str(), *
reinterpret_cast<float *
>(&
data[cursor++]));
#define BLI_assert_unreachable()
A dynamically sized string ADT.
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len) ATTR_NONNULL()
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
#define STREQLEN(a, b, n)
void CLG_log_raw(const CLG_LogType *lg, const char *message)
#define CLOG_CHECK(clg_ref, verbose_level,...)
#define CLOG_AT_LEVEL(clg_ref, verbose_level,...)
int CLG_color_support_get(CLG_LogRef *clg_ref)
void GPU_storagebuf_free(blender::gpu::StorageBuf *ssbo)
void GPU_storagebuf_clear_to_zero(blender::gpu::StorageBuf *ssbo)
void GPU_storagebuf_read(blender::gpu::StorageBuf *ssbo, void *data)
#define GPU_storagebuf_create(size)
Read Guarded memory(de)allocation.
BMesh const char void * data
constexpr int64_t size() const
static constexpr int64_t not_found
constexpr int64_t rfind(char c, int64_t pos=INT64_MAX) const
constexpr int64_t find(char c, int64_t pos=0) const
constexpr const char * begin() const
constexpr const char * end() const
constexpr bool is_empty() const
constexpr StringRef substr(int64_t start, int64_t size) const
constexpr bool endswith(StringRef suffix) const
constexpr int64_t size() const
void copy_utf8_truncated(char *dst, int64_t dst_size) const
constexpr const char * c_str() const
void append(const T &value)
const T & last(const int64_t n=0) const
IndexRange index_range() const
Vector< StorageBuf * > printf_buf
static size_t line_start_get(StringRefNull source_combined, size_t target_line)
static StringRef filename_get(StringRefNull source_combined, size_t pos)
int parse_number(const char *log_line, const char **r_new_position) const
const char * skip_separators(const char *log_line, const StringRef separators) const
bool at_number(const char *log_line) const
static size_t source_line_get(StringRefNull source_combined, size_t pos)
bool at_any(const char *log_line, const StringRef chars) const
virtual const char * parse_line(const char *source_combined, const char *log_line, GPULogItem &log_item)=0
const char * skip_until(const char *log_line, char stop_char) const
const char * skip_severity(const char *log_line, GPULogItem &log_item, const char *error_msg, const char *warning_msg, const char *note_msg) const
void print_log(Span< StringRefNull > sources, const char *log, const char *stage, bool error, GPULogParser *parser)
#define GPU_SHADER_PRINTF_MAX_CAPACITY
#define DEBUG_CONTEXT_LINES
#define DEBUG_LOG_SHADER_SRC_ON_ERROR
void MEM_freeN(void *vmemh)
static void error(const char *str)
const PrintfFormat & gpu_shader_dependency_get_printf_format(uint32_t format_hash)
bool gpu_shader_dependency_has_printf()
StringRefNull gpu_shader_dependency_get_filename_from_source_string(const StringRef source_string)
Find the name of the file from which the given string was generated.
void printf_begin(Context *ctx)
void printf_end(Context *ctx)
std::string file_name_and_error_line