HOWTO implement an OpenGL extension for Mesa
That's a great idea. I'd be interested in implementing OpenGL extensions. If only I could manage to figure out the gory details.
Originally Posted by Agdr
Here's a rough plan how I'd go about adding an extension to r600g.
Step 0: Read the FAQ
Mesa FAQ. Join the mailing list.
Gallium3d documentation, and whatever else you can find
Step 1: Figure out what's missing
Running an application I see this warning:
EE r600_screen.c/r600_get_param:109 - r600: unknown param 9
Looking at r600_screen.c r600_get_param, then at include/pipe/p_defines.h enum pipe_cap tells me that param 9 is
Step 2: Find out what this should do
Step 3: Find out what the hardware offers
Searching for "time" points to the Event Initiator.
There are four instructions that return timestamps:
* 04 - CACHE_FLUSH_TS
* 20 - CACHE_FLUSH_AND_INV_TS_EVENT
* 37 - CR_DONE_TS
* 40 - BOTTOM_OF_PIPE_TS
Quoting GL_EXT_timer_query spec, "In this extension, the timers start and stop when the BeginQuery/EndQuery commands reach the bottom of the rendering pipeline."
Looks like 40 - BOTTOM_OF_PIPE_TS might be a good candidate.
Step 4: Look for prior art
Mathias Fröhlich, EXT_timer_query softpipe implementation
So, there's no hardware implementation we could copy from. The software implementation isn't much help in writing the needed asynchronous query mechanism from scratch. But maybe there's such a mechanism in a similar extension?
Quoting the spec, "This extension (..) uses the query object mechanisms first introduced in the occlusion query extension, which allow time intervals to be polled asynchronously by the application."
Stephan Schmid and Alex Deucher, occlusion query support
Step 5: Implementation
At this point, it looks like most of the work is copy and paste:
Copy the occlusion query implementation.
Replace ZPASS_DONE with BOTTOM_OF_PIPE_TS.
Return timestamps instead of ZPASS counters.
Step 6: Test
Looks like it's already there, no need to write from scratch
Mathias Fröhlich and Brian Paul, Simple test for GL_EXT_timer_query
Step 7: Submit to Mesa-dev
Nice post -- this is an interesting pursuit. Do you think there is sufficient room in the open source drivers for people without NDAs to start implementing hardware-accelerated OpenGL extensions for Gallium?
I think the main impedance is that it's traditionally been difficult to accrue any domain knowledge about the implementation of hardware-accelerated graphics. Even for someone like Michael who knows all the lingo, knowing the lingo plus the C programming language isn't enough to be able to do something significant for Mesa.
Then again, I used to think audio was a difficult-to-learn domain. Then I just started hacking on stuff and eventually I became good enough at it to know what I'm talking about most of the time.
Maybe it's just the reputation of difficulty?
Getting new hardware to work for the first time is pretty hard because the hardware doesn't tell you when you do something wrong, it just locks up or doesn't do anything. Once the driver is working, making it do new things that don't require new hardware interaction is more like normal software development.
The current 3D driver stack is >90% common, hardware independent code (ie Mesa common code) if that helps. If you're interested, people will help you get up to speed on how the driver works today.
There's not really anything you need an NDA to implement. All the information is available in the register specs and programming guides, you just have to put together what registers relate to the extension you want to implement. You just need a test app and some patience. Feel free to ask questions on the mesa and dri mailing lists; we are happy to help new developers.
Perhaps there needs to be some equivalent of kernelnewbies.org for open GPU development: maybe Phoronix could host it and/or help with that?
Maybe it could also imitate LWN, with regular overviews of current development, and articles contributed by the developer themselves?
Or perhaps LWN itself could expand with a "Graphics development" feature like the "Kernel Development" it already has?
After all, if people read "kernel development", wouldn't they also read "graphics development", which is as complicated, and also comes with pretty pictures?
There is already a lot of content disseminated over several blogs, freedesktop wikis, and mailing lists, often reported on by Phoronix, but maybe some newbie-oriented and developer oriented central place could help.
What else could be done to increase contributions?
Much more user friendly and comprehensive documentation for Radeons could possibly be very helpful, but the ATI open driver team seems to already have trouble keeping up, so it's probably best they work on releasing new stuff instead.
By the way, note that reverse engineering is often much easier than you could think at first.
The reason is that there are tools that let you run some OpenGL program on the proprietary driver, and get a list of the commands it sends to the hardware.
By comparing the commands generated for code that uses a given extension with the ones for code that doesn't, you can often easily and sometimes trivally figure out how something is performed.
You often literally get a text diff looking like this:
+ SET_REGISTER 0x2230 1
+ SET_REGISTER 0x2234 <parameter value I passed to OpenGL>
or looking like this:
- SET_REGISTER TEXTURE_SETUP_3 0x34507802
+ SET_REGISTER TEXTURE_SETUP_3 0x34517802
In the first case, it clearly means that register 0x2230 is an enable boolean for the feature, and register 0x2234 is used to specify the parameter value.
In the second case, bit 16 of TEXTURE_SETUP_3 is the bit that enables the feature in question.
Only issue, apparently the "revenge" tool for reverse engineering fglrx only works for r100-r500 and hasn't been updated for r600+.
Perhaps the docs and driver code are so good that no one felt the need to reverse engineer fglrx?
Obviously reverse engineering a whole new GPU from scratch is much harder, but you don't usually need to do that.
Originally Posted by allquixotic
Understanding OpenGL extension specifications should be sufficient for implementing extensions in Mesa. If you don't know your hardware, you may try adding extensions to a software rasterizer first. Knowing something about 3D graphics helps a lot.
Originally Posted by allquixotic
I think reverse-engineering ATI hardware is a waste of time these days. It's just easier to ask somebody, or read docs.
I'd like to add that GPU command stream analysis is not only useful for reverse engineering, but also for tracking down open driver bugs by looking for commits changing the command stream, to compare the command streams generated by two drivers to figure out, and to develop immature hardware without locking up the hardware every time.
In general, the tools used are:
- mmiotrace, which logs all writes and reads from PCI registers: used to log the register read/writes by the kernel driver and X driver. Included in the mainstream kernel
- valgrind-mmt, which logs all writes and reads from PCI registers generated by an userspace application.
- renouveau, which dumps the command stream of the nVidia Linux OpenGL driver
- revenge which dumps the command stream of the ATI Linux OpenGL driver
- patches to libdrm that dump the command stream of the open drivers
- renouveau-parse (and perhaps rules-ng-ng tools) to convert hexadecimal data into readable register offset/value pairs for known registers for nVidia cards
- radeondb (and maybe others?) to convert hexadecimal data into readable register offset/value pairs for known registers for nVidia cards
Also, there should be ways to use virtualization software with PCI Express passthrough and perhaps IO-MMUs to trace the Windows drivers, but I'm not sure about the specifics, and this is not usually done since reverse engineering the Linux drivers is much easier (and they are mostly shared code anyway for both nVidia and ATI).
And you can use IDA Pro or equivalent tools to disassemble and decompile the proprietary drivers, but this is also not usually done, since it is not worth the hugely increased difficulty and time over reading command streams.
For example, on http://nouveau.freedesktop.org/tests/, you can find a repository of command streams generated by the nVidia drivers.
So, the HOWTO for reverse engineering OpenGL features is as follows:
1. Check if the proprietary driver supports the extension. Otherwise, give up, or figure out how to emulate it in terms of other functionality (usually, this means the hardware itself doesn't support it directly).
2. If the feature is not trivial, look for feature lists, public documentation, whitepapers, game development guides, tech presentations about the feature from the GPU manufacturer to know what exactly the hardware supports and maybe get some juicy details too
3. Get a reverse engineering tool like renouveau or revenge
4. Check if there is already a test for your feature
5. If not:
5a. Find some demo or test that makes use of the feature, and check that it works on the proprietary driver. If you cannot find any, write one yourself.
5b. Find the most similar renouveau/revenge test, and modify it with code from the test/demo.
5c. If applicable, either do two rendering passes, one with and one without a feature, or otherwise make it a compile option
6. Run renouveau/revenge on the proprietary driver to get a trace (or use an existing trace if the test was already available)
7. Run the parsing tool on the trace to get it as human readable as possible
8. Compare command streams with and without the feature (either from the two passes of your tests, or comparing with other tests or other versions of your tests). Either use manual comparison, or "diff" if applicable.
9. Figure out how the hardware works. If necessary, modify the test to add runs with different parameters, until you get a complete picture
10. Add the registers you just reverse engineered to the relevant header and/or register database
11. If necessary, enhance Mesa and Gallium core to support the new extension or feature. You may also want to implement it in softpipe if not available.
12. Implement the extension in the open hardware driver
13. If necessary, experiment with different values and different cases to get a better understanding
14. Write a test for the feature if not already present in mesa-demos and piglit, and submit it
15. Check that the tests have with no regression, and that the tests for the new feature now pass
16. Submit your work
Good to know!
Originally Posted by marek
Anyway, in some sense, reverse engineering is literally asking the proprietary driver itself what you should do, and you are guaranteed to get the correct answer.
The problem, of course, is that the answer is specific for a given set of parameters, and will need manual generalization (sometimes from multiple data points) to be useful.
I think you'll see more enthusiasm for documentation once the Great Re-architecture is finished and documentation stops becoming obsolte within a few weeks of writing it. Most of it is done; the main open issue is moving the default 3D drivers onto the Gallium3D framework.
Originally Posted by Agdr
I don't really understand why you're saying this, given that between ATI/AMD and community developers they have nearly caught up on 8 years of new product introduction (r3xx came out in 2002) in a bit over 3 years.
Originally Posted by Agdr