Curious why no hybrid MSAA/SSAA?

Cryect

Regular
Seems to me that it would be ideal and fairly simple for hardware developers for transparent textures with alpha testing enabled to fall back to doing SSAA instead of MSAA. It's been bugging me for a while why neither ATI or Nvidia have implemented something of the like. It seems this should be fairly simple implementation and not a large performance hit if implemented in the silicon (I'm sure of course it could be done at the driver level somehow with a state change but the performance loss would potentially be worse than just doing SSAA).

Is there some reason I'm just missing or what?
 
You're not the only one wondering. While I think it would require certain changes in silicon to seamlessly switch between MS and SS, it could be done at the driver level in a less efficient way, by setting the multisample mask and sending a batch several times down the pipeline. One problem in this case might be the position of the geometry sampling points in relation to the texture sampling point (probably NVidia related only), and that the geometry has to be shifted slightly, but that can be done easily via the viewport transform.

In fact, any application could do this by itself, but for older games a force switch would be nice.
 
Cryect said:
Seems to me that it would be ideal and fairly simple for hardware developers for transparent textures with alpha testing enabled to fall back to doing SSAA instead of MSAA.
Alpha testing rather B' ups early Z testing schemes and so probably isn't all that popular with any of the IHV's these days. They probably don't want to be actively encouraging it <shrug>
 
Simon F said:
Cryect said:
Seems to me that it would be ideal and fairly simple for hardware developers for transparent textures with alpha testing enabled to fall back to doing SSAA instead of MSAA.
Alpha testing rather B' ups early Z testing schemes and so probably isn't all that popular with any of the IHV's these days. They probably don't want to be actively encouraging it <shrug>
Could you please elaborate on how alpha test breaks early (hierarchical?) Z? I remember a discussion about that a while ago, but it wasn't too productive :?

My theory was that you have some "early Z storage" on chip that must always be updated with the correct Z data, and that there would be ordering hazards when the alpha test culls a fragment that the early Z block didn't cull, so that the "early Z storage" goes out of sync and this would cause too many fragments to be culled.
:?:

Disclaimer: IANAHWD.
 
Early Z effectively does the Z testing before the far more expensive texturing operation thus can save some otherwise redundant work.

It can't be used with alpha testing as that requires you to texture before deciding if you need to do the Z test.
 
It can't be used with alpha testing as that requires you to texture before deciding if you need to do the Z test.

Hum, why is that? Don't you need to discard the pixel if the alphatest fails OR the ztest fails? So the order in which you do the operation doesn't matter? I am probably missing something here.
 
Scali said:
It can't be used with alpha testing as that requires you to texture before deciding if you need to do the Z test.

Hum, why is that? Don't you need to discard the pixel if the alphatest fails OR the ztest fails? So the order in which you do the operation doesn't matter? I am probably missing something here.
You can only update the Z buffer if the pixel is visible. With alpha testing, visibility is a function of (amongst other things) the texturing operation.

AHHH! I think I know why you're confused. Consider what would happen with the next object, i.e the following an alpha tested object, if you didn't do all the operations on the alpha tested object first.
 
I'll agree with Simon's original comment: I would prefer it if alpha test largely went away. Which is not to say that I don't think it should be available, but it should be a 'last resort' measure when other solutions aren't viable.

Hierarchical Z and early Z test both have to be done before the pixel shader is run to be worthwhile. They also have to commit the Z write at that time, because the cost of buffering it for the massive latency of the shader unit (hundreds or thousands of cycles) would be prohibitive. Therefore, operations which depend on the shader result - such as alpha test or shader pixel kill (texkill) cause us to move the Z test after the shader.
 
AHHH! I think I know why you're confused. Consider what would happen with the next object, i.e the following an alpha tested object, if you didn't do all the operations on the alpha tested object first.

I think I know what you mean now... Because of alphatesting, you don't necessarily have nice consecutive runs of pixels on each polygon... You could have random 'holes' in the poly, which means isolated z-values.
And those can only be stored at the deepest level of the hierarchy, so you end up doing per-pixel checks. That's what you mean, right?

Then I think that as long as you have consecutive runs of pixels with alphatesting, it could still be done with the early z check. But perhaps hardware doesn't implement this case separately, because it is not that easy to find out if the entire block of pixels you just drew contained any discarded pixels.
 
Scali said:
AHHH! I think I know why you're confused. Consider what would happen with the next object, i.e the following an alpha tested object, if you didn't do all the operations on the alpha tested object first.

I think I know what you mean now... Because of alphatesting, you don't necessarily have nice consecutive runs of pixels on each polygon... You could have random 'holes' in the poly, which means isolated z-values.
And those can only be stored at the deepest level of the hierarchy, so you end up doing per-pixel checks. That's what you mean, right?
No, not really.

Ahh maybe I see what the confusion is:
If the alpha tested polygon is completely behind everything in the Z buffer then, yes, in theory you could reject it early but that's only a small part of the problem.

As soon as some pixels of polygon are in front of the stored Z's you have to go and do the texturing operations for those pixels. Only then you can decide which (random) pixels the polygon is actually covering and, hence, whether to update the Z data. The texturing takes a lot of time which, ideally, you'd want to overlap with something else but...

In the mean time, the next polygon down the pipeline might not know if can safely be rejected or not until the Z buffer has been updated. (I suppose some special cases can be handled but that starts getting very messy).
 
here's a pic of some alpha test errors in action...
alphatest.JPG

the hanging ice showing through the grate is obvious, but if you look close in the lower left hand corner you can see cracked ice texture showing through as well. the image was resized from 1024*768 (no fsaa, no af) on a radeon9700.

to be honest, i'd like to be able to force alpha test at the driver level even with these errors. in some games they are almost completely unoticable, while the aliasing on alpha textures almost always is.
c:
 
Scali said:
No, not really.

I think yes really. What you said was what I said, or what I meant anyway. Perhaps not what you understood.
No. I wasn't concerned with the issues of handling heirarchical Z - that's an extra problem. You can do early Z tests with a bog-standard Z buffer.
 
I don't understand the issue with hierarchical Z. Ok, you lose the ability to trivially accept a triangle since you can't update the closest Z value per tile. But when the triangle is between minZ and maxZ of the tile you have to do the per-pixel Z test anyway, so why not do the same with alpha test polygons that can't be trivially rejected?
 
I don't know who is replying to whom now. :( To summarise:


No alpha test case:
Lots of pixels => Z test (CHEAP * lots of pixels) => fewer pixels => Texturing (expensive * fewer pixels)

Alpha test case:
Lots of pixels => Texturing (expensive * lots of pixels) => still lots of pixels => Z Test (Cheap * lots).


Does that make sense to people?
 
Why not
Lots of pixels => HierZ => fewer pixels => texturing => alpha test => Z test
?
 
Z writes are commited at the point of test - therefore in that example HiZ might be testing stale data. There are some special cases (e.g. Z writes disabled) where this can still operate, but in most it can't.
 
see colon said:
here's a pic of some alpha test errors in action...

Sorry, but to me it looks like a sorting issue. (Rendering stuff in the wrong order.)
Of course I might be wrong but if there's also transparency on the "ice", which I believe is the case, it really sounds like a sorting issue.
 
Dio said:
Z writes are commited at the point of test - therefore in that example HiZ might be testing stale data. There are some special cases (e.g. Z writes disabled) where this can still operate, but in most it can't.
There's a difference between HiZ and early Z, at least on R300 and R420 based products. HiZ can be enabled while alpha test is enabled because HiZ only does early rejection, not early acceptance (conservative algorithm). Early Z test cannot be enabled because it actually would update the Z value if the pixel passed, which would cause problems if it were later killed by the alpha test.

Regarding switching between SSAA and MSAA on the fly... I have tried several ideas here none of which work acceptably for various reasons.
 
Back
Top