[PATCH] glretrace: Use GL_TIMESTAMP (if available) for CPU profiling.

José Fonseca jose.r.fonseca at gmail.com
Thu Nov 15 11:20:57 PST 2012


Hi Carl,

On Thu, Nov 15, 2012 at 6:51 PM, Carl Worth <cworth at cworth.org> wrote:
> The prior scheme of trying to continuously re-synchronize separate CPU
> and GPU counters is doomed to always be unreliable. Instead, simply prefer
> to use the GL_TIMESTAMP values for both GPU and for CPU profiling.

Won't the CPU and GPU timings match 1:1 the same then?

The CPU start/end times are useful information. If they are always out
of sync with the GPU then instead of discarding them we should update
the GUI so that CPU and GPU time axis can vary independent.

Also, why are GPU counters doomed to be always be unreliable? Ignoring
theory of relativity, there should be only one time. What makes this
so technically impossible?

Jose

> ---
>  retrace/glretrace_main.cpp |   42 ++++++++++++++++++++++++++++++++----------
>  1 file changed, 32 insertions(+), 10 deletions(-)
>
> diff --git a/retrace/glretrace_main.cpp b/retrace/glretrace_main.cpp
> index 024a285..771eb27 100755
> --- a/retrace/glretrace_main.cpp
> +++ b/retrace/glretrace_main.cpp
> @@ -46,7 +46,7 @@ bool supportsARBShaderObjects = false;
>
>  struct CallQuery
>  {
> -    GLuint ids[3];
> +    GLuint ids[5];
>      unsigned call;
>      bool isDraw;
>      GLuint program;
> @@ -113,22 +113,30 @@ checkGlError(trace::Call &call) {
>  static void
>  getCurrentTimes(int64_t& cpuTime, int64_t& gpuTime) {
>      GLuint query;
> +    int64_t timestamp;
>
> -    if (retrace::profilingGpuTimes && supportsTimestamp) {
> +    if (supportsTimestamp) {
>          glGenQueries(1, &query);
>          glQueryCounter(query, GL_TIMESTAMP);
> -        glGetQueryObjecti64vEXT(query, GL_QUERY_RESULT, &gpuTime);
> +        glGetQueryObjecti64vEXT(query, GL_QUERY_RESULT, &timestamp);
> +    }
> +
> +    if (retrace::profilingGpuTimes && supportsTimestamp) {
> +        gpuTime = timestamp;
>      } else {
>          gpuTime = 0;
>      }
>
>      if (retrace::profilingCpuTimes) {
> -        cpuTime = os::getTime();
> +        if (supportsTimestamp)
> +            cpuTime = timestamp;
> +        else
> +            cpuTime = os::getTime();
>      } else {
>          cpuTime = 0;
>      }
>
> -    if (retrace::profilingGpuTimes && supportsTimestamp) {
> +    if (supportsTimestamp) {
>          glDeleteQueries(1, &query);
>      }
>  }
> @@ -151,15 +159,20 @@ completeCallQuery(CallQuery& query) {
>              glGetQueryObjecti64vEXT(query.ids[2], GL_QUERY_RESULT, &pixels);
>          }
>
> -        glDeleteQueries(3, query.ids);
>      } else {
>          pixels = -1;
>      }
>
>      if (retrace::profilingCpuTimes) {
> +        if (supportsTimestamp) {
> +            query.cpuStart = gpuStart;
> +            glGetQueryObjecti64vEXT(query.ids[3], GL_QUERY_RESULT, &query.cpuEnd);
> +        }
>          cpuDuration = query.cpuEnd - query.cpuStart;
>      }
>
> +    glDeleteQueries(4, query.ids);
> +
>      /* Add call to profile */
>      retrace::profiler.addCall(query.call, query.sig->name, query.program, pixels, gpuStart, gpuDuration, query.cpuStart, cpuDuration);
>  }
> @@ -182,10 +195,10 @@ beginProfile(trace::Call &call, bool isDraw) {
>      query.sig = call.sig;
>      query.program = glretrace::currentContext ? glretrace::currentContext->activeProgram : 0;
>
> +    glGenQueries(4, query.ids);
> +
>      /* GPU profiling only for draw calls */
>      if (isDraw) {
> -        glGenQueries(3, query.ids);
> -
>          if (retrace::profilingGpuTimes) {
>              if (supportsTimestamp) {
>                  glQueryCounter(query.ids[0], GL_TIMESTAMP);
> @@ -203,7 +216,11 @@ beginProfile(trace::Call &call, bool isDraw) {
>
>      /* CPU profiling for all calls */
>      if (retrace::profilingCpuTimes) {
> -       callQueries.back().cpuStart = os::getTime();
> +        CallQuery& query = callQueries.back();
> +
> +        if (! supportsTimestamp) {
> +            query.cpuStart = os::getTime();
> +        }
>      }
>  }
>
> @@ -214,7 +231,12 @@ endProfile(trace::Call &call, bool isDraw) {
>      /* CPU profiling for all calls */
>      if (retrace::profilingCpuTimes) {
>          CallQuery& query = callQueries.back();
> -        query.cpuEnd = time;
> +
> +        if (supportsTimestamp) {
> +            glQueryCounter(query.ids[3], GL_TIMESTAMP);
> +        } else {
> +            query.cpuEnd = time;
> +        }
>      }
>
>      /* GPU profiling only for draw calls */
> --
> 1.7.10
>
> _______________________________________________
> apitrace mailing list
> apitrace at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/apitrace


More information about the apitrace mailing list