Commit graph

59 commits

Author SHA1 Message Date
Brian Nguyen c8f664587d [GLX_dummy] Implement selected dummy functions
Implement a fake glXChooseVisual() and glXCreateContext() function for
use with the makecurrent tests. Likewise, implement
glMakeCurrentTestResults(), glBegin(), and glEnd().

Implement a fake glXGetClientString() for use with the getclientstr
test.
2013-08-26 11:03:43 -07:00
Brian Nguyen e906738529 [GLX_dummy] Implement an example extension function and its dispatcher
To test that vendor-implemented dispatching works in the getprocaddress
test, implement glXExampleExtensionFunction and its vendor-neutral
dispatcher in GLX_dummy, and plug each respectively into the
getProcAddress and getDispatchAddress callback functions.
2013-08-26 11:03:43 -07:00
Brian Nguyen c11bd25282 [GLX_dummy] Implement glMakeCurrentTestResults()
This fake GL extension function is used by the glxnscreens and
makecurrent tests.  This plugs the function prototype spec into
GLX_dummy's getDispatchProto() callback and adds an entry into the table
used by its getProcAddress() callback.
2013-08-26 11:03:43 -07:00
Brian Nguyen d3b38da75d [GLX_dummy] Implement the getProcAddress() callback 2013-08-26 11:03:43 -07:00
Brian Nguyen 01ea1d2e41 [GLX_dummy] Define glMakeCurrentTestResults()
This fake GL extension function will be responsible for performing
various queries on the vendor library for the purposes of testing,
and also serves as a useful test of the API driver's handling of
dynamic GL entrypoints.
2013-08-26 11:03:43 -07:00
Brian Nguyen 402e5a8a4c [tests] Add testx11glvndproto and testglxnscreens subtests
testx11glvndproto tests specifically the GLVendor X extension, which is
used to lookup XID -> screen and screen -> vendor mappings in the
prototype.

testglxnscreens tests that the API library successfully dispatches GL
calls to the right vendor based on this lookup.
2013-08-26 11:03:43 -07:00
Brian Nguyen 9eec93a6f8 [tests] Add testglxqueryversion subtest
This verifies that the GLX API library's hand-coded implementation
of glXQueryVersion() works as expected.
2013-08-26 11:03:43 -07:00
Brian Nguyen f3c6f65d36 [tests] Add testglxgetclientstr subtest
This subtest verifies that the GLX API library's implementation of
glXGetClientString() (which takes the "union" (concatenation) of each
vendor's client string) works as expected.
2013-08-26 11:03:43 -07:00
Brian Nguyen 67f04602e6 [tests] Add testglxmcoldlink subtest
This is a variant of the testglxmakecurrent subtest which links against
the libGL filter library instead of libOpenGL + libGLX. This verifies
the ELF symbol filtering works as expected.
2013-08-26 11:03:43 -07:00
Brian Nguyen 808706d3a2 [tests] Add make current subtests
This implements a test app, testglxmakecurrent, which verifies the
correctness of the API library's GL dispatching when a vendor's context
is current in one or more threads.

This test spawns a given number of threads each with their own separate
context and window, and has each thread make current to its given
context. The thread then calls some core GL functions and
(to-be-implemented) a GL extension function, glMakeCurrentTestResults(),
which returns the number of times each core GL function was called.
The test then compares glMakeCurrentTestResults()'s result (which should
match up with the vendor library's call count) to the application's call
count and fails if there is a mismatch.

The test is designed to only require pthreads if multiple threads are
used. This verifies that the API library's single-threaded fake pthread
wrapper functions work properly.

Add testglxmc{basic,late,loop,threads}.sh scripts, which run the
testglxmakecurrent test with different arguments for ordering of
glXGetProcAddress(), number of threads, and number of iterations.

Isolate helper functions for window creation/destruction to a separate
test_utils.c source file which will be used by later tests.
2013-08-26 11:03:43 -07:00
Brian Nguyen e0e68e14d4 [tests] Add testglxgetprocaddress subtest
This subtest verifies that glXGetProcAddress() works for the various
classifications of "GetProcAddress-able" functions:

- GLX 1.4 functions with dispatchers implemented directly by the API
  library
- GLX 1.4 extension functions with dispatchers implemented by a vendor
  loaded by the API library
- Core OpenGL functions with static dispatch stubs in libGLdispatch
- Core OpenGL functions with dynamic dispatch stubs generated by
  libGLdispatch

This also tests some assertions about these dispatch stubs; namely that
the core GL dispatch stubs are no-ops if no context is current.
2013-08-26 11:03:43 -07:00
Brian Nguyen b3f7cbc3e0 [tests] Add a GLX_dummy dummy vendor library
This vendor library will be loaded by the API library in various
subtests in the test suite, and will implement the bare minimum
needed to verify features and code paths in the API library. This
includes creating a fake GL "context", making current to the
"context", and calling some GL functions.
2013-08-26 11:03:43 -07:00
Brian Nguyen 42589ec4c5 [tests] Add basic test infrastructure
This adds build infrastructure for unit testing the API library
using the serial test harness. TODO: this should be replaced with
the parallel test harness, as the automake documentation says the
serial harness is deprecated.

The first and last tests to be run are scripts to initialize the test
environment (an X session with a special -modulepath argument and
xorg.conf file to pick up x11glvnd) and tear it down after all unit
tests are run.

This also adds a placeholder directory for a fake vendor library
called "GLX_dummy", to be implemented later.
2013-08-26 11:03:43 -07:00
Brian Nguyen 58193778b0 Use noop-gl mapi generated header to implement GL noop stubs
Update libGL and libOpenGL filter libraries to use the new noop-gl mapi
header generation mode to generate no-op stubs for core GL symbols.
2013-08-26 11:03:43 -07:00
Brian Nguyen 79a0b9a093 [mapi] mapi_abi.py: Implement a noop-gl printer
This is used to generate no-op dispatch stubs with extern linkage, for
use with the libGL and libOpenGL filter libraries.
2013-08-26 11:03:43 -07:00
Brian Nguyen e6da529d16 Add libGL and libOpenGL filter libraries
libOpenGL is a filter library on libGLdispatch which only exports the
core GL 1.x-4.x entrypoints.

libGL is a filter library on libGLX and libGLdispatch which only exports
the core GL 1.x-4.x entrypoints and GLX 1.4 entrypoints. This is a
backwards compatibility layer for legacy apps which link against the old
libGL.so ABI.
2013-08-26 11:03:43 -07:00
Brian Nguyen 2b810fcefe [mapi] Add spec file for GL 4.x entrypoints 2013-08-26 11:03:43 -07:00
Brian Nguyen f5e3920e23 [mapi] Implement glapi_init_table_from_callback()
This is a new glapi function which takes an already-allocated
_glapi_table and fills it in using the given getProcAddress callback.
This is needed because the existing _glapi_create_table_from_handle()
function only allows clients to pass in a loader handle from which to
dlsym() entrypoints. This reduces the number of symbols required by
each vendor library and also allows vendor libraries to provide
different context-dependent entrypoints if desired when building
dispatch tables.
2013-08-26 11:03:42 -07:00
Brian Nguyen efa8ca15c5 [mapi] Implement _glapi_{set,get}_current()
This replaces the _glapi_tls_{Dispatch,Context} symbols with a single
symbol, _glapi_tls_Current, which references an array of type (void*).
This allows us to easily extend mapi to accomodate additional TLS
entries, which will be necessary for storing current API state and
allowing vendors to utilize TLS entries for their own purposes.

This change is rather messy. It requires modification to both the
dispatch stub generation code and mapi's compatibility #defines in
u_current.h. This could probably be cleaned up in later changes. It's
not clear whether _glapi_{set,get}_{dispatch,context}() are even needed
anymore, but they are kept in place for backwards compatibility and to
keep this change as self-contained as possible.
2013-08-26 11:03:42 -07:00
Brian Nguyen 13fa286563 [GLdispatch] Implement FixupDispatchTable() and FindProcInList()
FixupDispatchTable() does the work of iterating through the list of new
pending entrypoints and querying the vendor library assigned to a
dispatch table for the appropriate function address.

FindProcInList() is used to check for duplicate procs in the tracking
lists.
2013-08-26 11:03:42 -07:00
Brian Nguyen 51a5417cec [GLdispatch] Add global current dispatch table list
This is used for fixing up all current dispatch tables whenever a thread
calls GetProcAddress() on a function which has never been seen before by
GLdispatch. The fixup itself should be threadsafe since the dispatch
lock will be taken around all accesses to this list, and actual GL calls
won't be made to the newly-GetProcAddress()'ed function since the
address for this function hasn't been returned to the application yet.
2013-08-26 11:03:42 -07:00
Brian Nguyen 48cbe20f60 [GLdispatch] First pass at implementing the GLdispatch API
Introduce two lists for tracking dynamic dispatch stubs: newProcList and
extProcList. newProcList contains stubs which were generated by a
getProcAddress call but not assigned a prototype from a vendor, and
extProcList contains stubs which have been assigned a prototype but may
still need the vendor's implementation to be plugged into the dispatch
tables.

Also introduce a generation number which is an attribute of both
dispatch stubs and dispatch tables, and a global variable,
latestGeneration. Each time __glDispatchGetProcAddress() generates a new
dispatch stub, latestGeneration is incremented and assigned to the new
dispatch stub. Dispatch tables with a generation number less than
latestGeneration need to be fixed up with functions from the extProcList
whose generation number is greater than the dispatch table's number.
After the fixup is complete, the dispatch table's generation is updated
to latestGeneration.

This also requires we track current dispatch tables globally; this will
be done in a subsequent change.

Link against glapi to get the required symbols we need.
2013-08-26 11:03:42 -07:00
Brian Nguyen 873faf57b0 [GLdispatch] Build mapi
- Replace hard-coded mapi and mesa paths in mapi makefiles with the
  autoconf variables MAPI_PREFIX and MAPI_MESA_PREFIX
- In mapi_abi.py, create a new vnd-glapi printer which provides a
  statically-linked glapi (implemented using mapi) with public symbols
  for consumption by libGLdispatch.
- Create a vnd-glapi subfolder and makefile for building glapi in this
  mode, copied from shared-glapi. The Makefile.am (not SConscript) has
  been modified to build glapi_mapi_tmp.h using the vnd-glapi printer.
- Fix top-level makefile to call into the mapi/vnd-glapi subdirectory,
  and configure.ac to generate the makefile at bootstrap time.
2013-08-26 11:03:42 -07:00
Brian Nguyen ce945ea5a2 [GLdispatch] Add mapi from MESA commit fa7829c36b78b8ecc42238cbc0a02d1059320c77
The MESA API module, mapi, and its corresponding GL submodule, glapi,
will be used by GLdispatch for implementing dynamic and static GL stub
generation and management of core GL dispatch tables.
2013-08-26 11:03:42 -07:00
Brian Nguyen 535b1cb0ab Add mesa headers from git commit fa7829c36b78b8ecc42238cbc0a02d1059320c77 2013-08-26 11:03:42 -07:00
Brian Nguyen 810c434324 [GLdispatch] Write pseudo-code implementations of API
This adds comments and (incomplete) code to describe the general
strategy which will be taken to implement the GLdispatch API. This
is still a WIP.
2013-08-26 11:03:42 -07:00
Brian Nguyen fa83b3954f [x11glvnd] Implement the client- and server-side code
This fills in currently unimplemented functions for packing protocol
in the client, and retrieving mappings in the server.

- XID -> screen mappings are performed by running
  dixLookupResourceByType() on the appropriate resource lists. A
  callback which GLX can plug into allows for the registration of
  additional resources to do XID -> screen tracking (e.g. GLX
  drawables).
- screen -> vendor mappings are saved in XGLVendor's screen privates
  when the extension is loaded
2013-08-26 11:03:42 -07:00
Brian Nguyen 9730ce862e [x11glvnd] Define X11 protocol for XGLVendor extension
Implement the server-side dispatching function for routing an XGLVendor
request to the right proc, but don't implement the actual lookup
functionality, yet.
2013-08-26 11:03:42 -07:00
Brian Nguyen 3eb00015de Add x11glvnd X11 extension
This will be used to handle the corner case when a drawable XID is
passed into the API library which belongs to an X window or otherwise
has never been seen before by the process, by providing a way to lookup
which screen the corresponding drawable belongs. This still is racey
since we can't guarantee a different process won't free the XID and
cause it to be recycled as a handle for a different resource after the
lookup, but better than not being able to figure out the mapping at all.

This extension also solves the less-difficult problem of mapping a
screen to a vendor name (though it may make more sense to at some point
directly map drawables to a vendor to better support render-offload
scenarios).
2013-08-26 11:03:42 -07:00
Brian Nguyen 8b3953b2f7 Add GLdispatch DSO
Move the GLdispatch header file to its own directory in src/GLdispatch,
and build a real DSO that GLX will depend on. In GLdispatch.c, add stub
functions which will later be fleshed out.
2013-08-26 11:03:42 -07:00
Brian Nguyen 557711cde5 [GLX] Add libglxgldispatch.[ch]
This implements thin wrappers around libGLdispatch which allow vendors
to manage their own dispatch tables. See documentation in the interface
header file libglxabi.h for more details.
2013-08-26 11:03:42 -07:00
Brian Nguyen b459d25cd5 [GLX] Define GLdispatch API
Add a new header file, GLdispatch.h, which defines an API for
window-system libraries such as libGLX to manage core GL dispatch tables
as well as TLS. Refactor the __GLXAPIState to be derived from
__GLdispatchAPIState, make __GLXvendorInfo::glDispatch type
__GLdispatchTable, and implement make current/get current functionality
using this API.

At some point this API will be implemented in a shared library used by
both libGLX and libEGL.
2013-08-26 11:03:42 -07:00
Brian Nguyen 01a58da204 [GLX] Implement the no-op GLX dispatch table
Set the __glXDispatchNoopPtr statically to the __glXDispatchNoop
dispatch table, defined in libglxnoop.c.

Define no-op GLX 1.4 templates in libglxnoopdefs.h, which is included by
libglxnoop.c. We do this instead of defining the no-op functions
directly because these functions will also be needed by the libGL filter
library. To facilitate code sharing, these templates use GLXNOOP and
NOOP_FUNC() macros to respectively define the function qualifiers and
prefix (e.g. "glX") of each no-op function.
2013-08-26 11:03:42 -07:00
Brian Nguyen a1047eb2a8 [GLX] Implement __glXFetchDispatchEntry()
This function is an implementation of the fetchDispatchEntry export,
which is called by vendor-implemented GLX dipsatchers to fetch a
dispatch table entry given a logical dispatch table index.

This change also implements the logic for assigning dispatch table
indices to GLX entrypoints at glXGetProcAddress() time.  The dynamic
dispatch table is actually a hashtable which uses the "index" as a key,
and not a flat array, to prevent wasted memory usage from sparse
dispatch tables.  Since GLX entrypoints are generally not
performance-critical this should be fine.
2013-08-26 11:03:42 -07:00
Brian Nguyen a7ca3457a9 [GLX] Implement screen-pointer mapping helper functions 2013-08-26 11:03:41 -07:00
Brian Nguyen 74c9644124 [GLX] Implement screen-XID mapping helper functions 2013-08-26 11:03:41 -07:00
Brian Nguyen 226d3a8a24 [GLX] Implement loading vendor libraries
This implements __glXLookupVendorByName(), which is responsible for
checking a hash table for existing loaded vendors with the given name,
and loading the vendor with that name if no existing vendors are found.
This also implements __glXGetGLXDispatchAddress(), which iterates
through this hash table checking whether each loaded vendor supports
dispatching to the given GLX entrypoint.
2013-08-26 11:03:41 -07:00
Brian Nguyen d89a8ee8cf [GLX] Implement __glXLookupVendorByScreen()
This function, which looks up a vendor given a screen number, is used
by several helper functions which look up core GL and GLX dispatch
tables given a screen number, and directly by the API library's make
curent proc. This relies on the (still unimplemented) function
__glXLookupVendorByName().
2013-08-26 11:03:41 -07:00
Brian Nguyen 4c68d3cc1b Add lkdhash.h
This is a simple wrapper around uthash which simplifies read/write
locking around hashtables used by libGLX.
2013-08-26 11:03:41 -07:00
Brian Nguyen cbe7587997 [GLX] Implement caching proc addresses in glXGetProcAddress()
This also doubles as a way to store addresses of locally-exported GLX
functions; we use a pthread_once() callback to initialize the table
with these addresses.
2013-08-26 11:03:41 -07:00
Brian Nguyen 93bb43c5e7 Add uthash commit 2c8cd98e0be93d38ff3340a0fbce300bc6739b08 to src/util
uthash's hashtable implementation will be used by libGLX for storing
various mappings needed for correct dispatching.
2013-08-26 11:03:41 -07:00
Brian Nguyen f0aa610a3d [GLX] Include libglxmapping.c and libglxnoop.h in build
libglxmapping.c implements functions needed for libGLX to map function
calls to vendors for dispatching.

libglxnoop.h contains a pointer to a no-op dispatch table.

These will be re-implemented in a later change.
2013-08-26 11:03:41 -07:00
Brian Nguyen fff1fcc0c0 [GLX] Hook up glvnd_pthread
This sets up GLX to use the glvnd_pthread wrapper library, and
implements real locking around the glXGetClientString() implementation.
2013-08-26 11:03:41 -07:00
Brian Nguyen 8dad6e57f8 Implement glvnd_pthread
This is a wrapper library around libpthread which implements
single-threaded fallbacks in case the API library is loaded in an
application which does not link against pthreads.
2013-08-26 11:03:41 -07:00
Brian Nguyen c51b191aef [GLX] Implement MakeContextCurrentInternal()
This does the work of glXMake{,Context}Current().
2013-08-26 11:03:41 -07:00
Brian Nguyen ec9be3bfac [GLX] Implement glXQueryVersion()
This function directly packs protocol to get the version from
server-side GLX.
2013-08-26 11:03:41 -07:00
Brian Nguyen 8ec20e11d5 [GLX] Implement glXGetClientString()
This takes the "union" (concatenation) of the vendor libraries' client
strings.
2013-08-26 11:03:41 -07:00
Brian Nguyen 3db1e19fcf [GLX] Begin implementing glXMake{,Context}Current()
This makes use of a (still unimplemented) helper function called
MakeContextCurrentInternal() to actually perform the required API
library work for make current.
2013-08-26 11:03:41 -07:00
Brian Nguyen 4ee8d21ae6 Implement tracing
This implements a small tracing convenience library for debugging
purposess.
2013-08-26 11:03:41 -07:00
Brian Nguyen 31817fbb9b [GLX] Define internal APIs needed for looking up mappings, getting current state
- libglxabipriv.h: This is a simple wrapper around libglxabi.h which
  defines the static dispatch table to be the same as the set of
  functions exported by the vendor (they could potentially differ).

- libglxcurrent.h: This defines a current "API state" struct which
  encapsulates the API library's knowledge of the current display,
  read/draw drawables, dispatch tables, and vendor (owning the current
  context).  The glXGetCurrent*() functions are implemented by
  retrieving various fields from this API state.

- libglxmapping.h: This defines a "vendor info" struct which contains
  information about a loaded vendor. It also provides accessor functions
  for retrieving the dispatch table given a screen, and functions for
  adding/removing mappings from various keys (Context, FBConfig,
  Drawable) to screens.

- libglx.c: Replace the dummy GetStaticDispatch() function with calls to
  the API in libglxmapping.h to retrieve the right dispatch table.
2013-08-26 11:03:41 -07:00