32 bit z-buffer on the Radeon 9700 Pro?

I have an ATI Radeon 9700 Pro, which says that is supports 32 bit z-buffer. But when I try to create a rendering context with 32 bit z and 8 bit stencil, I end up with a 24 bit z and 8 bit stencil buffer. When I try to create a 32 bit z and 0 bit stencil buffer, I STILL get a 24 bit z and 8 bit stencil buffer. Has anybody been able to create a 32 bit z-buffer on the Radeon 9700 Pro? Also, has anyone been able to create a 32 bit z-buffer with 8 bits of stencil on the 9700 Pro? Any help will be greatly appreciated.

list all the pixel formats, and you’ll see if 32bits depth buffer is available.

If you know there is a pixel format with a 32-bit depth buffer, then why are you using ChoosePixelFormat? Just set that pixel format, no need for ChoosePixelFormat to get in your way.

I would never use ChoosePixelFormat because there is no documentation of how it actually chooses a pixel format.

The z & stencil buffer share the same area of memory so you can’t have a 32bit z + 8 bit stencil , because that would be a 40 bit surface. It’s not required to share the same area, but it does for efficiency.

Same goes for NVidia’s cards.

BTW, you wouldn’t get any real benifit from those extra 8-bits of accuracy anyway. Since, internally, everything is 32-bit floats, and therefore, 23 bits of mantissa, when it converts it to the z-range, you only have 23 bits of accuracy. As such, you won’t derive any benifit from the extra accuracy.

I thought they use fixpoint math for the zbuffer…



Korval, when the exponent changes those bits get spent elsewhere. Ofcourse there’s more precision. The mantissa is not the sole issue when it comes to determining precision. If you have 8 bits of of exponent you have 256 different exponents to use with your 24 (or 23 signed) bits of mantissa, in otherwords you can represent data with 256 times more accuracy on a non linear scale (log 2?). This is the whole point of floating point. You don’t just toss away your exponent when it comes to accuracy, it counts.

[This message has been edited by dorbie (edited 10-09-2002).]

Unless the float is in the range [0,1], right Dorbie? Like it might be in a straightforward implementation of depth? Or am I missing something?

You’re missing a few things:

First, just because the float is in the range 0.0-1.0 doesn’t mean you don’t use the exponent.

I don’t know what the exponent for 1.0 is with an IEEE float but it’s a bigger than 0.00000001 for example. In other words the exponent still counts between 0 and 1.

Second, reading the Z 0.0 to 1.0 is an OpenGL convention, you could store eye space z there, w, or bananas per furlong and call it a depth buffer, just so long as you convert on read. You can create issues with changing projection and this, but this has been ignored by at least one vendor.

Third, 1.0 might very well be MAX_FLOAT in their implementation, it doesn’t have to be IEEE on their chip, you’d never know, you just get good results and only lose on a read (unless you read a double for depth).

Fourth, they could scale whatever they get from their interpolators up if they have enough precision in the implementation and store as whatever MAX_FLOAT their FP implementation has. Really it’s just a binary number, what it actually means or scales to is a matter of convention.

Items three and four are different sides of the same coin really. By this point it’s almost certain your precision issues aren’t in your framebuffer depth storage. The real trick is (I expect) adding enough bits to the preceeding operations to fully exploit the available precision.

[This message has been edited by dorbie (edited 10-09-2002).]

Just to complete Dorbie’s explanation on the IEEE float to fixed point issue. Floats support expoenents from approximately 128 to -127. The range between 0.5 and 1.0 is supported by a -1 exponent. This gives 24 bits of precision here. (23 bits plus the implied leading 1) Between 0.25 and 0.5 the exponent is -2 and get 24 bits of precision in this range also. The moral of the story is that an IEEE float has more precision than a 24 bit integer depth buffer, but it really doesn’t have enough precison everywhere to fully use a 32 bit integer depth buffer.

As for the maximum number of depth bits, I thought the driver was only exporting 24. (I think this is the same as the 8500) I will double check. Frink, can you mail me offline to tell me where you got the info that it had a 32 bit depth buffer?


Right Dorbie and Evan, i didn’t think about what the exponenet was for 1.0.Thanks for the heads up I did think about the other stuff though, what I meant with “straight forward implementation of depth” was more or less “integer depth buffer and no fancy usage of the max float value to get more precision”. Or something along those lines anyway.