ati_fragment_shader bug?

Hi, I’v searched and couldn’t find a post spot on about this so I figured I’d ask.
Im just trying to do a simple monocrome shader that preserves the incoming textures alpha channel.

This code:

glBeginFragmentShaderATI();

glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);

glColorFragmentOp2ATI(GL_DOT4_ATI,
GL_REG_0_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_CON_0_ATI, GL_NONE, GL_BIAS_BIT_ATI | GL_2X_BIT_ATI);

glEndFragmentShaderATI();

Results in an alpha of 0. (CON_0 is (.3,.6,.1,0))
But if I add this statement before the DOT4 statement everything works fine (yes, its a garbage statement):
glColorFragmentOp1ATI(GL_MOV_ATI,
GL_REG_1_ATI, GL_NONE, GL_NONE,
GL_REG_0_ATI, GL_ALPHA, GL_NONE);

I do need to use DOT4 and not DOT3 because this shader is used for other reasons also.

Any ideas, can anyone test this and see if they get the same behavior?

Thanks

Malcolm

[This message has been edited by MalcolmB (edited 08-01-2003).]

From the specification, i’d be suspicious about that part:

** - After a DOT4_ATI color instruction is specified, the only alpha instruction that can immediately follow is a DOT4_ATI. This is because the DOT4 color instruction implicitely uses an alpha instruction to calculate the result. If another type of alpha instruction is desired after a DOT4_ATI color instruction is issued, there are two choices: either issue another color instruction first, or issue the DOT4_ATI alpha instruction followed by the desired alpha instruction.

Y.

Try this

glBeginFragmentShaderATI();

glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);

glColorFragmentOp2ATI(GL_DOT4_ATI,
GL_REG_[b]1[/b]_ATI, GL_NONE, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_CON_0_ATI, GL_NONE, GL_BIAS_BIT_ATI | GL_2X_BIT_ATI);

glColorFragmentOp1ATI(GL_MOV_ATI,
GL_REG_0_ATI,GL_NONE,GL_SATURATE_BIT_ATI,
GL_REG_1_ATI,GL_NONE,GL_NONE);

glEndFragmentShaderATI();

DOT4 kind of nukes the alpha channel, so if you want to preserve it you should put the calculation to another (temp) register.

Ok, this is wierd. Clearly your code should work, but it doesn’t. I still get 0 for the alpha channel. If I put the alpha DOT4 instruction after the color instruction it works though.

Again, if I put a garbage statement that moves stuff from REG_0 to REG_1 before the DOT4 instruction, the alpha channel is preserved also. This is really inconsistant behavior.
Im starting to think this is a driver bug (running 3.6 here though)

Can anyone test this on their machine to see if they get the same behavior?
Thanks

[This message has been edited by MalcolmB (edited 08-05-2003).]

This looks like an improper-optimization bug on the alpha chanel to me.

What HW are you on?

It would good if you could contact devrel@ati.com with the issue to report it.

-Evan

Its a 9800 pro.
Ya, I was going to send this to ATI, just posted here incase anyone had any ideas.

Evan: What is the correct behavior of the DOT4 instruction? Should it overwrite the alpha channel even if the alpha instruction isn’t called?

Thanks

According to the spec both the DOT3 and DOT4 instructions modify all four channels.

Have you tried this:

glBeginFragmentShaderATI();

glSampleMapATI(GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI);

glColorFragmentOp2ATI(GL_DOT4_ATI,
GL_REG_0_ATI, GL_RED_BIT_ATI|GL_GREEN_BIT_ATI|GL_BLUE_BIT_ATI, GL_SATURATE_BIT_ATI,
GL_REG_0_ATI, GL_NONE, GL_NONE,
GL_CON_0_ATI, GL_NONE, GL_BIAS_BIT_ATI | GL_2X_BIT_ATI);

glAlphaFragmentOp1ATI(GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE);

glEndFragmentShaderATI();

No, but the spec says the only alpha instruction allowed following a DOT4 instruction is an alpha DOT4 instruction so I don’t think that’ll work.

I’ve just noticed (after ~two days of frantically looking for a bug) that Cat 3.6 also broke some of my dynamically generated ATI_fragment_shader shaders.

The scope of the issue is limited (only one out of fifteen tested client apps is affected), and due to the dynamic nature of the shader gen I couldn’t yet identify any specific shader code that breaks.

Just for Evan, both R200 and R300 products exhibit this breakage, apparently on the same shaders (not yet confirmed). R200/R300 use the exact same codepath here.

The R300 is however ‘more affected’ than the R200. There does indeed seem to be a problem with the alpha channel, as the affected app gets an alpha test treatment (alpha generated by the shader).
On R300, alpha tested fragments never fail (at least not in the affected application).
On R200, some alpha tested fragments fail, but not all that should.
On R200 this seems to be non-deterministic, too, ie I’ve seen some flickering on certain objects’ “coronas”. This might be an interaction with previous blending state and previous alpha testing state (reference value is dynamic, too). With “previous” I mean, not current.

Maybe a renderstate unlatch gone bad.

I’ll be investigating further and hopefully come back with a minimum test case, but that’ll be some serious work …