void initContext() { glretrace::Context *currentContext = glretrace::getCurrentContext(); /* Ensure we have adequate extension support */ assert(currentContext); supportsTimestamp = currentContext->hasExtension("GL_ARB_timer_query"); supportsElapsed = currentContext->hasExtension("GL_EXT_timer_query") || supportsTimestamp; supportsOcclusion = currentContext->hasExtension("GL_ARB_occlusion_query"); supportsDebugOutput = currentContext->hasExtension("GL_ARB_debug_output"); supportsARBShaderObjects = currentContext->hasExtension("GL_ARB_shader_objects"); /* Check for timer query support */ if (retrace::profilingGpuTimes) { if (!supportsTimestamp && !supportsElapsed) { std::cout << "Error: Cannot run profile, GL_ARB_timer_query or GL_EXT_timer_query extensions are not supported." << std::endl; exit(-1); } GLint bits = 0; glGetQueryiv(GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS, &bits); if (!bits) { std::cout << "Error: Cannot run profile, GL_QUERY_COUNTER_BITS == 0." << std::endl; exit(-1); } } /* Check for occlusion query support */ if (retrace::profilingPixelsDrawn && !supportsOcclusion) { std::cout << "Error: Cannot run profile, GL_ARB_occlusion_query extension is not supported." << std::endl; exit(-1); } /* Setup debug message call back */ if (retrace::debug && supportsDebugOutput) { glretrace::Context *currentContext = glretrace::getCurrentContext(); glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); glDebugMessageCallbackARB(&debugOutputCallback, currentContext); if (DEBUG_OUTPUT_SYNCHRONOUS) { glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } } /* Sync the gpu and cpu start times */ if (retrace::profilingCpuTimes || retrace::profilingGpuTimes) { if (!retrace::profiler.hasBaseTimes()) { double cpuTimeScale = 1.0E9 / getTimeFrequency(); GLint64 currentTime = getCurrentTime() * cpuTimeScale; retrace::profiler.setBaseCpuTime(currentTime); retrace::profiler.setBaseGpuTime(currentTime); } } if (retrace::profilingMemoryUsage) { GLint64 currentVsize, currentRss; getCurrentVsize(currentVsize); retrace::profiler.setBaseVsizeUsage(currentVsize); getCurrentRss(currentRss); retrace::profiler.setBaseRssUsage(currentRss); } }
/* * Called the first time a context is made current. */ void initContext() { glretrace::Context *currentContext = glretrace::getCurrentContext(); assert(currentContext); /* Ensure we have adequate extension support */ glprofile::Profile currentProfile = currentContext->actualProfile(); supportsTimestamp = currentProfile.versionGreaterOrEqual(glprofile::API_GL, 3, 3) || currentContext->hasExtension("GL_ARB_timer_query"); supportsElapsed = currentContext->hasExtension("GL_EXT_timer_query") || supportsTimestamp; supportsOcclusion = currentProfile.versionGreaterOrEqual(glprofile::API_GL, 1, 5); supportsARBShaderObjects = currentContext->hasExtension("GL_ARB_shader_objects"); currentContext->KHR_debug = currentContext->hasExtension("GL_KHR_debug"); if (currentContext->KHR_debug) { glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, ¤tContext->maxDebugMessageLength); assert(currentContext->maxDebugMessageLength > 0); } #ifdef __APPLE__ // GL_TIMESTAMP doesn't work on Apple. GL_TIME_ELAPSED still does however. // http://lists.apple.com/archives/mac-opengl/2014/Nov/threads.html#00001 supportsTimestamp = false; #endif /* Check for timer query support */ if (retrace::profilingGpuTimes) { if (!supportsTimestamp && !supportsElapsed) { std::cout << "error: cannot profile, GL_ARB_timer_query or GL_EXT_timer_query extensions are not supported." << std::endl; exit(-1); } GLint bits = 0; glGetQueryiv(GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS, &bits); if (!bits) { std::cout << "error: cannot profile, GL_QUERY_COUNTER_BITS == 0." << std::endl; exit(-1); } } /* Check for occlusion query support */ if (retrace::profilingPixelsDrawn && !supportsOcclusion) { std::cout << "error: cannot profile, GL_ARB_occlusion_query extension is not supported (" << currentProfile << ")" << std::endl; exit(-1); } /* Setup debug message call back */ if (retrace::debug) { if (currentContext->KHR_debug) { if (currentProfile.desktop()) { glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); glDebugMessageCallback(&debugOutputCallback, currentContext); } else { glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); glDebugMessageCallbackKHR(&debugOutputCallback, currentContext); } if (DEBUG_OUTPUT_SYNCHRONOUS) { glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); } } else if (currentContext->hasExtension("GL_ARB_debug_output")) { glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); glDebugMessageCallbackARB(&debugOutputCallback, currentContext); if (DEBUG_OUTPUT_SYNCHRONOUS) { glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } } } /* Sync the gpu and cpu start times */ if (retrace::profilingCpuTimes || retrace::profilingGpuTimes) { if (!retrace::profiler.hasBaseTimes()) { double cpuTimeScale = 1.0E9 / getTimeFrequency(); GLint64 currentTime = getCurrentTime() * cpuTimeScale; retrace::profiler.setBaseCpuTime(currentTime); retrace::profiler.setBaseGpuTime(currentTime); } } if (retrace::profilingMemoryUsage) { GLint64 currentVsize, currentRss; getCurrentVsize(currentVsize); retrace::profiler.setBaseVsizeUsage(currentVsize); getCurrentRss(currentRss); retrace::profiler.setBaseRssUsage(currentRss); } }