pixel precise rasterizing on different archs

Started by
1 comment, last by tanzanite7 11 years, 12 months ago
Hi all,
for an application I'm developing I need to be able to

- draw lines of different widths and colours
- draw solid color filled triangles
- draw textured (no alpha) quads

Very easy...but...

All coordinates are integer in pixel space and, very important: glReading all the pixels from the framebuffer
on two different machines, with two different graphic cards, running two different OS (Linux and freebsd),
must result in exactly the same sequence of bits (given an appropriate constant format conversion).


I think this is impossible to safely be achieved using opengl and hardware acceleration, since I bet different graphic
cards (from different vendors) may implement different algorithms for rasterization.
(OpenGl specs are clear about this, since they propose an algorithm but they also state that implementations may differ
under certain circumstances).
Also I don't really need hardware acceleration since I will be rendering very low speed and simple graphics.

Do you think I can achieve this by just disabling hardware acceleration? What happens in that case under linux, will I default on
MESA software rasterizer? And in that case, can I be sure it will always work or I am missing something?

thanks a lot !

Daniele
Advertisement
You are correct that your requirements are beyond what OpenGL guarantees. It does provide an ideal reference but also allows some deviations from it.

Your only option is a renderer you have control over. If you expect varying platforms, then Mesa may provide the control you need to get it to work for every platform you're interested in. That way you can ensure that the same renderer is used all the time. I don't know if Mesa used fixed point or floating point arithmetics internally in its default software renderer, but you may even have to force a non-floating point policy also since floating point arithmetics can behave differently on different platforms.

And I don't mean your program should use whatever version of Mesa is installed on the target platform; you need to supply it pre-compiled with your application (subject to its license of course, if it allows that) so you have full control over the renderer. Different platforms may ship with different versions of Mesa, and even compiled differently.
I do not think such a guarantee is even possible - as long as floating point is used (almost certainly used) :/.

* different platforms/compilers have different default state of the FPU => results will differ (probably all of it can be overridden [afaik. VC on 64 platform won't allow changing calculation precision at all tho and the default in fact differs from the default used on (at least some) Unix/Linux OS - as you do not need Win, you might be in luck] - assuming none of the other libs etc will explode).
* different compilers can optimize differently - FP is highly susceptible to compounding errors (VC has an option to turn all optimizations off - which helps, but does not eliminate the problem. also, there are no guarantees the result will match with other compilers on other platforms - you can be certain they won't).
* 32bit and 64bit platforms have different amount of registers available - which means there will be different amount of downcast to float at different times (disabling all optimizations and forcing to downcast every FP value at every point will help).

So, to have any chance of, consistently, getting the same results:
* use a software renderer - obviously - and compile it yourself, applying the following rules as you need to do everywhere else too.
* all floating point optimizations must be turned off.
* including: compiler must be instructed to write out every temporary (and otherwise) value and reload them before using again (ie. downcast). This, besides being absolutely necessary anyway, should remove 32bit/64bit register allocation differences.
* use the exact same version of a compiler every time on every platform.
* override all of the FPU state by explicitly setting it to something you like.
* hope that different FPU from different manufacturers made over the years will give the same results (constantly down-casting to single precision floating point should remove thous differences when FPU is instructed to calculate at least in double precision mode)

To recap: if exact, repeatable, results are absolutely required - i would forget OpenGl and write a fixed-point renderer. ... or rather just forget it.

Or at least be aware of what kind of headache you are heading towards if you use floating point.

This topic is closed to new replies.

Advertisement