ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_timer_query / timestamp-get.c
blob39676c692c71251c17ff5bbd4a545eb9ea335325
1 /*
2 * Copyright © 2012 Marek Olšák <maraeo@gmail.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
24 #include "piglit-util-gl.h"
26 #include <inttypes.h> /* for PRIu64 macro */
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h> /* for usleep */
29 #endif
31 /* GL_TIMESTAMP isn't expected to be reliable for measuring long durations and
32 * although the ARB_timer_query spec doesn't stipulate what kind of drifting
33 * from wall clock time is acceptable, we at least want a sanity check that
34 * things look reasonable...
36 #define DRIFT_NS_PER_SEC_THRESHOLD 3000000
38 /**
39 * @file timestamp-get.c
41 * Test that GL_TIMESTAMP obtained via glGet and glQuery returns roughly
42 * the same value, and that durations measured via GL_TIMESTAMP have
43 * nanosecond units.
46 PIGLIT_GL_TEST_CONFIG_BEGIN
48 config.supports_gl_compat_version = 10;
49 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
50 config.khr_no_error_support = PIGLIT_NO_ERRORS;
52 PIGLIT_GL_TEST_CONFIG_END
54 static GLint64
55 get_gpu_time_via_query(GLuint q)
57 GLint64 time;
59 glQueryCounter(q, GL_TIMESTAMP);
60 glGetQueryObjecti64v(q, GL_QUERY_RESULT, &time);
61 return time;
64 static GLint64
65 get_gpu_time_via_get(GLuint q)
67 GLint64 time;
69 glGetInteger64v(GL_TIMESTAMP, &time);
70 return time;
73 static void
74 validate_times(GLint64 t1, GLint64 t2, GLint64 tolerance)
76 if (t1 > t2) {
77 printf("old time = %" PRIu64 " us\n", (uint64_t) t1 / 1000);
78 printf("new time = %" PRIu64 " us\n", (uint64_t) t2 / 1000);
79 puts("old time > new time");
80 piglit_report_result(PIGLIT_FAIL);
83 /* the tolerance of 1 milisecond seems to be sufficient */
84 if (t2 - t1 > tolerance) {
85 printf("time 1 = %" PRIu64 " us\n", (uint64_t) t1 / 1000);
86 printf("time 2 = %" PRIu64 " us\n", (uint64_t) t2 / 1000);
87 puts("too big difference");
88 piglit_report_result(PIGLIT_FAIL);
92 static void
93 validate_delta(GLint64 gl_ts1, GLint64 gl_ts2, GLint64 cpu_delay_ns)
95 GLint64 gl_ts_delta = gl_ts2 - gl_ts1;
96 int64_t drift = llabs(cpu_delay_ns - gl_ts_delta);
97 int64_t drift_per_sec = drift * 1000000000LL / cpu_delay_ns;
99 /* XXX: technically we shouldn't be as strict about drift when the gpu
100 * clock is running fast and the duration is longer than expected,
101 * because we can't easily exclude other factors like OS scheduling
102 * affecting the measurements. For now though we don't take this into
103 * account.
105 if (drift_per_sec > DRIFT_NS_PER_SEC_THRESHOLD) {
106 printf("GL_TIMESTAMP 1 = %" PRId64 " us\n", gl_ts1 / 1000);
107 printf("GL_TIMESTAMP 2 = %" PRId64 " us\n", gl_ts2 / 1000);
108 printf("delta = %" PRId64 " us (expect >= %"PRId64" us)\n",
109 gl_ts_delta / 1000, cpu_delay_ns / 1000);
111 piglit_loge("GL_TIMESTAMP drift of %" PRId64 " ns/sec, greater than %" PRId64 " ns/sec",
112 drift_per_sec,
113 (int64_t)DRIFT_NS_PER_SEC_THRESHOLD);
114 piglit_report_result(PIGLIT_FAIL);
115 } else
116 printf("GL_TIMESTAMP drift of approx. %" PRId64 " ns/sec\n",
117 drift_per_sec);
120 enum piglit_result
121 piglit_display(void)
123 GLint64 t1, t2;
124 GLint64 query_overhead, get_overhead, tolerance;
125 GLuint q;
126 int64_t delay;
128 glGenQueries(1, &q);
130 /* this creates the query in the driver */
131 get_gpu_time_via_query(q);
133 /* compute a reasonable tolerance based on driver overhead */
134 t1 = piglit_time_get_nano();
135 get_gpu_time_via_query(q);
136 query_overhead = piglit_time_get_nano() - t1;
138 t1 = piglit_time_get_nano();
139 get_gpu_time_via_get(q);
140 get_overhead = piglit_time_get_nano() - t1;
142 printf("glGet overhead: %" PRIu64 " us\n", (uint64_t) get_overhead / 1000);
143 printf("glQuery overhead: %" PRIu64 " us\n", (uint64_t) query_overhead / 1000);
145 /* minimum tolerance is 3 ms */
146 tolerance = query_overhead + get_overhead + 3000000;
148 /* do testing */
149 puts("Test: first glQuery, then glGet");
150 t1 = get_gpu_time_via_query(q);
151 t2 = get_gpu_time_via_get(q);
152 validate_times(t1, t2, tolerance);
154 usleep(10000);
156 puts("Test: first glGet, then glQuery");
157 t1 = get_gpu_time_via_get(q);
158 t2 = get_gpu_time_via_query(q);
159 validate_times(t1, t2, tolerance);
161 puts("Test: wall clock time via glQuery");
162 t1 = get_gpu_time_via_query(q);
163 delay = piglit_delay_ns(1000000000);
164 t2 = get_gpu_time_via_query(q);
165 validate_delta(t1, t2, delay);
167 puts("Test: wall clock time via glGet");
168 t1 = get_gpu_time_via_get(q);
169 delay = piglit_delay_ns(1000000000);
170 t2 = get_gpu_time_via_get(q);
171 validate_delta(t1, t2, delay);
173 glDeleteQueries(1, &q);
175 return PIGLIT_PASS;
178 void
179 piglit_init(int argc, char **argv)
181 piglit_automatic = true;
183 piglit_require_gl_version(20);
185 piglit_require_extension("GL_ARB_timer_query");