33#define TRIM_NVIDIA_BUFFER_INFO 1
35#define TRIM_SHADER_STATS_INFO 1
48# define APIENTRY __stdcall
58 const GLchar *message,
61 if (
ELEM(type, GL_DEBUG_TYPE_PUSH_GROUP, GL_DEBUG_TYPE_POP_GROUP)) {
84 if (
ELEM(severity, GL_DEBUG_SEVERITY_LOW, GL_DEBUG_SEVERITY_NOTIFICATION)) {
86 const char *
format = use_color ?
"\033[2m%s\033[0m" :
"%s";
91 char debug_groups[512] =
"";
103 case GL_DEBUG_TYPE_ERROR:
104 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
105 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
108 case GL_DEBUG_TYPE_PORTABILITY:
109 case GL_DEBUG_TYPE_PERFORMANCE:
110 case GL_DEBUG_TYPE_OTHER:
111 case GL_DEBUG_TYPE_MARKER:
118 CLG_logf(
LOG.type, clog_level, debug_groups,
"",
"%s", message);
119 if (severity == GL_DEBUG_SEVERITY_HIGH) {
122 fprintf(stderr,
"\033[2m");
126 fprintf(stderr,
"\033[0m\n");
138 glEnable(GL_DEBUG_OUTPUT);
139 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
141 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0,
nullptr, GL_TRUE);
142 glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION,
143 GL_DEBUG_TYPE_MARKER,
145 GL_DEBUG_SEVERITY_NOTIFICATION,
147 "Successfully hooked OpenGL debug callback");
164 GLenum
error = glGetError();
166#define ERROR_CASE(err) \
169 SNPRINTF(msg, "%s : %s", #err, info); \
170 debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg, nullptr); \
187 debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg,
nullptr);
202 uint16_t ubo_needed =
interface->enabled_ubo_mask_;
203 ubo_needed &= ~ctx->bound_ubo_slots;
206 uint16_t ssbo_needed =
interface->enabled_ssbo_mask_;
207 ssbo_needed &= ~ctx->bound_ssbo_slots;
211 tex_needed &=
~GLContext::state_manager_active_get()->bound_texture_slots();
214 uint8_t ima_needed =
interface->enabled_ima_mask_;
215 ima_needed &=
~GLContext::state_manager_active_get()->bound_image_slots();
217 if (ubo_needed == 0 && tex_needed == 0 && ima_needed == 0 && ssbo_needed == 0) {
221 for (
int i = 0; ubo_needed != 0;
i++, ubo_needed >>= 1) {
222 if ((ubo_needed & 1) != 0) {
224 const char *ubo_name =
interface->input_name_get(ubo_input);
228 msg,
"Missing UBO bind at slot %d : %s > %s : %s",
i, sh_name.
c_str(), ubo_name, info);
229 debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg,
nullptr);
233 for (
int i = 0; ssbo_needed != 0;
i++, ssbo_needed >>= 1) {
234 if ((ssbo_needed & 1) != 0) {
236 const char *ssbo_name =
interface->input_name_get(ssbo_input);
240 msg,
"Missing SSBO bind at slot %d : %s > %s : %s",
i, sh_name.
c_str(), ssbo_name, info);
241 debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg,
nullptr);
245 for (
int i = 0; tex_needed != 0;
i++, tex_needed >>= 1) {
246 if ((tex_needed & 1) != 0) {
253 "Missing Texture bind at slot %d : %s > %s : %s",
258 debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg,
nullptr);
262 for (
int i = 0; ima_needed != 0;
i++, ima_needed >>= 1) {
263 if ((ima_needed & 1) != 0) {
270 msg,
"Missing Image bind at slot %d : %s > %s : %s",
i, sh_name.
c_str(), tex_name, info);
271 debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg,
nullptr);
278 debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, info,
nullptr);
293 case GL_FRAGMENT_SHADER:
294 case GL_GEOMETRY_SHADER:
295 case GL_VERTEX_SHADER:
305 case GL_VERTEX_ARRAY:
307 case GL_UNIFORM_BUFFER:
318 case GL_FRAGMENT_SHADER:
320 case GL_GEOMETRY_SHADER:
322 case GL_VERTEX_SHADER:
332 (epoxy_gl_version() >= 43 || epoxy_has_gl_extension(
"GL_KHR_debug")))
338 case GL_FRAGMENT_SHADER:
339 case GL_GEOMETRY_SHADER:
340 case GL_VERTEX_SHADER:
341 case GL_COMPUTE_SHADER:
344 case GL_UNIFORM_BUFFER:
345 case GL_SHADER_STORAGE_BUFFER:
346 case GL_ARRAY_BUFFER:
347 case GL_ELEMENT_ARRAY_BUFFER:
353 glObjectLabel(type,
object, -1, label);
372 (epoxy_gl_version() >= 43 || epoxy_has_gl_extension(
"GL_KHR_debug")))
376 glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, index, -1,
name);
379 if (!
G.profile_gpu) {
383 TimeQuery query = {};
385 query.finished =
false;
387 glGetInteger64v(GL_TIMESTAMP, &query.cpu_start);
389 glGenQueries(2, query.handles);
390 glQueryCounter(query.handle_start, GL_TIMESTAMP);
392 if (frame_timings.is_empty()) {
393 frame_timings.append({});
395 frame_timings.last().queries.append(query);
401 (epoxy_gl_version() >= 43 || epoxy_has_gl_extension(
"GL_KHR_debug")))
406 if (!
G.profile_gpu) {
411 for (
int i = queries.
size() - 1;
i >= 0;
i--) {
412 TimeQuery &query = queries[
i];
413 if (!query.finished) {
414 query.finished =
true;
415 glQueryCounter(query.handle_end, GL_TIMESTAMP);
416 glGetInteger64v(GL_TIMESTAMP, &query.cpu_end);
420 CLOG_ERROR(&
LOG,
"Profile GPU error: Extra GPU_debug_group_end() call.");
425void GLContext::process_frame_timings()
427 if (!
G.profile_gpu) {
431 for (
int frame_i = 0; frame_i < frame_timings.
size(); frame_i++) {
434 GLint frame_is_ready = 0;
435 bool frame_is_valid = !queries.
is_empty();
437 for (
int i = queries.
size() - 1;
i >= 0;
i--) {
438 if (!queries[
i].finished) {
439 frame_is_valid =
false;
440 CLOG_ERROR(&
LOG,
"Profile GPU error: Missing GPU_debug_group_end() call");
443 glGetQueryObjectiv(queries.
last().handle_end, GL_QUERY_RESULT_AVAILABLE, &frame_is_ready);
448 if (!frame_is_valid) {
450 for (TimeQuery &query : queries) {
451 glDeleteQueries(2, query.handles);
453 frame_timings.remove(frame_i--);
457 if (!frame_is_ready) {
461 for (TimeQuery &query : queries) {
462 GLuint64 gpu_start = 0;
463 GLuint64 gpu_end = 0;
464 glGetQueryObjectui64v(query.handle_start, GL_QUERY_RESULT, &gpu_start);
465 glGetQueryObjectui64v(query.handle_end, GL_QUERY_RESULT, &gpu_end);
466 glDeleteQueries(2, query.handles);
469 query.name, gpu_start, gpu_end, query.cpu_start, query.cpu_end);
472 frame_timings.remove(frame_i--);
475 frame_timings.append({});
487 bool result = renderdoc_.start_frame_capture(
nullptr,
nullptr);
489 renderdoc_.set_frame_capture_title(title);
507 renderdoc_.end_frame_capture(
nullptr,
nullptr);
520 const char *title = (
const char *)scope;
534 const char *title = (
const char *)scope;
#define SNPRINTF(dst, format,...)
void BLI_system_backtrace(FILE *fp)
#define CLOG_ERROR(clg_ref,...)
void void CLG_logf(const CLG_LogType *lg, enum CLG_Level level, const char *file_line, const char *fn, const char *format,...) _CLOG_ATTR_NONNULL(1
#define CLOG_CHECK(clg_ref, verbose_level,...)
int CLG_color_support_get(CLG_LogRef *clg_ref)
bool GPU_debug_group_match(const char *ref)
#define GPU_DEBUG_SHADER_SPECIALIZATION_GROUP
void GPU_debug_get_groups_names(int name_buf_len, char *r_name_buf)
#define GPU_DEBUG_SHADER_COMPILATION_GROUP
unsigned long long int uint64_t
constexpr const char * c_str() const
const T & last(const int64_t n=0) const
bool debug_capture_begin(const char *title)
void * debug_capture_scope_create(const char *name) override
void debug_unbind_all_ubo() override
void debug_capture_end() override
bool debug_capture_begin(const char *title) override
uint16_t bound_ssbo_slots
void debug_group_begin(const char *name, int index) override
void debug_capture_scope_end(void *scope) override
void debug_group_end() override
bool debug_capture_scope_begin(void *scope) override
void debug_unbind_all_ssbo() override
static ProfileReport & get()
void add_group(StringRefNull name, uint64_t gpu_start, uint64_t gpu_end, uint64_t cpu_start, uint64_t cpu_end)
StringRefNull name_get() const
#define TRIM_NVIDIA_BUFFER_INFO
#define TRIM_SHADER_STATS_INFO
static void error(const char *str)
void check_gl_resources(const char *info)
static void APIENTRY debug_callback(GLenum, GLenum type, GLuint, GLenum severity, GLsizei, const GLchar *message, const GLvoid *)
void raise_gl_error(const char *info)
static const char * to_str_prefix(GLenum type)
void check_gl_error(const char *info)
static const char * to_str_suffix(GLenum type)
void object_label(GLenum type, GLuint object, const char *name)
static void tex_input(float *out, int num, bNodeStack *in, TexParams *params, short thread)