Carl Worth [Wed, 23 Oct 2013 01:47:40 +0000 (18:47 -0700)]
Fix for an implementation with non-contiguous group ID values.
It seems crazy to me that group IDs (being integers) can be anything
other than [0 .. num_groups - 1], but the specification is written
with full generality here.
The code was already querying the group ID values originally, and
assigning those to each group->id slot in the metric_group_info_t
structure. But after that, the code had been assuming it could just
use values from 0 .. num_groups-1.
Fix this by carefully using group_index values ([0..num_groups-1])
when indexing into the various arrays and group->id values when
passing ID values to the various performance-monitor API functions.
Carl Worth [Wed, 23 Oct 2013 00:44:04 +0000 (17:44 -0700)]
Free all fip-allocated data when the program exits
This isn't strictly necessary since the operating system is about to
reclaim all of this data anyway.
The only real advantage of doing this is that it enables us to see in
a valgrind report that there aren't any memory leaks due to direct
allocation by code within fips.
Carl Worth [Wed, 23 Oct 2013 00:23:46 +0000 (17:23 -0700)]
Print performance-counter names in report
This isn't necessarily a very useful way to see the numbers. The
important part of the code here is that fips is now querying the names
so that it can do some useful interpretation of the values based on
the names.
Carl Worth [Tue, 22 Oct 2013 23:30:34 +0000 (16:30 -0700)]
Un-nest an inner loop while printing program metrics
Before we add more code to complicate the way we print performance
counters, it helps to have this code in its own function, (where we
can safely use 'i' instead of 'j' for loop-control variable, etc.).
There was an extra 's' in here before (GroupsString instead of
GroupString), preventing these functions from being used
correctly. Fix this, (since fips will soon be using this function).
Carl Worth [Tue, 22 Oct 2013 19:19:37 +0000 (12:19 -0700)]
Respect GLAZE_LIBGL environment variable (if FIPS_LIBGL is unset)
Since the LD_PRELOAD mechanism of fips may not work with some
programs, users may want to run fips within glaze instead, (which uses
LD_LIBRARY_PATH instead of LD_PRELOAD). In order to make this
convenient, fips can recognize that glaze has identified the
appropriate libGL.so library by examining the GLAZE_LIBGL environment
variable.
So, if the user has not specifically set the FIPS_LIBGL variable, and
the GLAZE_LIBGL variable is set, use it to find the libGL.so to load.
Carl Worth [Tue, 22 Oct 2013 19:18:23 +0000 (12:18 -0700)]
Ensure that the name "fips" appears in all error messages.
With the number of wrappers potentially involved, (fips, glaze,
apitrace, etc.), sometimes it can be ambiguous which error messages
belong to which wrappers.
Ensure that fips, at least, always advertises its own name in its
error messages.
Carl Worth [Tue, 22 Oct 2013 18:04:25 +0000 (11:04 -0700)]
Add collection of (AMD_performance_monitor) performance counters to fips
The implementation involves a linked-list of outstanding
performance-monitor queries next to the existing list of outstanding
timer queries.
The results from the performance counters are stored (without any
interpretation in an array of values next to the existing time values
within each op_metrics_t value for each operation.
The numbers are currently printed with simple counter numbers (no
names and no units) and with the values divided by 1e6. Counters with
values of zero are not printed.
Next steps from here that will make things useful:
1. Use relative number of cycels in each stage to apportion measured
shader time among the various stages, (so that per-stage time
numbers are sorted in the final report).
2. Print percentage active, (by looking at per-stage active and stall times)
3. Print names for counters (other than per-stage active and stall
which will be used in the above two calculations).
4. Fix to silently ignore performance counters if the
AMD_performance_monitor extension is not available.
Carl Worth [Tue, 22 Oct 2013 17:41:16 +0000 (10:41 -0700)]
fips-dispatch: Simplify dispatch code by abstracting resolve functions
All of the resolve functions were structured identically, so rather
than repating the function bodies over and over, we can use a simple
"resolve" macro to implement this code. This gives a net reduction in
source code for better readability and maintainability.
Carl Worth [Wed, 16 Oct 2013 20:03:15 +0000 (13:03 -0700)]
Restore metrics op after temporarily changing for non-shader operation
This fixes the bug where an operation such as glClear would
incorrectly accrue all subsequent time until the next call to
glUseProgram would change the op away from glClear.
Now, each non-shader operation that changes the metrics operation
restores it to its previous value immediately afterward.
Carl Worth [Wed, 16 Oct 2013 03:23:08 +0000 (20:23 -0700)]
Aggregate non-shader GPU operations into their own operations
These operations are named after representative functions, (glClear,
glReadPixels, etc.). Aggregate time spent in any of these operations
is sorted together with the existing reports for time spent in
particular shader programs.
The shader program times should now be more accurate since time spent
in operations such as glClear will now no longer be accumulated into
the most recently-used shader.
Carl Worth [Tue, 15 Oct 2013 20:45:06 +0000 (13:45 -0700)]
Rework timer queries to run continuously.
Previously, we ran timer queries only around gl calls that we
determined were "drawing operations". This had the following
drawbacks:
1. Lots of timer queries, so more overhead than desired
2. Misses accumulating time from non "drawing operations"
3. Misses accumulating time from drawing operations we failed to
identify.
Here, instead, we keep the timer running continuously, solving all
three of the above problems. We first start timer at make-current time
(glxMakeCurrent, glxMakeContextCurrent, or eglMakeCurrent), and only
stop it, (and immediately restart it), in one of the following
circumstances:
1. Current program changed (glUseProgram or glUseProgramObjectARB)
2. At each frame end (glxSwapBuffers or eglSwapBuffers)
Carl Worth [Tue, 15 Oct 2013 20:20:33 +0000 (13:20 -0700)]
Simplify metrics interface by dropping metrics_counter_new
None of the callers of this function were doing anything with the
returned value other than passing it directly to
metrics_counter_start. So it's simpler to just fold the contents of
the metrics_counter_new function into the body of
metrics_counter_start itself.
Carl Worth [Mon, 7 Oct 2013 22:57:34 +0000 (15:57 -0700)]
metrics: Use a more meaningful field name.
I had "ticks" here before I knew the units of the timer-query
result. Since then, Eric dug up the documentation saying that this
timer reports time in nanoseconds. So use a field name of "time_ns"
rather than "ticks".
Eric Anholt [Tue, 27 Aug 2013 18:43:40 +0000 (11:43 -0700)]
Report what the actual units are.
"When the timer query timer is finally stopped, the elapsed time
(in nanoseconds) is written to the corresponding query object as
the query result value"
Carl Worth [Mon, 7 Oct 2013 22:39:12 +0000 (15:39 -0700)]
configure: Fix generated comment for BINDIR_TO_LIBFIPSDIR
The variable names were misspelled before, (incorrect case), so the
comment was being generated with empty values for the two variables,
(making it less than useful).
Carl Worth [Tue, 27 Aug 2013 20:14:53 +0000 (13:14 -0700)]
glxwrap: Initialize fips_dispatch when glxMakeContextCurrent is called
Previously, we only intitialized fips_dispatch if glxMakeCurrent was
called. This caused fips to fail for programs that called
glxMakeContextCurrent instead. Both functions are now handled
indentically, (giving fips a clear indication that GLX is being used,
not EGL).
This fixes the failure of fips with Lightsmark 2008.
Carl Worth [Mon, 5 Aug 2013 17:23:10 +0000 (10:23 -0700)]
dlwrap: Add new dlwrap_dlopen_libfips function
Previously, two different pieces of fips code (both for dlopen and for
glXGetProcAddress) both needed to dlopen the fips library
itself. However, the two pieces were implemented differently, (one
passed a symbol to dladdr to find a filename to dlopen, the other just
passed NULL to dlsym and hopef for the best).
Make things consistent by having a single, shared implementation in
the new function dlwrap_dlopen_libfips, (and implement it with the
more reliable approach of calling dladdr and then the real dlopen).
Carl Worth [Wed, 3 Jul 2013 00:38:28 +0000 (17:38 -0700)]
dlwrap: Add "libGLESv2.so" to the list of supported wrapped libraries
This hooks up libGLESv2 to all of our dlsym machinery. It ensures that
we can intercept any dlsym calls into libGLESv2. It also ensures that
when glwrap looks for underlying, "real", GL functions it will look
into libGLESv2.so if that's the library that the application has
previously dlopened.
This commit fixes the egl-glesv2-dlopen-dlsym and
egl-glesv2-dlopen-gpa tests in the test suite.
Carl Worth [Tue, 2 Jul 2013 20:07:40 +0000 (13:07 -0700)]
test: Add 4 tests using EGL and OpenGLESv2
These are similar variants to the four existing tests using EGL and OpenGL.
To add these tests we add a new configure-time check to find the
compilation flags for GLESv2. We also drop the set_2d_projection code
which was using glLoadIdentity, glMatrixMode, and glOrtho functions
which apparently don't exist in GLESv2. So common.s and all tests with
custom wrappers are modified to drop these calls.
As with the egl-opengl tests, all new tests except for the dlsym-based
test pass. That's not too surprising since there are so many twisty
paths in trying to get all the dlopen/dlsym stuff to work correctly.
Carl Worth [Wed, 3 Jul 2013 00:33:12 +0000 (17:33 -0700)]
glwrap: Don't hardcode "libGL.so.1" for looking up real OpenGL symbols
As preparation for testing using GLESv2 we need to ensure that our GL
wrappers are prepared for an OpenGL implementation in either the
libGL.so.1 library or in libGLESv2.so.2.
When the application is directly linked to an OpenGL implementation,
we don't care about the name at all. In this case, we can simply call
dlsym with RTLD_NEXT to find the real, underlying OpenGL symbols.
But when an application uses dlopen to load the OpenGL library, we
want to carefully call dlsym with a handle for the same library that
the application uses. Previously, the glwrap code was unconditionally
calling dlopen for "libGL.so" and that's not what we want.
Instead, we now have our dlopen wrapper watch for any dlopen of a
library whose name begins with "libGL" and then stashing the returned
handle via a new glwrap_set_gl_handle call. The stashed handle will
then be used by dlsym calls within glwrap.
Carl Worth [Tue, 2 Jul 2013 19:45:18 +0000 (12:45 -0700)]
configure: Drop broken workarounds for missing pkg-config
Any reasonably-modern system should have versions of things like OpenGL
libraries installed with pkg-config libraries.
Regardless, the checks we had in place here for missing gl.pc files
were untested and obviously not very useful, (they didn't actually
look around anywhere for GL headers nor for GL libraries).
We're better off not even pretending to be able to find things without
pkg-config.
Carl Worth [Tue, 2 Jul 2013 19:28:03 +0000 (12:28 -0700)]
fips: Fix dlsym wrapper for egl symbols
Previously, fips was failing to provide its own wrapped versions for
functions such as eglMakeCurrent if the application was using dlsym to
locate the symbol. This led to the failure of the egl-opengl-dlopen-*
tests in the test suite.
The root of the problem was that the fips wrapper for dlopen was only
returning the libfips_handle if dlopen was requested for
"libGL.so". But here, we need to also intercept a dlopen for
"libEGL.so" as well.
However, the fix is not as simple as updating dlopen.
Previously, if dlsym failed to find a libfips-specific version of the
symbol of interest it would defer unconditionally to a call to the
real dlsym with a handle dlopened from "libGL.so". That's obviously
the wrong thing for symbols sougth from "libEGL.so". So, now, our
dlopen caches the originally dlopen'ed handles and encodes an index
into its return value so that the final dlsym can reference the
correct handle in order to find its symbol.
This commit fixes the egl-opengl-dlopen-dlsym and
egl-opengl-dlopen-gpa test cases.
Carl Worth [Tue, 2 Jul 2013 18:53:52 +0000 (11:53 -0700)]
test: Add remaining three egl-opengl tests
In a previous commit message, I had suggested we would be adding five
additional tests here. But unlike GLX, EGL provides only
eglGetProcAddress, (and no eglGetProcAddressARB), so two of the GLX
variants don't apply.
The two dlopen-based tests are currently failing when run under fips,
so once again the test suite has come through and found another bug.
Carl Worth [Tue, 2 Jul 2013 00:44:14 +0000 (17:44 -0700)]
test: Add support for EGL-based test, (and one EGL-based test)
For this, common.c now supports a new macro COMMON_USE_EGL which can
optionally be defined by the test before including common.c.
Some aspects of the common.c interface have changed slightly, (the
create_context call is now either create_glx_context or
create_egl_context, and the caller must explicitly call the new
common_make_current call).
This commit adds a single egl-based test, (egl-opengl-link-call),
which is similar to the existing gl-link-call test. This is basically
to ensure that the new code in common.c is functional.
We plan to follow up with egl-opengl variants for the remaining 5
existing gl tests, (and then egl-glesv2 variants for all 6 as well).
Carl Worth [Mon, 1 Jul 2013 18:22:17 +0000 (11:22 -0700)]
util-x11: Rework init_window interface to accept XVisualInfo
This is a much more correct way of doing things. Previously, we would select
a visual when creating the OpenGL context, but then use a default visual when
creating a window. This was fragile and would fail if the default visual was
not identical to what we had created.
Now, instead, we pass the selected XVisualInfo to our init_window interface
and call XCreateWindow instead of XCreateSimpleWindow. This guarantees that
the visuals match as required.
Carl Worth [Mon, 1 Jul 2013 17:43:50 +0000 (10:43 -0700)]
test: Rename util.c and util.h to util-x11.c and util-x11.h
These utility functions are all specific to the libX11 interface already,
and since we're planning to add some other utility functions soon, (such
as EGL), it will help to not have a too-generic name already used.
While doing this, also split up the interfaces for Display and Window
creation. This will allow us to create the GL context in between to
guarantee that the Window is created with the same visual as the GL
context.
Carl Worth [Thu, 27 Jun 2013 22:20:45 +0000 (15:20 -0700)]
test: Reduce code duplication in test-suite programs
All of the test suite programs previously had their own copies of
common drawing code. Now, this code is put into a shared
handle-events.c. Each test program includes handle-events and can
provide its own prefix for called OpenGL functions by first defining
HANDLE_EVENTS_GL_PREFIX.
Carl Worth [Thu, 27 Jun 2013 20:26:59 +0000 (13:26 -0700)]
fips: Add the beginning of a test suite
So far, there's just one test program. It links against libGL.so and
uses GLX to render a few solid frames. The test suite ensures that it
can be run and that "fips --verbose" actually prints a message.
Carl Worth [Thu, 27 Jun 2013 20:23:55 +0000 (13:23 -0700)]
fips: Add a -v/--verbose flag.
The only real purpose imagined for this for now is to be able to
verify that fips is actually doing something, (for example, if a
program renders less than 60 frames and exits then previous fips would
exit silently).
The --verbose flag will be useful with the upcoming test suite and its
short-lived programs.
Carl Worth [Thu, 27 Jun 2013 03:46:40 +0000 (20:46 -0700)]
configure: Set GL_LDFLAGS and EGL_LDFLAGS in configure script
The libfips library doesn't link directly to libGL nor libEGL so
didn't need these flags. But we're adding test programs that do link
to these, so the test's Makefile needs access to these flags.
Carl Worth [Thu, 27 Jun 2013 01:18:52 +0000 (18:18 -0700)]
Push final collection of CFLAGS/LDFLAGS from Makefile.config to Makefile.local
This makes the final decision more explicit closer to where the flags
are actually being used. This will be helpful as we add other
programs, which can now easily mimic the style of flags collection as
is done for fips.
This also eliminates any potential confusion of FIPS_FLAGS
vs. FINAL_FIPS_FLAGS, etc. The use of "FINAL_" has now been entirely
eliminated.
Carl Worth [Mon, 24 Jun 2013 22:49:44 +0000 (15:49 -0700)]
eglwrap: Add comment describing why we don't lookup into libGLESv2.so
A user recently asked me why we didn't perform lookups in
libGLESv2.so, (instead of just libEGL.so). I actually made the mistake
of writing code to do that before I realized the answer.
Adding the answer in a comment here should help me avoid making that
mistake again.
Carl Worth [Mon, 24 Jun 2013 22:44:47 +0000 (15:44 -0700)]
EGL: Add wrapper for eglGetProcAddress
If an EGL-using program uses eglGetProcAddress to locate functions, we
want to intercept that to return our own versions of the functions,
(to add out metrics timings, etc.).
If the requested function is not implemented in our library, just
defer to the real, underlying eglGetProcAddress function to find the
symbol.
Carl Worth [Mon, 24 Jun 2013 22:27:50 +0000 (15:27 -0700)]
configure: Fix configure check to look for egl.h in the correct directory
This configure check was broken by looking for GL/egl.h instead of
EGL/egl.h as it should. This failure was masked on any system with an
EGL implementation providing a pkg-config file (egl.pc).
Carl Worth [Mon, 24 Jun 2013 20:22:59 +0000 (13:22 -0700)]
fips-dispatch: Completely separate fips-dispatch GL prototypes from GL/gl.h
Move the OpenGL prototypes previously in fips-dispatch.h to a new
fips-dispatch-gl.h. The idea here is that any given file should
include only one of GL/gl.h or fips-dispatch-gl.h.
Files that implement libfips wrappers for OpenGL functions include
GL/gl.h to ensure that they implement functions with the correct
prototypes.
Meanwhile, files that call into OpenGL functions at run-time, (such as
metrics.c which calls the various OpenGL query-related functions),
instead include fips-dispatch-gl.h and do not include GL/gl.h. With
this approach, any new calls to OpenGL functions will cause
compilation warnings if the stubs are not also added to
fips-dispatch-gl.h.
Carl Worth [Sat, 22 Jun 2013 00:10:03 +0000 (17:10 -0700)]
Add dynamic dispatch for any calls to OpenGL functions.
Previously, fips code was making direct calls to OpenGL functions,
(such as glGenQueries, glBeinQuery, etc. within metrics.c). Some
OpenGL implementations do not export these symbols directly,
(expecting the application to instead look the symbols up via a call
to glXGetProcAddressARB or eglGetProcAddress).
The new fips-dispatch code added here does precisely that, (and adds
wrapper for both glXMakeCurrent and eglMakeCurrent in order to know
which GetProcAddress function should be called).
The dispatch code follows the model of piglit-dispatch, (available
under the same license as fips). Thanks to Eric Anholt for suggesting
following the same approach as piglit.
Carl Worth [Mon, 24 Jun 2013 20:19:41 +0000 (13:19 -0700)]
configure: Fix to have compiler warnings enabled while building libfips
In commit e42d9f224a4ef2784f8fd43f9f4f5c593a7ddd57 , when the flags
were split between fips and libfips, the warnings flags were
mistakenly applied to both CFLAGS and LDFLAGS of fips. (What was
actually intended was to have the warnings applied to the CFLAGS of
both fips and libfips).
Carl Worth [Fri, 14 Jun 2013 18:29:33 +0000 (11:29 -0700)]
TODO: Add some additional items suggested by Eero.
Again, simply trying to ensure that good ideas that come in via email
don't get dropped on the floor.
Report shader compilation time.
+Report elapsed time per frame.
+
+Add options to control which metrics should be collected.
+
Add Eric's tiny hash table for collecting per-shader statistics
Carl Worth [Fri, 14 Jun 2013 18:11:42 +0000 (11:11 -0700)]
TODO: Remove bug causing libfips-32.so to not build.
The configure script now checks for this problem and won't attempt to
build a non-native-arch libfips if the toolchain pieces, (such as the
gcc-multilib package), are not in place.
Carl Worth [Fri, 14 Jun 2013 06:29:07 +0000 (23:29 -0700)]
configure: Fully separate CFLAGS/LDFLAGS between fips and libfips
The top-level program and the underlying library have fundamentally
different requirements. For example, the top-level program needs to
link against libtalloc and libelf but the library does not.
Previously, the necessary flags for both were mixed together in
CONFIGURE_CFLAGS and CONFIGURE_LDFLAGS. This caused the library to
unnecessarily link against libtalloc and libelf, (which in turn caused
problems since the library is compiled as both 32-bit and 64-bit but
the system may not provide both 32- and 64-bit versions of these
libraries).
By splitting things up into separate FIPS_LDFLAGS vs. LIBFIPS_LDFLAGS,
etc. we can keep the dependencies down to what is really required and
eliminate several sprious failure cases.
Carl Worth [Fri, 14 Jun 2013 05:02:45 +0000 (22:02 -0700)]
Add more detailed warning if libfips binary could not be found.
Since we now may not compile a non-native bit-size libfips, (such as
not compiling libfips-32.so on a native 64-bit install), then fips can
fail when trying to wrap a 32-bit application.
So be kind and suggest that the user install gcc-multilib and
re-compile fips as one potential solution for this problem.
Carl Worth [Thu, 13 Jun 2013 22:39:30 +0000 (15:39 -0700)]
configure: Move the code which detects compiler warning options
For no good reason, this code was previously stuck right in the middle
of code reporting the final results of previous checks, (after the
case reporting that errors were found and before the case reporting
that no errors were found).
It's more clean to have the warning-option detection happen before any
of that reporting.
Carl Worth [Thu, 13 Jun 2013 22:00:49 +0000 (15:00 -0700)]
configure: Add an early check for a functional C compiler
Without this, later compiler-based checks for header files, etc. would
falsely claim that libraries were not installed, (when in fact, the
libraries were installed but the compiler-based checks were failing
because no compiler is available).
Carl Worth [Thu, 13 Jun 2013 21:26:08 +0000 (14:26 -0700)]
configure: Move the error message for pkg-config earlier
Once pkg-config cannot be found, there's no point in running the rest
of the configure script since it will just spew a bunch of errors due
to missing pkg-config.
So, stop early and let the user know that pkg-config needs to be
installed.
Carl Worth [Wed, 12 Jun 2013 23:22:06 +0000 (16:22 -0700)]
Fix to actually load the real libGL.so when the application asks for it.
Our wrapper library intercepts calls to dlopen "libGL.so" and returns
a handle to itself. That's correct, and as intended.
Before doing this, however, it's essential to actual dlopen "libGL.so"
for real even though we won't be returning a handle to it. This
ensures that any side effects from that dlopen are taken care of.
This fixes a bug where "fips apitrace replay foo.trace" would cause
Mesa to fail to load its driver as follows (with LIBGL_DEBUG=verbose):
Carl Worth [Wed, 12 Jun 2013 00:18:12 +0000 (17:18 -0700)]
Switch from glGetQueryObjectiv to glGetQueryObjectuiv
The latter is available in OpenGL ES 3 while the former is not.
We don't really care about the signedness either way, (we're fetching
a Boolean), so sticking consistently to the unsigned version provides
better portability with no downside.
Carl Worth [Mon, 10 Jun 2013 21:40:43 +0000 (14:40 -0700)]
Add a new GLWRAP_DEFER_WITH_RETURN macro.
This allows for the elimination of some code duplication from our
implementation of glXGetPrcAddressARB. The previous implementation
duplicated code from glwrap_lookup simply because the GLWRAP_DEFER
macro did not provide access to the return value of the wrapped
function.
With the new macro, (very much like GLWRAP_DEFER but accepting a
parameter for a variable to accept the return value), we can eliminate
this code duplication.
Of course, our symbol-extraction script is now a bit more complicated
since it has to find occurrences of DEFER_WITH_RETURN in addition to
occurrences of DEFER, and pull out the function name as the second
argument rather than the first.
Carl Worth [Mon, 10 Jun 2013 21:34:26 +0000 (14:34 -0700)]
Remove typedef for fips_glXGetProcAddressARB_t
There were two problems with this typedef. First, we don't actually
need it, (we define it here and then use it exactly once on the next
line---it's simpler to have the direct syntax for a function returning
a pointer to a function accepting void and returning void.
More importantly, the typedef was relying on the type __GLXextFuncPtr
being defined. This happens to work with Mesa on my system but is
inherently fragile. So the code is more robust not relying on this.
Carl Worth [Thu, 30 May 2013 22:10:15 +0000 (15:10 -0700)]
Makefile: Automatically generate libfips.sym symbol map
Previously, we had to manually maintain this table of symbols, (hence
it was too easy for the list to be stale). Instead, we now generate
the list automatically by examining the source code for symbols that
are wrapped.
These were previously commented out with a "FIXME" comment. I don't
recall now what original problem I ran into when trying to add these,
but they seem to work fine now.
Carl Worth [Thu, 30 May 2013 21:05:08 +0000 (14:05 -0700)]
metrics: Collect new timer-query results before report
The timers from the most-recently-completed frame may not yet be
complete, but still, for the most accurate reports, we now collect all
available timer values before printing the report.
Carl Worth [Thu, 30 May 2013 19:55:26 +0000 (12:55 -0700)]
dlwrap: Fix dlwrap_real_dlopen to only perform dlsym-lookup once
Making the real_dlopen variable static means that we perform the dlysm
lookup only once and then re-use the result for later calls. This is
what was always intended for this code.
Carl Worth [Fri, 24 May 2013 18:11:15 +0000 (11:11 -0700)]
Avoid inserting timer queries while constructing a display list
We only want to time actual drawing operations. When between glNewList
and glEndList, calls that look like drawing operations are not really,
instead these are just calls that are being recorded to be later
executed with glCallList. (And it won't work to put our timer queries
inside the display list.)
So, track when we are within glNewList/glEndList and don't add timer
queries. Instead, we will time these operations as a whole with a
timer query around the glCallList call itself.
Carl Worth [Thu, 23 May 2013 21:22:42 +0000 (14:22 -0700)]
Add several missing symbols to the libfips symbol map.
I'm not sure why these weren't added before, but without these in the
map, these calls were not being successfully wrapped, so these calls
were not being timed as they should have been.
In the future we should automatically generate the symbol list to
avoid any similar problems.
Carl Worth [Mon, 6 May 2013 18:57:24 +0000 (11:57 -0700)]
Remove useless fork before executing wrapped program.
The fork did nothing for us since the parent simply waited on the child
and then exited. It's simpler to simply exec the wrapped program, (which
simplifies running fips within a debugger, etc.).
Carl Worth [Mon, 6 May 2013 18:18:33 +0000 (11:18 -0700)]
Move metrics-tracking code from glwrap.c to new metrics.c
We're moving toward having separate *wrap.c files for each flavor of GL,
(glwrap.c, glxwrap.c, and eglwrap.c). But this metrics-tracking code is
generic to all of those so belongs in a separate module.
Carl Worth [Thu, 2 May 2013 21:33:12 +0000 (14:33 -0700)]
Reduce code duplication with with new 'glwrap_lookup' function.
We already had two copies of 'lookup', (and were anticipating additional
modules which needed it as well). The DEFER macro is now also exported
as GLWRAP_DEFER for use in additional modules.
Carl Worth [Mon, 29 Apr 2013 21:54:52 +0000 (14:54 -0700)]
configure: Add checks for GL/gl.h
Previously, the compile would just forge ahead assuming GL/gl.h was present.
Now, at configure time, actually look for gl.h, (first, by looking for
a pkg-config "gl" package, otherwise, trying to just test-compile
something with a #include <GL/gl.h>).
If things aren't found at configure time, tell the user which packages
to install.
Carl Worth [Mon, 29 Apr 2013 20:23:58 +0000 (13:23 -0700)]
Fix glwrap.c to workaround 'const' changes in OpenGL headers.
Not all OpenGL headers are created equal. Some include more "const"
keywords than others, and we don't know wheter the headers we are
compiling against include the extra "const". We force all to be equal
by using the preprocessor to remove all "const" keywords altogether.
And in each wrapper we fire of a glBeginQuery/glEndQuery measurement around
the call to measure how much GPU time is consumed by the call. At the end
of each frame, we capture all available query results and accumulate those
into per-shader-program counters based on the currently active program,
(which we track by wrapping glUseProgram and glUseProgramObjectARB).
Finally, every 60 frames, we print out a simple report showing the
accumulated time for each shader program.
The report could very easily become more sophisticated. Here are some
obvious ideas:
1. Sort the report so that the most active shaders are reported first
2. Come up with some real units for the report values rather than mega-ticks
3. Report relative execution time as percentages
4. Clear the screen for each report, (with ncurses)
5. Dump the source for the shaders themselves to a file for easy inspection
Without any of the above, things are fairly raw for now, but are
perhaps still useful.
Carl Worth [Thu, 25 Apr 2013 05:55:01 +0000 (22:55 -0700)]
Generalize glXGetProcAddressARB wrapper to work for all wrapper functions
The originally implementation here had a whitelist of function names for
which we would return a wrapped symbol, (a very short whitelist consisting
only of "glXSwapBuffers"). A hard-coded list here would be a maintenance
nightmare.
Instead, we now simply perform a dlsym lookup on the wrapper library itself
and if there's a function that exists in the library matching the name
being requested, we return that.
This way we can add functions to our wrapper library without needing to
change the implementation of glXGetProcAddressARB at all.
Carl Worth [Wed, 24 Apr 2013 22:28:43 +0000 (15:28 -0700)]
Add a simple fips.h file.
This pulls in a few widely-used header files, (config.h, stdio.h,
stdlib.h, and string.h), and also gives us a place to define common
macros such as unused and STRNCMP_LITERAL.
Carl Worth [Wed, 24 Apr 2013 08:08:54 +0000 (01:08 -0700)]
Append to, rather than replace, the LD_PRELOAD value.
This is more polite for running things such as Steam games where there
is already an LD_PRELOAD value in place. This way, both the Steam overlay
and fips can get along happily.
Carl Worth [Wed, 24 Apr 2013 07:58:26 +0000 (00:58 -0700)]
Add wrappers for dlopen, dlsym, and glXGetProcAddressARB
This allows for many applications to start working with fips that would not
work before. Specifically, applications that dlopen libGL.so.1 instead of
directly linking with it would previously bypass fips' attempts to wrap
GL calls.
With these new wrappers carefully in place, many applications now work.
I've verified the following applications at least:
apitrace replay
NightSkyHD, a Humble Bundle game, both 32 and 64-bit versions
World of Goo, via Steam
I was also happy to notice that the Steam overlay does not cause fips
any difficulties.
Carl Worth [Wed, 24 Apr 2013 00:47:20 +0000 (17:47 -0700)]
Fix fips to work without requiring an absolute path for program to run.
With the latest commit that examines the ELF header of the program to
run fips was suddenly requiring that the absolute path of the program
be provided. This was obvisouly not desired.
It's simple enough to search through the PATH environment variable to
find the absolute path of the program to be run and examine that.
Carl Worth [Wed, 24 Apr 2013 00:25:13 +0000 (17:25 -0700)]
Compile both 32-bit and 64-bit versions of the wrapper library.
This is intended to make it transparent to run fips with either a
32-bit or a 64-bit program. And it does do that once you successfully
build both versions of the library.
Actually being able to build both versions of the library is a little
tricky though. Here are some of the tricks:
1. You will need to have installed both a 32-bit and a 64-bit .so file
for each dependent library, (currently libelf and libtalloc).
The current configure script doesn't check for both versions, so
you don't get a lot of guidance here. And that's because...
2. On Debian, at least, one cannot currently install both
libtalloc-dev:amd64 and libtalloc-dev:i386 at the same time.
Contrast with libelf-dev:i386 and libelf-dev:amd64 which work just
fine when installed simultaneously.
One can work around this by just install libtalloc-dev:amd64 and then
manually creating the link you need for the i386 package. Namely:
Carl Worth [Tue, 23 Apr 2013 21:17:33 +0000 (14:17 -0700)]
Start wrapping OpenGL, and print periodic FPS value to stdout.
In addition to the fips binary, we now also compile a libfips.so library
and LD_PRELOAD that before executing the program specified on the command-
line.
The libfips.so library wraps OpenGL calls of interest for purpose of
instrumentation. So far, the only call wrapped is glXSwapBuffers and
the only instrumentation is to compute and print out a frames-per-second
value every 60 frames.