00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "pipe/p_winsys.h"
00033 #include "u_timed_winsys.h"
00034 #include "util/u_memory.h"
00035 #include "util/u_time.h"
00036
00037
00038 struct timed_winsys {
00039 struct pipe_winsys base;
00040 struct pipe_winsys *backend;
00041 uint64_t last_dump;
00042 struct {
00043 const char *name_key;
00044 double total;
00045 unsigned calls;
00046 } funcs[13];
00047 };
00048
00049
00050 static struct timed_winsys *timed_winsys( struct pipe_winsys *winsys )
00051 {
00052 return (struct timed_winsys *)winsys;
00053 }
00054
00055
00056 static uint64_t time_start( void )
00057 {
00058 return util_time_micros();
00059 }
00060
00061
00062 static void time_display( struct pipe_winsys *winsys )
00063 {
00064 struct timed_winsys *tws = timed_winsys(winsys);
00065 unsigned i;
00066 double overall = 0;
00067
00068 for (i = 0; i < Elements(tws->funcs); i++) {
00069 if (tws->funcs[i].name_key) {
00070 debug_printf("*** %-25s %5.3fms (%d calls, avg %.3fms)\n",
00071 tws->funcs[i].name_key,
00072 tws->funcs[i].total,
00073 tws->funcs[i].calls,
00074 tws->funcs[i].total / tws->funcs[i].calls);
00075 overall += tws->funcs[i].total;
00076 tws->funcs[i].calls = 0;
00077 tws->funcs[i].total = 0;
00078 }
00079 }
00080
00081 debug_printf("*** %-25s %5.3fms\n",
00082 "OVERALL WINSYS",
00083 overall);
00084 }
00085
00086 static void time_finish( struct pipe_winsys *winsys,
00087 long long startval,
00088 unsigned idx,
00089 const char *name )
00090 {
00091 struct timed_winsys *tws = timed_winsys(winsys);
00092 uint64_t endval = util_time_micros();
00093 double elapsed = (endval - startval)/1000.0;
00094
00095 if (endval - startval > 1000LL)
00096 debug_printf("*** %s %.3f\n", name, elapsed );
00097
00098 assert( tws->funcs[idx].name_key == name ||
00099 tws->funcs[idx].name_key == NULL);
00100
00101 tws->funcs[idx].name_key = name;
00102 tws->funcs[idx].total += elapsed;
00103 tws->funcs[idx].calls++;
00104
00105 if (endval - tws->last_dump > 10LL * 1000LL * 1000LL) {
00106 time_display( winsys );
00107 tws->last_dump = endval;
00108 }
00109 }
00110
00111
00112
00113
00114
00115 static struct pipe_buffer *
00116 timed_buffer_create(struct pipe_winsys *winsys,
00117 unsigned alignment,
00118 unsigned usage,
00119 unsigned size )
00120 {
00121 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00122 uint64_t start = time_start();
00123
00124 struct pipe_buffer *buf = backend->buffer_create( backend, alignment, usage, size );
00125
00126 time_finish(winsys, start, 0, __FUNCTION__);
00127
00128 return buf;
00129 }
00130
00131
00132
00133
00134 static struct pipe_buffer *
00135 timed_user_buffer_create(struct pipe_winsys *winsys,
00136 void *data,
00137 unsigned bytes)
00138 {
00139 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00140 uint64_t start = time_start();
00141
00142 struct pipe_buffer *buf = backend->user_buffer_create( backend, data, bytes );
00143
00144 time_finish(winsys, start, 1, __FUNCTION__);
00145
00146 return buf;
00147 }
00148
00149
00150 static void *
00151 timed_buffer_map(struct pipe_winsys *winsys,
00152 struct pipe_buffer *buf,
00153 unsigned flags)
00154 {
00155 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00156 uint64_t start = time_start();
00157
00158 void *map = backend->buffer_map( backend, buf, flags );
00159
00160 time_finish(winsys, start, 2, __FUNCTION__);
00161
00162 return map;
00163 }
00164
00165
00166 static void
00167 timed_buffer_unmap(struct pipe_winsys *winsys,
00168 struct pipe_buffer *buf)
00169 {
00170 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00171 uint64_t start = time_start();
00172
00173 backend->buffer_unmap( backend, buf );
00174
00175 time_finish(winsys, start, 3, __FUNCTION__);
00176 }
00177
00178
00179 static void
00180 timed_buffer_destroy(struct pipe_winsys *winsys,
00181 struct pipe_buffer *buf)
00182 {
00183 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00184 uint64_t start = time_start();
00185
00186 backend->buffer_destroy( backend, buf );
00187
00188 time_finish(winsys, start, 4, __FUNCTION__);
00189 }
00190
00191
00192 static void
00193 timed_flush_frontbuffer( struct pipe_winsys *winsys,
00194 struct pipe_surface *surf,
00195 void *context_private)
00196 {
00197 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00198 uint64_t start = time_start();
00199
00200 backend->flush_frontbuffer( backend, surf, context_private );
00201
00202 time_finish(winsys, start, 5, __FUNCTION__);
00203 }
00204
00205
00206
00207
00208 static struct pipe_surface *
00209 timed_surface_alloc(struct pipe_winsys *winsys)
00210 {
00211 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00212 uint64_t start = time_start();
00213
00214 struct pipe_surface *surf = backend->surface_alloc( backend );
00215
00216 time_finish(winsys, start, 6, __FUNCTION__);
00217
00218 return surf;
00219 }
00220
00221
00222
00223 static int
00224 timed_surface_alloc_storage(struct pipe_winsys *winsys,
00225 struct pipe_surface *surf,
00226 unsigned width, unsigned height,
00227 enum pipe_format format,
00228 unsigned flags,
00229 unsigned tex_usage)
00230 {
00231 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00232 uint64_t start = time_start();
00233
00234 int ret = backend->surface_alloc_storage( backend, surf, width, height,
00235 format, flags, tex_usage );
00236
00237 time_finish(winsys, start, 7, __FUNCTION__);
00238
00239 return ret;
00240 }
00241
00242
00243 static void
00244 timed_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
00245 {
00246 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00247 uint64_t start = time_start();
00248
00249 backend->surface_release( backend, s );
00250
00251 time_finish(winsys, start, 8, __FUNCTION__);
00252 }
00253
00254
00255
00256 static const char *
00257 timed_get_name( struct pipe_winsys *winsys )
00258 {
00259 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00260 uint64_t start = time_start();
00261
00262 const char *ret = backend->get_name( backend );
00263
00264 time_finish(winsys, start, 9, __FUNCTION__);
00265
00266 return ret;
00267 }
00268
00269 static void
00270 timed_fence_reference(struct pipe_winsys *winsys,
00271 struct pipe_fence_handle **ptr,
00272 struct pipe_fence_handle *fence)
00273 {
00274 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00275 uint64_t start = time_start();
00276
00277 backend->fence_reference( backend, ptr, fence );
00278
00279 time_finish(winsys, start, 10, __FUNCTION__);
00280 }
00281
00282
00283 static int
00284 timed_fence_signalled( struct pipe_winsys *winsys,
00285 struct pipe_fence_handle *fence,
00286 unsigned flag )
00287 {
00288 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00289 uint64_t start = time_start();
00290
00291 int ret = backend->fence_signalled( backend, fence, flag );
00292
00293 time_finish(winsys, start, 11, __FUNCTION__);
00294
00295 return ret;
00296 }
00297
00298 static int
00299 timed_fence_finish( struct pipe_winsys *winsys,
00300 struct pipe_fence_handle *fence,
00301 unsigned flag )
00302 {
00303 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00304 uint64_t start = time_start();
00305
00306 int ret = backend->fence_finish( backend, fence, flag );
00307
00308 time_finish(winsys, start, 12, __FUNCTION__);
00309
00310 return ret;
00311 }
00312
00313 static void
00314 timed_winsys_destroy( struct pipe_winsys *winsys )
00315 {
00316 struct pipe_winsys *backend = timed_winsys(winsys)->backend;
00317 backend->destroy( backend );
00318 FREE(winsys);
00319 }
00320
00321
00322
00323 struct pipe_winsys *u_timed_winsys_create( struct pipe_winsys *backend )
00324 {
00325 struct timed_winsys *ws = CALLOC_STRUCT(timed_winsys);
00326
00327 ws->base.user_buffer_create = timed_user_buffer_create;
00328 ws->base.buffer_map = timed_buffer_map;
00329 ws->base.buffer_unmap = timed_buffer_unmap;
00330 ws->base.buffer_destroy = timed_buffer_destroy;
00331 ws->base.buffer_create = timed_buffer_create;
00332 ws->base.flush_frontbuffer = timed_flush_frontbuffer;
00333 ws->base.get_name = timed_get_name;
00334 ws->base.surface_alloc = timed_surface_alloc;
00335 ws->base.surface_alloc_storage = timed_surface_alloc_storage;
00336 ws->base.surface_release = timed_surface_release;
00337 ws->base.fence_reference = timed_fence_reference;
00338 ws->base.fence_signalled = timed_fence_signalled;
00339 ws->base.fence_finish = timed_fence_finish;
00340 ws->base.destroy = timed_winsys_destroy;
00341
00342 ws->backend = backend;
00343
00344 return &ws->base;
00345 }
00346