Vendor & device filtering in Ogre material techniques

· by Steve · Read in about 4 min · (668 Words)

Ogre’s material system is pretty smart already, and one of its many features is to automatically switch techniques based on the supportability of certain hardware features you’ve tried to use in your material. Thus, you might provide an uber-fantastic Shader Model 3 lighting model for cards that can handle it, and provide simpler implementations that will be automatically used on lower end hardware. Other uses of techniques include ‘material schemes’ (where you can define alternate pathways for your materials and associate them with particular viewports, render targets or system options - useful for HDR paths, high / low detail options etc) and level-of-detail support where you can drop the complexity of your materials in the distance automatically - however hardware fallback is probably the most common use.

However, useful though the autodetected hardware fallback feature is, we’ve all come across particular hardware combinations that affect how our materials look, but that might not be directly represented by the standard hardware caps. Things like the internal precision applied to calculations, support for filtering and blending on floating point surfaces, and other such differences. These edge cases can cause you problems on some hardware in your more advanced materials, and you may need a way to utilise your experience with particular types of hardware to influence your rendering approach, beyond the feature points that can already be detected and applied to the technique choice.

Well, now you can. In CVS HEAD, you can now use the following new directives in your material scripts: ‘gpu_vendor_rule’ and ‘gpu_device_rule’. When applied to techniques, they allow you to manually influence the ‘supportability’ detection based on vendors (NVIDIA, Intel, ATI, S3 etc), and device ‘patterns’ (e.g. ‘*8800*"). For example:

gpu_vendor_rule include ati

gpu_device_rule exclude *firegl*

That would make a technique valid only for ATI cards, but excluding FireGL variants. ‘include’ rules, if stated, require a card to match at least one of the ‘include’ rules present in that technique, and an ‘exclude’ rule will mark a technique as unsupported if the card matches any of the ‘exclude’ rules. You can add as many rules of either type as you like to each technique, they just combine together - the ‘gpu_device_rule’ is the most powerful of course for doing fine-grained filtering. Of course, hardware capabilities are still detected and the above would not make a technique valid on a card that didn’t support the features used, but it can be used to filter out cards that would otherwise be considered valid based on hardware caps alone.

Ideally, you would never need to use this feature since Ogre will detect the important hardware capabilities and filter techniques for you based on that. But I think those with a lot of practical experience with the nuances of working across a range of hardware will find this useful, as a last-resort lifebelt in those sticky situations where something misbehaves on a particular set of hardware, or there’s some little trick you’d particularly like to use on a given family of cards but couldn’t before because it’s not detectable in a standardised way.

Some of you might be wondering about driver bugs. I’ve also considered adding a ‘gpu_driver_rule’ option here, although so far I haven’t, partly because of the difficulty standardising driver version numbers and comparing them, but also because driver bugs should be transient (we all hope so anyway!). It just feels a little wrong to be including workarounds that should be transient in your material assets, as compared to things that should stay fixed like vendor and device variants. If you’re in a pinch, you can already detect the driver via RenderSystemCapabilities and set a workaround up in code to cope if you need to, and I tend to feel that’s a better approach for something that should eventually become moot - you can always put a #pragma msg or something in your code to keep reminding you to check if the bug has been fixed yet. If anyone has any alternative thoughts on that, let me know.