Unfortunately, I do not have access to an ATI GPU but many users of my OpenGL application have notified me of a bug that appears to have been introduced around the time of the 11.10 driver update a few months ago. The problem is semi-randomly discarded fragments. My fragment shader is reasonably complex and attempts to emulate the behavior of a mid-90's Real3D GPU. It distinguishes between three different types of texture formats:
1. T1RGB5 "contour" textures. The T bit indicates transparency and indicates the fragment must be discarded and should NOT modify the Z buffer. I encode T in the alpha channel: 0.0 is transparent, 1.0 is opaque. This can be enabled/disabled on a per polygon basis by the Real3D hardware.
2. RGBA4 textures. This is what you would expect except that when A is near 0 (full transparency), the depth buffer is not modified. The entire fragment is discarded.
3. Fully opaque textures. No contour/alpha processing.
What I do is pass two vertex attribs to the fragment shader:
1. fsTexFormat If >0, indicates a T1RGB5 texture.
2. fsTexParams.y If >0, indicates that fragments with a near 0 should be discarded entirely (T1RGB5 or RGBA4).
I encode the T (transparency) bit as an alpha value (either 1.0 or 0.0). If fsTexParams.y indicates that transparent fragments must be discarded, I do so. If the texture is a T1RGB5 type and the fragment has not been discarded, I force its alpha value to 1.0 (opaque), because when processing of this bit is disabled, the T bit is ignored and often set randomly.
I've attached the fragment shader.
Here are examples of the problem (wide images -- click them to view them in their entirety):
The left image demonstrates the problem. Look at the clouds and the castle ramparts. On the right, I forced alpha = 1.0 for all fragments, which breaks RGBA4 decals on the vehicle but eliminates the other problem.
The same user also submitted this image:
Notice that the corruption in the alpha channel on the right image takes the shape of another texture in the game. Please note that I am using only a single texture map: all textures are decoded into a giant 2048x2048 texture sheet, so this is not a CPU-side problem with texture decoding.
Here is a snippet from the fragment shader:
* The transparency bit determines whether to discard pixels (if set).
* What is unknown is how this bit behaves when interpolated. OpenGL
* processes it as an alpha value, so it might concievably be blended
* with neighbors. Here, an arbitrary threshold is chosen.
* To-do: blending could probably enabled and this would work even
* better with a hard threshold.
* Countour processing also seems to be enabled for RGBA4 textures.
* When the alpha value is 0.0 (or close), pixels are discarded
if (fsTexParams.y > 0.5) // contour processing enabled
if (fragColor.a < 0.01) // discard anything with alpha == 0
// If contour texture and not discarded, force alpha to 1.0 because will later be modified by polygon translucency
if (fsTexFormat < 0.5) // contour (T1RGB5) texture map
fragColor.a = 1.0;
The top right image ('Scud Race') is from a version of this fragment shader with all of these lines removed except for: fragColor.a = 1.0;
This disables all transparencies, of course.
I have no idea where the problem might be. As I said, this is not a problem with older drivers and it does not occur on Nvidia hardware. Also, at least one user was able to fix it by completely wiping the drivers and doing a fresh install. Other users have not been able to replicate this but it may be because they are not completely removing the old drivers (they happen to be a bit less computer savvy and I can't verify if they are doing it correctly).
I don't see anything obviously wrong with the fragment shader. What you're proposing ought to work. We can try to find the regression point, but we'll need a build that exhibits the issue. Can you provide a link where we can obtain the application?
Thanks for the prompt response, Graham, and for being willing to look at the application. Version 0.2a can be obtained at http://www.supermodel3.com/Download.html but I can give you a more recent build:
The application: http://www.supermodel3.com/tmp/Supermodel64.zip
The complete application source code is available at supermodel3.com. Disclaimer: This is an emulator and requires copyrighted ROM images to function. If linking them here infringes upon forum policy, feel free to remove this message and contact me privately at 'trzy at uw dot edu'. For reasons I can explain in better detail privately, I am quite certain the ROM link will not be a problem and it will be removed from my site once I have confirmation that you've downloaded it. Thank you!
I forgot to include usage instructions. It is a command line application. Simply run 'supermodel' to get a list of options, including options that control video resolution and window (default) vs. full screen mode. Default resolution is the system native 496x384, which can be a bit small to work with. I recommend:
supermodel -res=800,600 scud.zip
You can use -frag-shader=XXX.glsl to load an external fragment shader. By default, the internal fragment shader is the same as Fragment.glsl included in the zip archive.
The game should boot on its own into an attract mode very quickly. To enter the game itself, you can use the default keyboard-based controls:
Insert coin: 3
Steering wheel left/right: Left and right arrow keys
Accelerator pedal: Up arrow key
To quickly save and restore to any point in the game (to avoid the boot up sequence, for instance), press F5 to generate a save state image and F7 to reload it.
Thanks. Unfortunately, we cannot host links to copyrighted material on the AMD forums. I have downloaded the binary of the application you sent but have removed the link to the ROM image from your post. I suppose we will have to find some way to regress the issue.
Would it be helpful for me to build a special version that loads saved states of the graphics hardware (which would be rendered as static frames) without requiring the ROM sets? I could rip out the CPU emulation and then distribute a series of states containing bad frame data which could be loaded and examined.
That's great news, Graham! I hope you guys find the problem and if there's something I'm doing wrong on my end, I would love to hear about it so I can get a fix out for my users. Thanks!