dx pixel shaders requiring vertex shader on ati

Started by
6 comments, last by rubicondev 14 years, 4 months ago
Hello all, I've been around a bit, but this is my first actual post. Up until quite recently, I had been doing all my dx graphics programming on nvidia cards. I recently got an ATI card (Radeon 5850), and immediately noticed an odd issue. The ATI card seems to require that I specify a vertex shader if I'm using a pixel shader, even if the pixel shader doesn't intrinsically rely on the vertex shader. On the nvidia 7900 and 8800gt's, I can set the vertex shader to NULL, and only use a pixel shader, and the polys would render fine. This seems to be the expected behavior for dx. But, on the ATI card, this causes the polys to flat-out not draw. None of the dx calls appear to return an error, it just doesn't draw anything. I've managed to narrow it down to where the vertex shader does nothing more than the world*projection transform for the position, and the pixel shader simply returns a static color (red). On the nvidia cards, I can enable either just the pixel shader, or both pixel and vertex shaders, and I get the same correct result: the polys are rendered red. But, on the ATI card, I must pass both shaders for it to display the polygons. If I only pass the pixel shader, even though it does nothing more than return a color value and therefore shouldn't require a vertex shader, it renders nothing. My best guess is that, on ATI cards, once a pixel shader is specified, it assumes a vertex shader will also be provided to perform the world*projection transform, and doesn't bother to do it itself when no vertex shader is provided. So, my question is, is this a known issue on ATI cards? Has anyone else run into this? My current "fix" is to just always create a vertex shader. This works, but seems like a waste of gpu power. Any ideas are appreciated, thanks!
Advertisement

By creating a vertex shader, you don't waste any GPU power. Modern cards use a shader whether you specify one or don't. Even fixed function pipeline is implemented as a shader and not as a separated hardware.

It is even possible that by creating a simple shader that you mention, you may actually save some GPU clocks as the fixed function vertex shader may well be a bit heavier. As if it did matter.

Cheers!
Hey Kauna, thanks for the quick reply! Perhaps you're right, and it won't be a big deal on performance. Still disappointing to see such inconsistencies between vendors on a supposedly common API, but so be it.
Quote:Original post by joefear
Hey Kauna, thanks for the quick reply! Perhaps you're right, and it won't be a big deal on performance. Still disappointing to see such inconsistencies between vendors on a supposedly common API, but so be it.


To be more accurate, nVidia is usually the one that generally makes these exceptions that aren't standard to the API.

For example, if you were to create a ps_3_0 shader, and wanted to use a vertex shader, you need to supply a vs_3_0 (or higher) as well (in fact, you'll get errors using ATI hardware or the DX Debug Runtime if you try it any other way). However, on nVidia hardware this isn't required at all and will be more than happy to run without a vertex shader or with a shader lower than vs_3_0.

I'm not entirely sure why these things are allowed to happen. I can only assume they do it to increase compatibility with poorly written software.
I think that if you switch to using the debug runtimes you should get a warning about this. My understanding is that if you specify a NULL VS then the system assumes that you will use the FFP so it should really generate an error if you attach a PS to it imo as it's not compatible.

I agree that these inconsistencies are probably more about retrofixes than proper behaviour and you should really stick to doing things how it says in the docs which is to supply both or none. I'd go for both.
------------------------------Great Little War Game
You're describing polygons rendering "correctly" on NVIDIA cards without using a vertex shader. What are you using then? Are you using the fixed function pipeline, or are you simply going on the assumption that vertices need to be transformed by some magic without you telling the card what to do with them?

Pixel shaders will work with fixed function according to the Direct3D definition as long as they are shader model 2.x or lower. It's possible that this works on NVIDIA cards in other cases, but that's not part of the spec. You can always try with the reference device and see what it does, because it should work the way things are meant to be.

As for performance, just because you don't define a vertex shader doesn't mean that the card is doing less work. You say that the polygons are transformed correctly, which means that the card is doing that (again, it's not pixie dust, everything is done somewhere, even if you don't have to define it specifically). So defining a vertex shader that does the same things will take the same amount of work for the card.
To ET3D, obviously leaving anything in the rendering chain to chance would be foolish. Yes, I was supplying the transform and view projection matrices to the ffp. I doubt even the nvidia cards, with as many work-arounds as they have, would be able to render the polys without such information being fed to it in some way.
And to Flimflam, yep, I have first hand experience with nvidia's tendencies for shenanigans when it comes to adhering to API's. It's bitten me before, and I guess it bit me again.
Surprisingly, I never knew or came across the official limitation that shader model 3.0 no longer works with the ffp. I guess all the docs I read and examples I've studied dealt with 2.0 and lower. Looks like I need to hit the books.
On the performance, I had always assumed the ffp might be faster simply because they know there won't be any intense shader zaniness, and so they might be able to take shortcuts and optimize. But, it seems that is not the case.

Well, thanks all, that pretty much solves all the mysteries.
Quote:Original post by joefear
On the performance, I had always assumed the ffp might be faster simply because they know there won't be any intense shader zaniness, and so they might be able to take shortcuts and optimize. But, it seems that is not the case.

It's a reasonable assumption, but if you think it through a bit more, what you're expecting isn't gonna happen:

If you have a game that's old enough to want to run on the FFP, a modern card simply won't need to optimise it - it'll run like shit off a shovel as-is. So instead they keep it simple (and hopefully therefore less bug prone) and just emulate it all in a big shader anyway - even when you think you're "on" the FFP path, you're really not. The actual source to the FFP shader is around somewhere, I stumbled across it once. Can't remember exactly where tho.
------------------------------Great Little War Game

This topic is closed to new replies.

Advertisement