/**************************************************************************
*
* Copyright 2011 Jose Fonseca
+ * Copyright (C) 2013 Intel Corporation. All rights reversed.
+ * Author: Shuang He <shuang.he@intel.com>
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
#include "glstate.hpp"
#include "glretrace.hpp"
#include "os_time.hpp"
+#include "os_memory.hpp"
/* Synchronous debug output may reduce performance however,
* without it the callNo in the callback may be inaccurate
bool insideList = false;
bool insideGlBeginEnd = false;
+bool supportsARBShaderObjects = false;
enum {
GPU_START = 0,
const trace::FunctionSig *sig;
int64_t cpuStart;
int64_t cpuEnd;
+ int64_t vsizeStart;
+ int64_t vsizeEnd;
+ int64_t rssStart;
+ int64_t rssEnd;
};
static bool supportsElapsed = true;
}
}
-static void
-getCurrentTimes(int64_t& cpuTime, int64_t& gpuTime) {
- GLuint query = 0;
-
- if (retrace::profilingGpuTimes && supportsTimestamp) {
- glGenQueries(1, &query);
- glQueryCounter(query, GL_TIMESTAMP);
- GLint64 timestamp = 0;
- glGetQueryObjecti64vEXT(query, GL_QUERY_RESULT, ×tamp);
- gpuTime = timestamp;
- } else {
- gpuTime = 0;
- }
-
- if (retrace::profilingCpuTimes) {
- cpuTime = getCurrentTime();
- } else {
- cpuTime = 0;
- }
+static inline void
+getCurrentVsize(int64_t& vsize) {
+ vsize = os::getVsize();
+}
- if (retrace::profilingGpuTimes && supportsTimestamp) {
- glDeleteQueries(1, &query);
- }
+static inline void
+getCurrentRss(int64_t& rss) {
+ rss = os::getRss();
}
static void
completeCallQuery(CallQuery& query) {
/* Get call start and duration */
- int64_t gpuStart = 0, gpuDuration = 0, cpuDuration = 0, pixels = 0;
+ int64_t gpuStart = 0, gpuDuration = 0, cpuDuration = 0, pixels = 0, vsizeDuration = 0, rssDuration = 0;
if (query.isDraw) {
if (retrace::profilingGpuTimes) {
}
if (retrace::profilingCpuTimes) {
- cpuDuration = query.cpuEnd - query.cpuStart;
+ 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);
+ retrace::profiler.addCall(query.call, query.sig->name, query.program, pixels, gpuStart, gpuDuration, query.cpuStart, cpuDuration, query.vsizeStart, vsizeDuration, query.rssStart, rssDuration);
}
void
CallQuery& query = callQueries.back();
query.cpuStart = getCurrentTime();
}
+
+ if (retrace::profilingMemoryUsage) {
+ CallQuery& query = callQueries.back();
+ query.vsizeStart = os::getVsize();
+ query.rssStart = os::getRss();
+ }
}
void
glEndQuery(GL_SAMPLES_PASSED);
}
}
+
+ if (retrace::profilingMemoryUsage) {
+ CallQuery& query = callQueries.back();
+ query.vsizeEnd = os::getVsize();
+ query.rssEnd = os::getRss();
+ }
}
void
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) {
/* Sync the gpu and cpu start times */
if (retrace::profilingCpuTimes || retrace::profilingGpuTimes) {
if (!retrace::profiler.hasBaseTimes()) {
- GLint64 gpuTime, cpuTime;
-
- getCurrentTimes(cpuTime, gpuTime);
- retrace::profiler.setBaseCpuTime(cpuTime);
- retrace::profiler.setBaseGpuTime(gpuTime);
+ 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);
+ }
}
void
/* Complete any remaining queries */
flushQueries();
- /* GPU time drifts due to being relative times, not absolute and can be
- * affected by the gpu switch between processes.
- *
- * To attempt to compensate we resynchronise on frame end however there is
- * still noticeable drift within a single frame which we do not account for.
- */
- if (retrace::profilingCpuTimes || retrace::profilingGpuTimes) {
- int64_t cpuTime, gpuTime, error;
-
- getCurrentTimes(cpuTime, gpuTime);
- cpuTime = cpuTime - retrace::profiler.getBaseCpuTime();
- gpuTime = gpuTime - retrace::profiler.getBaseGpuTime();
- error = gpuTime - cpuTime * (1.0E9 / getTimeFrequency());
- std::cerr << "error = " << error << "\n";
-
- if (0) {
- retrace::profiler.setBaseGpuTime(retrace::profiler.getBaseGpuTime() + error);
- }
- }
-
/* Indicate end of current frame */
retrace::profiler.addFrameEnd();
}
void
retrace::waitForInput(void) {
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
+ if (currentContext) {
+ glretrace::flushQueries();
+ glFlush();
+ }
while (glws::processEvents()) {
os::sleep(100*1000);
}