Esempio n. 1
0
static void
completeCallQuery(CallQuery& query) {
    /* Get call start and duration */
    int64_t gpuStart = 0, gpuDuration = 0, cpuDuration = 0, pixels = 0, vsizeDuration = 0, rssDuration = 0;

    if (query.isDraw) {
        if (retrace::profilingGpuTimes) {
            if (supportsTimestamp) {
                /* Use ARB queries in case EXT not present */
                glGetQueryObjecti64v(query.ids[GPU_START], GL_QUERY_RESULT, &gpuStart);
                glGetQueryObjecti64v(query.ids[GPU_DURATION], GL_QUERY_RESULT, &gpuDuration);
            } else {
                glGetQueryObjecti64vEXT(query.ids[GPU_DURATION], GL_QUERY_RESULT, &gpuDuration);
            }
        }

        if (retrace::profilingPixelsDrawn) {
            if (supportsTimestamp) {
                glGetQueryObjecti64v(query.ids[OCCLUSION], GL_QUERY_RESULT, &pixels);
            } else if (supportsElapsed) {
                glGetQueryObjecti64vEXT(query.ids[OCCLUSION], GL_QUERY_RESULT, &pixels);
            } else {
                uint32_t pixels32;
                glGetQueryObjectuiv(query.ids[OCCLUSION], GL_QUERY_RESULT, &pixels32);
                pixels = static_cast<int64_t>(pixels32);
            }
        }

    } else {
        pixels = -1;
    }

    if (retrace::profilingCpuTimes) {
        double cpuTimeScale = 1.0E9 / getTimeFrequency();
        cpuDuration = (query.cpuEnd - query.cpuStart) * cpuTimeScale;
        query.cpuStart *= cpuTimeScale;
    }

    if (retrace::profilingMemoryUsage) {
        vsizeDuration = query.vsizeEnd - query.vsizeStart;
        rssDuration = query.rssEnd - query.rssStart;
    }

    glDeleteQueries(NUM_QUERIES, query.ids);

    /* Add call to profile */
    retrace::profiler.addCall(query.call, query.sig->name, query.program, pixels, gpuStart, gpuDuration, query.cpuStart, cpuDuration, query.vsizeStart, vsizeDuration, query.rssStart, rssDuration);
}
Esempio n. 2
0
void MetricBackend_opengl::beginPass() {
    if (curPass == 1) {
        for (int i = 0; i < QUERY_BOUNDARY_LIST_END; i++) {
            for (auto &m : metrics) {
                if (m.enabled[i]) m.profiled[i] = true;
            }
        }
        // profile frames in first pass
        if (twoPasses) {
            if (!supportsTimestamp) {
                metrics[METRIC_GPU_DURATION].profiled[QUERY_BOUNDARY_DRAWCALL] = false;
                metrics[METRIC_GPU_DURATION].profiled[QUERY_BOUNDARY_CALL] = false;
            }
            metrics[METRIC_GPU_PIXELS].profiled[QUERY_BOUNDARY_DRAWCALL] = false;
            metrics[METRIC_GPU_PIXELS].profiled[QUERY_BOUNDARY_CALL] = false;
        }
    }
    else if (curPass == 2) {
        for (int i = 0; i < QUERY_BOUNDARY_LIST_END; i++) {
            for (auto &m : metrics) {
                m.profiled[i] = false;
            }
        }
        // profile calls/draw calls in second pass
        if (!supportsTimestamp) {
            if (metrics[METRIC_GPU_DURATION].enabled[QUERY_BOUNDARY_DRAWCALL]) {
                metrics[METRIC_GPU_DURATION].profiled[QUERY_BOUNDARY_DRAWCALL] = true;
            }
            if (metrics[METRIC_GPU_DURATION].enabled[QUERY_BOUNDARY_CALL]) {
                metrics[METRIC_GPU_DURATION].profiled[QUERY_BOUNDARY_CALL] = true;
            }
        }
        if (metrics[METRIC_GPU_PIXELS].enabled[QUERY_BOUNDARY_DRAWCALL]) {
            metrics[METRIC_GPU_PIXELS].profiled[QUERY_BOUNDARY_DRAWCALL] = true;
        }
        if (metrics[METRIC_GPU_PIXELS].enabled[QUERY_BOUNDARY_CALL]) {
            metrics[METRIC_GPU_PIXELS].profiled[QUERY_BOUNDARY_CALL] = true;
        }
    }
    // setup times
    cpuTimeScale = 1.0E9 / getTimeFrequency();
    baseTime = getCurrentTime() * cpuTimeScale;
}
Esempio n. 3
0
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);
    }
}
Esempio n. 4
0
/*
 * 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, &currentContext->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);
    }
}